@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
package/dist/docx/runParser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parseHorizontalScalePercent } from "../utils/horizontalScale.js";
|
|
2
2
|
import { NO_MODELLED_ATTRIBUTES, attributeRemainder } from "./attributeRemainder.js";
|
|
3
|
-
import { CAPTURE,
|
|
3
|
+
import { CAPTURE, dispatchChildrenWithContext, keptUnless, ownedElsewhere, sequencePositions } from "./containerChildren.js";
|
|
4
4
|
import { parseDiagramPreview } from "./diagramPreview.js";
|
|
5
5
|
import { parseFieldState } from "./fieldState.js";
|
|
6
6
|
import { isGroupDrawing, parseGroupDrawing } from "./groupDrawingParser.js";
|
|
@@ -8,7 +8,9 @@ import { parseImage } from "./imageParser.js";
|
|
|
8
8
|
import { imageRawXmlFingerprint } from "./imageRawXml.js";
|
|
9
9
|
import { EmphasisMarkSchema, FontHintSchema, FontThemeSchema, HighlightColorSchema, PositionalTabAlignmentSchema, PositionalTabLeaderSchema, PositionalTabRelativeToSchema, TextEffectSchema, UnderlineStyleSchema, narrowEnum } from "./parserEnums.js";
|
|
10
10
|
import { preserveRunChild } from "./preservedRunContent.js";
|
|
11
|
+
import { standalonePreviewLedger } from "./previewBudget.js";
|
|
11
12
|
import { parseShading } from "./shadingParser.js";
|
|
13
|
+
import { captureShapeAlternateContent } from "./shapeAlternateContent.js";
|
|
12
14
|
import { parseShapeFromDrawing, shouldPreserveRawShapeDrawing } from "./shapeParser.js";
|
|
13
15
|
import { isTextBoxDrawing } from "./textBoxParser.js";
|
|
14
16
|
import { parseThemeColorAttribute } from "./themeColorAttribute.js";
|
|
@@ -69,7 +71,7 @@ const RUN_PROPERTY_OWNERS = {
|
|
|
69
71
|
* The children each owner's sibling record claims.
|
|
70
72
|
*
|
|
71
73
|
* Not the decision map: that one is total over the schema and lives in
|
|
72
|
-
* {@link
|
|
74
|
+
* {@link RUN_PROPERTY_HANDLERS}. This names only the children a given owner reads
|
|
73
75
|
* somewhere else, so both cannot write the same element.
|
|
74
76
|
*/
|
|
75
77
|
const OWNED_BY_A_SIBLING_RECORD = {
|
|
@@ -102,6 +104,16 @@ const OWNED_BY_A_SIBLING_RECORD = {
|
|
|
102
104
|
},
|
|
103
105
|
standalone: {}
|
|
104
106
|
};
|
|
107
|
+
/** The last statement of each declared property in `rPr`, by local name. */
|
|
108
|
+
const lastOccurrences = (rPr) => {
|
|
109
|
+
const winner = /* @__PURE__ */ new Map();
|
|
110
|
+
for (const child of getChildElements(rPr)) {
|
|
111
|
+
const namespace = getNamespaceUri(child);
|
|
112
|
+
if (namespace !== void 0 && !WORDPROCESSINGML_NAMESPACE_URIS.has(namespace)) continue;
|
|
113
|
+
winner.set(getLocalName(child.name), child);
|
|
114
|
+
}
|
|
115
|
+
return winner;
|
|
116
|
+
};
|
|
105
117
|
/**
|
|
106
118
|
* A property stated twice in one `w:rPr` resolves to the last statement.
|
|
107
119
|
*
|
|
@@ -123,17 +135,18 @@ const OWNED_BY_A_SIBLING_RECORD = {
|
|
|
123
135
|
* first and a reader that takes the last then read the same value.
|
|
124
136
|
*
|
|
125
137
|
* The name comes off the child rather than from the map key, so the guard
|
|
126
|
-
* cannot name a property the handler does not read.
|
|
138
|
+
* cannot name a property the handler does not read. `undefined` is "handled,
|
|
139
|
+
* nothing to capture": a beaten statement is neither read nor written.
|
|
127
140
|
*/
|
|
128
|
-
const readLastOccurrenceOnly = (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return (
|
|
136
|
-
};
|
|
141
|
+
const readLastOccurrenceOnly = (read) => (child, context) => context.winner.get(getLocalName(child.name)) === child ? read(child, context) : void 0;
|
|
142
|
+
const readToggle = (field) => readLastOccurrenceOnly((child, { formatting }) => {
|
|
143
|
+
formatting[field] = parseBooleanElement(child);
|
|
144
|
+
});
|
|
145
|
+
const readNumericVal = (field) => readLastOccurrenceOnly((child, { formatting }) => {
|
|
146
|
+
const val = parseNumericAttribute(child, "w", "val");
|
|
147
|
+
if (val !== void 0) formatting[field] = val;
|
|
148
|
+
return keptUnless(val !== void 0);
|
|
149
|
+
});
|
|
137
150
|
/**
|
|
138
151
|
* `w:vertAlign` `baseline` is the reserved value that means "no vertical
|
|
139
152
|
* offset", not a third offset beside `superscript` and `subscript`. It is
|
|
@@ -225,6 +238,131 @@ const readLanguage = (lang, formatting) => {
|
|
|
225
238
|
return true;
|
|
226
239
|
};
|
|
227
240
|
/**
|
|
241
|
+
* The `w:rPr` decision map, before the owner's own claims. Built once: every
|
|
242
|
+
* reader takes the record it fills from the walk's context rather than
|
|
243
|
+
* closing over it. See {@link parseRunProperties} for what each disposition
|
|
244
|
+
* means.
|
|
245
|
+
*/
|
|
246
|
+
const RUN_PROPERTY_BASE_HANDLERS = {
|
|
247
|
+
ins: CAPTURE,
|
|
248
|
+
del: CAPTURE,
|
|
249
|
+
moveFrom: CAPTURE,
|
|
250
|
+
moveTo: CAPTURE,
|
|
251
|
+
rStyle: readLastOccurrenceOnly((child, { formatting }) => {
|
|
252
|
+
const val = getAttribute(child, "w", "val");
|
|
253
|
+
if (val) formatting.styleId = val;
|
|
254
|
+
return keptUnless(Boolean(val));
|
|
255
|
+
}),
|
|
256
|
+
rFonts: readLastOccurrenceOnly((child, { formatting, theme }) => keptUnless(readFontFamily(child, theme, formatting))),
|
|
257
|
+
b: readToggle("bold"),
|
|
258
|
+
bCs: readToggle("boldCs"),
|
|
259
|
+
i: readToggle("italic"),
|
|
260
|
+
iCs: readToggle("italicCs"),
|
|
261
|
+
caps: readToggle("allCaps"),
|
|
262
|
+
smallCaps: readToggle("smallCaps"),
|
|
263
|
+
strike: readToggle("strike"),
|
|
264
|
+
dstrike: readToggle("doubleStrike"),
|
|
265
|
+
outline: readToggle("outline"),
|
|
266
|
+
shadow: readToggle("shadow"),
|
|
267
|
+
emboss: readToggle("emboss"),
|
|
268
|
+
imprint: readToggle("imprint"),
|
|
269
|
+
noProof: readToggle("noProof"),
|
|
270
|
+
vanish: readToggle("hidden"),
|
|
271
|
+
rtl: readToggle("rtl"),
|
|
272
|
+
cs: readToggle("cs"),
|
|
273
|
+
/** Whether the run follows the section's document grid; no layout slot. */
|
|
274
|
+
snapToGrid: CAPTURE,
|
|
275
|
+
/** Web-view-only hiding, distinct from `w:vanish`; nothing reads it. */
|
|
276
|
+
webHidden: CAPTURE,
|
|
277
|
+
color: readLastOccurrenceOnly((child, { formatting }) => {
|
|
278
|
+
const color = parseColorValue({
|
|
279
|
+
rgb: getAttribute(child, "w", "val"),
|
|
280
|
+
themeColor: getAttribute(child, "w", "themeColor"),
|
|
281
|
+
themeTint: getAttribute(child, "w", "themeTint"),
|
|
282
|
+
themeShade: getAttribute(child, "w", "themeShade"),
|
|
283
|
+
element: child.name ?? "w:color"
|
|
284
|
+
});
|
|
285
|
+
if (Object.keys(color).length === 0) return CAPTURE;
|
|
286
|
+
formatting.color = color;
|
|
287
|
+
}),
|
|
288
|
+
spacing: readNumericVal("spacing"),
|
|
289
|
+
w: readLastOccurrenceOnly((child, { formatting }) => {
|
|
290
|
+
const val = parseHorizontalScalePercent(getAttribute(child, "w", "val"));
|
|
291
|
+
if (val !== void 0) formatting.scale = val;
|
|
292
|
+
return keptUnless(val !== void 0);
|
|
293
|
+
}),
|
|
294
|
+
kern: readNumericVal("kerning"),
|
|
295
|
+
position: readNumericVal("position"),
|
|
296
|
+
sz: readNumericVal("fontSize"),
|
|
297
|
+
szCs: readNumericVal("fontSizeCs"),
|
|
298
|
+
highlight: readLastOccurrenceOnly((child, { formatting }) => {
|
|
299
|
+
const val = narrowEnum(getAttribute(child, "w", "val"), HighlightColorSchema);
|
|
300
|
+
if (val) formatting.highlight = val;
|
|
301
|
+
return keptUnless(Boolean(val));
|
|
302
|
+
}),
|
|
303
|
+
u: readLastOccurrenceOnly((child, { formatting }) => keptUnless(readUnderline(child, formatting))),
|
|
304
|
+
effect: readLastOccurrenceOnly((child, { formatting }) => {
|
|
305
|
+
const val = narrowEnum(getAttribute(child, "w", "val"), TextEffectSchema);
|
|
306
|
+
if (val) formatting.effect = val;
|
|
307
|
+
return keptUnless(Boolean(val));
|
|
308
|
+
}),
|
|
309
|
+
/** A text border around the run; `BorderSpec` is a paragraph/table slot. */
|
|
310
|
+
bdr: CAPTURE,
|
|
311
|
+
shd: readLastOccurrenceOnly((child, { formatting }) => {
|
|
312
|
+
const shading = parseShading(child);
|
|
313
|
+
if (shading) formatting.shading = shading;
|
|
314
|
+
return keptUnless(shading !== void 0);
|
|
315
|
+
}),
|
|
316
|
+
/** Compress the run's text into a fixed width; no layout slot holds it. */
|
|
317
|
+
fitText: CAPTURE,
|
|
318
|
+
vertAlign: readLastOccurrenceOnly((child, { formatting }) => {
|
|
319
|
+
const val = getAttribute(child, "w", "val");
|
|
320
|
+
if (val === "superscript" || val === "subscript" || val === "baseline") {
|
|
321
|
+
formatting.vertAlign = val;
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
return CAPTURE;
|
|
325
|
+
}),
|
|
326
|
+
em: readLastOccurrenceOnly((child, { formatting }) => {
|
|
327
|
+
const val = narrowEnum(getAttribute(child, "w", "val"), EmphasisMarkSchema);
|
|
328
|
+
if (val) formatting.emphasisMark = val;
|
|
329
|
+
return keptUnless(Boolean(val));
|
|
330
|
+
}),
|
|
331
|
+
lang: readLastOccurrenceOnly((child, { formatting }) => keptUnless(readLanguage(child, formatting))),
|
|
332
|
+
/** East Asian two-lines-in-one and horizontal-in-vertical typesetting. */
|
|
333
|
+
eastAsianLayout: CAPTURE,
|
|
334
|
+
/**
|
|
335
|
+
* The run-in heading marker. Under a run the schema declares it and folio
|
|
336
|
+
* models nothing for it; a paragraph mark's record reads it instead (see
|
|
337
|
+
* {@link RUN_PROPERTY_HANDLERS}).
|
|
338
|
+
*/
|
|
339
|
+
specVanish: CAPTURE,
|
|
340
|
+
/** The run is part of an equation; folio has no run-level maths slot. */
|
|
341
|
+
oMath: CAPTURE,
|
|
342
|
+
/**
|
|
343
|
+
* The tracked property change. A run's record reads it into
|
|
344
|
+
* `Run.propertyChanges`; a paragraph mark has no such record, so its
|
|
345
|
+
* snapshot is kept whole rather than dropped with the revision.
|
|
346
|
+
*/
|
|
347
|
+
rPrChange: CAPTURE
|
|
348
|
+
};
|
|
349
|
+
/** Each owner's total `w:rPr` decision map. */
|
|
350
|
+
const RUN_PROPERTY_HANDLERS = {
|
|
351
|
+
run: {
|
|
352
|
+
...RUN_PROPERTY_BASE_HANDLERS,
|
|
353
|
+
...OWNED_BY_A_SIBLING_RECORD.run
|
|
354
|
+
},
|
|
355
|
+
paragraphMark: {
|
|
356
|
+
...RUN_PROPERTY_BASE_HANDLERS,
|
|
357
|
+
specVanish: readLastOccurrenceOnly(() => void 0),
|
|
358
|
+
...OWNED_BY_A_SIBLING_RECORD.paragraphMark
|
|
359
|
+
},
|
|
360
|
+
standalone: {
|
|
361
|
+
...RUN_PROPERTY_BASE_HANDLERS,
|
|
362
|
+
...OWNED_BY_A_SIBLING_RECORD.standalone
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
228
366
|
* The one reader of a run property set (`w:rPr`).
|
|
229
367
|
*
|
|
230
368
|
* Every owner reads through here — a run, the paragraph mark, a style, a
|
|
@@ -253,167 +391,16 @@ const readLanguage = (lang, formatting) => {
|
|
|
253
391
|
function parseRunProperties(rPr, theme, owner) {
|
|
254
392
|
if (!rPr) return;
|
|
255
393
|
const formatting = {};
|
|
256
|
-
const
|
|
257
|
-
const preserved = dispatchChildren({
|
|
394
|
+
const preserved = dispatchChildrenWithContext({
|
|
258
395
|
element: rPr,
|
|
259
396
|
container: "run-properties",
|
|
260
|
-
handlers:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (val) formatting.styleId = val;
|
|
268
|
-
return keptUnless(Boolean(val));
|
|
269
|
-
}),
|
|
270
|
-
rFonts: wins((child) => keptUnless(readFontFamily(child, theme, formatting))),
|
|
271
|
-
b: wins((child) => {
|
|
272
|
-
formatting.bold = parseBooleanElement(child);
|
|
273
|
-
}),
|
|
274
|
-
bCs: wins((child) => {
|
|
275
|
-
formatting.boldCs = parseBooleanElement(child);
|
|
276
|
-
}),
|
|
277
|
-
i: wins((child) => {
|
|
278
|
-
formatting.italic = parseBooleanElement(child);
|
|
279
|
-
}),
|
|
280
|
-
iCs: wins((child) => {
|
|
281
|
-
formatting.italicCs = parseBooleanElement(child);
|
|
282
|
-
}),
|
|
283
|
-
caps: wins((child) => {
|
|
284
|
-
formatting.allCaps = parseBooleanElement(child);
|
|
285
|
-
}),
|
|
286
|
-
smallCaps: wins((child) => {
|
|
287
|
-
formatting.smallCaps = parseBooleanElement(child);
|
|
288
|
-
}),
|
|
289
|
-
strike: wins((child) => {
|
|
290
|
-
formatting.strike = parseBooleanElement(child);
|
|
291
|
-
}),
|
|
292
|
-
dstrike: wins((child) => {
|
|
293
|
-
formatting.doubleStrike = parseBooleanElement(child);
|
|
294
|
-
}),
|
|
295
|
-
outline: wins((child) => {
|
|
296
|
-
formatting.outline = parseBooleanElement(child);
|
|
297
|
-
}),
|
|
298
|
-
shadow: wins((child) => {
|
|
299
|
-
formatting.shadow = parseBooleanElement(child);
|
|
300
|
-
}),
|
|
301
|
-
emboss: wins((child) => {
|
|
302
|
-
formatting.emboss = parseBooleanElement(child);
|
|
303
|
-
}),
|
|
304
|
-
imprint: wins((child) => {
|
|
305
|
-
formatting.imprint = parseBooleanElement(child);
|
|
306
|
-
}),
|
|
307
|
-
noProof: wins((child) => {
|
|
308
|
-
formatting.noProof = parseBooleanElement(child);
|
|
309
|
-
}),
|
|
310
|
-
vanish: wins((child) => {
|
|
311
|
-
formatting.hidden = parseBooleanElement(child);
|
|
312
|
-
}),
|
|
313
|
-
rtl: wins((child) => {
|
|
314
|
-
formatting.rtl = parseBooleanElement(child);
|
|
315
|
-
}),
|
|
316
|
-
cs: wins((child) => {
|
|
317
|
-
formatting.cs = parseBooleanElement(child);
|
|
318
|
-
}),
|
|
319
|
-
/** Whether the run follows the section's document grid; no layout slot. */
|
|
320
|
-
snapToGrid: CAPTURE,
|
|
321
|
-
/** Web-view-only hiding, distinct from `w:vanish`; nothing reads it. */
|
|
322
|
-
webHidden: CAPTURE,
|
|
323
|
-
color: wins((child) => {
|
|
324
|
-
const color = parseColorValue({
|
|
325
|
-
rgb: getAttribute(child, "w", "val"),
|
|
326
|
-
themeColor: getAttribute(child, "w", "themeColor"),
|
|
327
|
-
themeTint: getAttribute(child, "w", "themeTint"),
|
|
328
|
-
themeShade: getAttribute(child, "w", "themeShade"),
|
|
329
|
-
element: child.name ?? "w:color"
|
|
330
|
-
});
|
|
331
|
-
if (Object.keys(color).length === 0) return CAPTURE;
|
|
332
|
-
formatting.color = color;
|
|
333
|
-
}),
|
|
334
|
-
spacing: wins((child) => {
|
|
335
|
-
const val = parseNumericAttribute(child, "w", "val");
|
|
336
|
-
if (val !== void 0) formatting.spacing = val;
|
|
337
|
-
return keptUnless(val !== void 0);
|
|
338
|
-
}),
|
|
339
|
-
w: wins((child) => {
|
|
340
|
-
const val = parseHorizontalScalePercent(getAttribute(child, "w", "val"));
|
|
341
|
-
if (val !== void 0) formatting.scale = val;
|
|
342
|
-
return keptUnless(val !== void 0);
|
|
343
|
-
}),
|
|
344
|
-
kern: wins((child) => {
|
|
345
|
-
const val = parseNumericAttribute(child, "w", "val");
|
|
346
|
-
if (val !== void 0) formatting.kerning = val;
|
|
347
|
-
return keptUnless(val !== void 0);
|
|
348
|
-
}),
|
|
349
|
-
position: wins((child) => {
|
|
350
|
-
const val = parseNumericAttribute(child, "w", "val");
|
|
351
|
-
if (val !== void 0) formatting.position = val;
|
|
352
|
-
return keptUnless(val !== void 0);
|
|
353
|
-
}),
|
|
354
|
-
sz: wins((child) => {
|
|
355
|
-
const val = parseNumericAttribute(child, "w", "val");
|
|
356
|
-
if (val !== void 0) formatting.fontSize = val;
|
|
357
|
-
return keptUnless(val !== void 0);
|
|
358
|
-
}),
|
|
359
|
-
szCs: wins((child) => {
|
|
360
|
-
const val = parseNumericAttribute(child, "w", "val");
|
|
361
|
-
if (val !== void 0) formatting.fontSizeCs = val;
|
|
362
|
-
return keptUnless(val !== void 0);
|
|
363
|
-
}),
|
|
364
|
-
highlight: wins((child) => {
|
|
365
|
-
const val = narrowEnum(getAttribute(child, "w", "val"), HighlightColorSchema);
|
|
366
|
-
if (val) formatting.highlight = val;
|
|
367
|
-
return keptUnless(Boolean(val));
|
|
368
|
-
}),
|
|
369
|
-
u: wins((child) => keptUnless(readUnderline(child, formatting))),
|
|
370
|
-
effect: wins((child) => {
|
|
371
|
-
const val = narrowEnum(getAttribute(child, "w", "val"), TextEffectSchema);
|
|
372
|
-
if (val) formatting.effect = val;
|
|
373
|
-
return keptUnless(Boolean(val));
|
|
374
|
-
}),
|
|
375
|
-
/** A text border around the run; `BorderSpec` is a paragraph/table slot. */
|
|
376
|
-
bdr: CAPTURE,
|
|
377
|
-
shd: wins((child) => {
|
|
378
|
-
const shading = parseShading(child);
|
|
379
|
-
if (shading) formatting.shading = shading;
|
|
380
|
-
return keptUnless(shading !== void 0);
|
|
381
|
-
}),
|
|
382
|
-
/** Compress the run's text into a fixed width; no layout slot holds it. */
|
|
383
|
-
fitText: CAPTURE,
|
|
384
|
-
vertAlign: wins((child) => {
|
|
385
|
-
const val = getAttribute(child, "w", "val");
|
|
386
|
-
if (val === "superscript" || val === "subscript" || val === "baseline") {
|
|
387
|
-
formatting.vertAlign = val;
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
return CAPTURE;
|
|
391
|
-
}),
|
|
392
|
-
em: wins((child) => {
|
|
393
|
-
const val = narrowEnum(getAttribute(child, "w", "val"), EmphasisMarkSchema);
|
|
394
|
-
if (val) formatting.emphasisMark = val;
|
|
395
|
-
return keptUnless(Boolean(val));
|
|
396
|
-
}),
|
|
397
|
-
lang: wins((child) => keptUnless(readLanguage(child, formatting))),
|
|
398
|
-
/** East Asian two-lines-in-one and horizontal-in-vertical typesetting. */
|
|
399
|
-
eastAsianLayout: CAPTURE,
|
|
400
|
-
/**
|
|
401
|
-
* The run-in heading marker. On a paragraph mark the paragraph's record
|
|
402
|
-
* reads it (`runInWithNext`); under a run the schema declares it and folio
|
|
403
|
-
* models nothing for it.
|
|
404
|
-
*/
|
|
405
|
-
specVanish: owner === RUN_PROPERTY_OWNERS.paragraphMark ? wins(() => void 0) : CAPTURE,
|
|
406
|
-
/** The run is part of an equation; folio has no run-level maths slot. */
|
|
407
|
-
oMath: CAPTURE,
|
|
408
|
-
/**
|
|
409
|
-
* The tracked property change. A run's record reads it into
|
|
410
|
-
* `Run.propertyChanges`; a paragraph mark has no such record, so its
|
|
411
|
-
* snapshot is kept whole rather than dropped with the revision.
|
|
412
|
-
*/
|
|
413
|
-
rPrChange: CAPTURE,
|
|
414
|
-
...OWNED_BY_A_SIBLING_RECORD[owner]
|
|
415
|
-
},
|
|
416
|
-
capturePosition: sequencePositions("run-properties", rPr)
|
|
397
|
+
handlers: RUN_PROPERTY_HANDLERS[owner],
|
|
398
|
+
capturePosition: sequencePositions("run-properties", rPr),
|
|
399
|
+
context: {
|
|
400
|
+
formatting,
|
|
401
|
+
theme,
|
|
402
|
+
winner: lastOccurrences(rPr)
|
|
403
|
+
}
|
|
417
404
|
});
|
|
418
405
|
if (preserved) formatting.preserved = preserved;
|
|
419
406
|
return formatting;
|
|
@@ -570,8 +557,8 @@ const preserveOnlyDrawing = (rawXml) => ({
|
|
|
570
557
|
* - anything the model cannot project (a group the rasterizer declines,
|
|
571
558
|
* a diagram, a shape with unmodeled properties) → preservation-only raw XML.
|
|
572
559
|
*/
|
|
573
|
-
function parseDrawingContent(element, rels, media) {
|
|
574
|
-
const groupImage = parseGroupDrawing(element, rels ?? void 0, media ?? void 0);
|
|
560
|
+
function parseDrawingContent(element, rels, media, previews) {
|
|
561
|
+
const groupImage = parseGroupDrawing(element, previews, rels ?? void 0, media ?? void 0);
|
|
575
562
|
if (groupImage) return {
|
|
576
563
|
type: "drawing",
|
|
577
564
|
image: groupImage,
|
|
@@ -612,7 +599,7 @@ function parseDrawingContent(element, rels, media) {
|
|
|
612
599
|
/**
|
|
613
600
|
* Parse all content within a run element
|
|
614
601
|
*/
|
|
615
|
-
function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
602
|
+
function parseRunContents(runElement, rels, media, previews, rootXmlns = {}) {
|
|
616
603
|
const contents = [];
|
|
617
604
|
const children = getChildElements(runElement);
|
|
618
605
|
for (const child of children) switch (getLocalName(child.name)) {
|
|
@@ -650,12 +637,12 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
650
637
|
contents.push({ type: "noBreakHyphen" });
|
|
651
638
|
break;
|
|
652
639
|
case "drawing": {
|
|
653
|
-
const drawing = parseDrawingContent(child, rels, media);
|
|
640
|
+
const drawing = parseDrawingContent(child, rels, media, previews);
|
|
654
641
|
if (drawing) contents.push(drawing);
|
|
655
642
|
break;
|
|
656
643
|
}
|
|
657
644
|
case "pict": {
|
|
658
|
-
const vmlDrawing = parseVmlImageContent(child, rels, media, rootXmlns);
|
|
645
|
+
const vmlDrawing = parseVmlImageContent(child, rels, media, previews, rootXmlns);
|
|
659
646
|
if (vmlDrawing) {
|
|
660
647
|
contents.push(vmlDrawing);
|
|
661
648
|
break;
|
|
@@ -664,7 +651,7 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
664
651
|
break;
|
|
665
652
|
}
|
|
666
653
|
case "object": {
|
|
667
|
-
const objectPreview = parseVmlImageContent(child, rels, media, rootXmlns);
|
|
654
|
+
const objectPreview = parseVmlImageContent(child, rels, media, previews, rootXmlns);
|
|
668
655
|
contents.push(objectPreview ?? preserveRunChild(child));
|
|
669
656
|
break;
|
|
670
657
|
}
|
|
@@ -687,7 +674,7 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
687
674
|
const choiceTextBoxDrawing = choiceEl ? getChildElements(choiceEl).find((element) => getLocalName(element.name) === "drawing" && isTextBoxDrawing(element)) : void 0;
|
|
688
675
|
const groupedChoiceDrawing = choiceEl ? getChildElements(choiceEl).find((element) => getLocalName(element.name) === "drawing" && findAllDeep(element, "wpg", "wgp").length > 0) : void 0;
|
|
689
676
|
if (groupedChoiceDrawing) {
|
|
690
|
-
const groupedDrawing = parseDrawingContent(groupedChoiceDrawing, rels, media);
|
|
677
|
+
const groupedDrawing = parseDrawingContent(groupedChoiceDrawing, rels, media, previews);
|
|
691
678
|
if (groupedDrawing?.type === "drawing" && groupedDrawing.rawXmlMode === DRAWING_RAW_XML_MODES.PREVIEW_ONLY && groupedDrawing.image.src) {
|
|
692
679
|
contents.push({
|
|
693
680
|
...groupedDrawing,
|
|
@@ -697,7 +684,7 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
697
684
|
}
|
|
698
685
|
}
|
|
699
686
|
const fallbackPict = fallbackEl ? getChildElements(fallbackEl).find((el) => getLocalName(el.name) === "pict") : void 0;
|
|
700
|
-
const fallbackVml = fallbackPict && !choiceTextBoxDrawing ? parseVmlImageContent(fallbackPict, rels, media, rootXmlns) : null;
|
|
687
|
+
const fallbackVml = fallbackPict && !choiceTextBoxDrawing ? parseVmlImageContent(fallbackPict, rels, media, previews, rootXmlns) : null;
|
|
701
688
|
if (fallbackVml?.image.src) {
|
|
702
689
|
fallbackVml.rawXml = captureVerbatimXml(cloneWithXmlnsDeclarations(child, rootXmlns));
|
|
703
690
|
contents.push(fallbackVml);
|
|
@@ -707,13 +694,22 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
707
694
|
if (targetEl) for (const innerChild of getChildElements(targetEl)) {
|
|
708
695
|
const innerName = getLocalName(innerChild.name);
|
|
709
696
|
if (innerName === "drawing") {
|
|
710
|
-
const innerDrawing = parseDrawingContent(innerChild, rels, media);
|
|
697
|
+
const innerDrawing = parseDrawingContent(innerChild, rels, media, previews);
|
|
711
698
|
if (innerDrawing) {
|
|
712
699
|
if (innerDrawing.type === "drawing" && (innerDrawing.rawXml !== void 0 || !innerDrawing.image.src)) innerDrawing.rawXml = captureVerbatimXml(child);
|
|
700
|
+
if (innerDrawing.type === "shape") {
|
|
701
|
+
const alternateContent = captureShapeAlternateContent({
|
|
702
|
+
shape: innerDrawing.shape,
|
|
703
|
+
alternateContent: child,
|
|
704
|
+
branch: targetEl,
|
|
705
|
+
drawing: innerChild
|
|
706
|
+
});
|
|
707
|
+
if (alternateContent) innerDrawing.alternateContent = alternateContent;
|
|
708
|
+
}
|
|
713
709
|
contents.push(innerDrawing);
|
|
714
710
|
}
|
|
715
711
|
} else if (innerName === "pict") {
|
|
716
|
-
const innerVml = parseVmlImageContent(innerChild, rels, media, rootXmlns);
|
|
712
|
+
const innerVml = parseVmlImageContent(innerChild, rels, media, previews, rootXmlns);
|
|
717
713
|
if (innerVml) {
|
|
718
714
|
innerVml.rawXml = captureVerbatimXml(cloneWithXmlnsDeclarations(child, rootXmlns));
|
|
719
715
|
contents.push(innerVml);
|
|
@@ -721,7 +717,7 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
721
717
|
} else contents.push(...parseRunContents({
|
|
722
718
|
...targetEl,
|
|
723
719
|
elements: [innerChild]
|
|
724
|
-
}, rels, media, rootXmlns));
|
|
720
|
+
}, rels, media, previews, rootXmlns));
|
|
725
721
|
}
|
|
726
722
|
const hasTextBoxBranch = [choiceEl, fallbackEl].some((branch) => getChildElements(branch).some((element) => getLocalName(element.name) === "drawing" && isTextBoxDrawing(element)));
|
|
727
723
|
if (contents.length === contentsBeforeAlternate && !hasTextBoxBranch) contents.push(preserveOnlyDrawing(captureVerbatimXml(cloneWithXmlnsDeclarations(child, rootXmlns))));
|
|
@@ -742,9 +738,11 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
742
738
|
* @param theme - Theme for resolving theme colors/fonts
|
|
743
739
|
* @param rels - Relationship map for resolving image references
|
|
744
740
|
* @param media - Media files map for image data
|
|
741
|
+
* @param previews - The ledger of the package this run belongs to; a run read
|
|
742
|
+
* on its own charges its previews to no package
|
|
745
743
|
* @returns Parsed Run object
|
|
746
744
|
*/
|
|
747
|
-
function parseRun(node, _styles, theme, rels = null, media = null, rootXmlns = {}) {
|
|
745
|
+
function parseRun(node, _styles, theme, rels = null, media = null, rootXmlns = {}, previews = standalonePreviewLedger()) {
|
|
748
746
|
const run = {
|
|
749
747
|
type: "run",
|
|
750
748
|
content: []
|
|
@@ -756,7 +754,7 @@ function parseRun(node, _styles, theme, rels = null, media = null, rootXmlns = {
|
|
|
756
754
|
const propertyChangesResult = parseRunPropertyChanges(rPr, theme, run.formatting);
|
|
757
755
|
if (propertyChangesResult) run.propertyChanges = propertyChangesResult;
|
|
758
756
|
}
|
|
759
|
-
run.content = parseRunContents(node, rels, media, mergeXmlnsDeclarations(rootXmlns, node));
|
|
757
|
+
run.content = parseRunContents(node, rels, media, previews, mergeXmlnsDeclarations(rootXmlns, node));
|
|
760
758
|
const remainder = attributeRemainder({
|
|
761
759
|
element: node,
|
|
762
760
|
modelled: NO_MODELLED_ATTRIBUTES
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CAPTURE,
|
|
1
|
+
import { CAPTURE, dispatchChildrenWithContext, keptUnless, sequencePositions } from "./containerChildren.js";
|
|
2
2
|
import { SdtLockSchema, narrowEnum } from "./parserEnums.js";
|
|
3
3
|
import { RUN_PROPERTY_OWNERS, parseRunProperties } from "./runParser.js";
|
|
4
4
|
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
@@ -287,6 +287,88 @@ const captureSdtSiblingMarkers = (sdt) => {
|
|
|
287
287
|
after: afterParts.join("")
|
|
288
288
|
};
|
|
289
289
|
};
|
|
290
|
+
/** Read a projection off a control-kind element, and keep the element. */
|
|
291
|
+
const kind = (read) => (element, props) => {
|
|
292
|
+
read(props, element);
|
|
293
|
+
return CAPTURE;
|
|
294
|
+
};
|
|
295
|
+
const SDT_PROPERTY_HANDLERS = {
|
|
296
|
+
rPr: CAPTURE,
|
|
297
|
+
alias: (element, props) => {
|
|
298
|
+
const value = getAttributeAnyPrefix(element, "val");
|
|
299
|
+
if (value !== null) props.alias = value;
|
|
300
|
+
return keptUnless(value !== null);
|
|
301
|
+
},
|
|
302
|
+
tag: (element, props) => {
|
|
303
|
+
const value = getAttributeAnyPrefix(element, "val");
|
|
304
|
+
if (value !== null) props.tag = value;
|
|
305
|
+
return keptUnless(value !== null);
|
|
306
|
+
},
|
|
307
|
+
id: (element, props) => {
|
|
308
|
+
const raw = getAttributeAnyPrefix(element, "val");
|
|
309
|
+
const value = raw === null ? NaN : Number.parseInt(raw, 10);
|
|
310
|
+
if (!Number.isNaN(value)) props.id = value;
|
|
311
|
+
return keptUnless(!Number.isNaN(value));
|
|
312
|
+
},
|
|
313
|
+
lock: (element, props) => {
|
|
314
|
+
const value = narrowEnum(getAttributeAnyPrefix(element, "val"), SdtLockSchema);
|
|
315
|
+
if (value !== void 0) props.lock = value;
|
|
316
|
+
return keptUnless(value !== void 0);
|
|
317
|
+
},
|
|
318
|
+
placeholder: (element, props) => {
|
|
319
|
+
const value = getAttributeAnyPrefix(findChild(element, "w", "docPart"), "val");
|
|
320
|
+
if (value !== null) props.placeholder = value;
|
|
321
|
+
return keptUnless(value !== null);
|
|
322
|
+
},
|
|
323
|
+
temporary: CAPTURE,
|
|
324
|
+
showingPlcHdr: (element, props) => {
|
|
325
|
+
props.showingPlaceholder = parseBooleanElement(element, "w");
|
|
326
|
+
},
|
|
327
|
+
dataBinding: CAPTURE,
|
|
328
|
+
label: CAPTURE,
|
|
329
|
+
tabIndex: CAPTURE,
|
|
330
|
+
equation: kind(() => {}),
|
|
331
|
+
comboBox: kind((props, element) => {
|
|
332
|
+
props.sdtType = "comboBox";
|
|
333
|
+
props.listItems = parseListItems(element);
|
|
334
|
+
readLastValue(element, props);
|
|
335
|
+
}),
|
|
336
|
+
date: kind((props, element) => {
|
|
337
|
+
props.sdtType = "date";
|
|
338
|
+
const format = getAttributeAnyPrefix(findChild(element, "w", "dateFormat"), "val");
|
|
339
|
+
if (format !== null) props.dateFormat = format;
|
|
340
|
+
const fullDate = getAttributeAnyPrefix(element, "fullDate");
|
|
341
|
+
if (fullDate !== null) props.dateValueISO = fullDate;
|
|
342
|
+
}),
|
|
343
|
+
docPartObj: kind((props) => {
|
|
344
|
+
props.sdtType = "buildingBlockGallery";
|
|
345
|
+
}),
|
|
346
|
+
docPartList: kind((props) => {
|
|
347
|
+
props.sdtType = "buildingBlockGallery";
|
|
348
|
+
}),
|
|
349
|
+
dropDownList: kind((props, element) => {
|
|
350
|
+
props.sdtType = "dropdown";
|
|
351
|
+
props.listItems = parseListItems(element);
|
|
352
|
+
readLastValue(element, props);
|
|
353
|
+
}),
|
|
354
|
+
picture: kind((props) => {
|
|
355
|
+
props.sdtType = "picture";
|
|
356
|
+
}),
|
|
357
|
+
richText: kind(() => {}),
|
|
358
|
+
text: kind((props) => {
|
|
359
|
+
props.sdtType = "plainText";
|
|
360
|
+
}),
|
|
361
|
+
citation: kind(() => {}),
|
|
362
|
+
group: kind((props) => {
|
|
363
|
+
props.sdtType = "group";
|
|
364
|
+
}),
|
|
365
|
+
bibliography: kind(() => {})
|
|
366
|
+
};
|
|
367
|
+
const SDT_PROPERTY_UNDECLARED = { [CHECKBOX_CHILD]: kind((props, element) => {
|
|
368
|
+
props.sdtType = "checkbox";
|
|
369
|
+
const state = findChild(element, "w14", "checked") ?? findChild(element, "w", "checked");
|
|
370
|
+
props.checked = state === null ? false : parseBooleanElement(state, "w14");
|
|
371
|
+
}) };
|
|
290
372
|
/**
|
|
291
373
|
* Parse `<w:sdtPr>` (and optional `<w:sdtEndPr>`) into {@link SdtProperties}.
|
|
292
374
|
*
|
|
@@ -301,92 +383,13 @@ const captureSdtSiblingMarkers = (sdt) => {
|
|
|
301
383
|
function parseSdtProperties(sdtPr, sdtEndPr) {
|
|
302
384
|
const props = { sdtType: "richText" };
|
|
303
385
|
if (sdtPr) {
|
|
304
|
-
|
|
305
|
-
const kind = (read) => (element) => {
|
|
306
|
-
read(element);
|
|
307
|
-
return CAPTURE;
|
|
308
|
-
};
|
|
309
|
-
const preserved = dispatchChildren({
|
|
386
|
+
const preserved = dispatchChildrenWithContext({
|
|
310
387
|
element: sdtPr,
|
|
311
388
|
container: "content-control-properties",
|
|
312
|
-
handlers:
|
|
313
|
-
rPr: CAPTURE,
|
|
314
|
-
alias: (element) => {
|
|
315
|
-
const value = getAttributeAnyPrefix(element, "val");
|
|
316
|
-
if (value !== null) props.alias = value;
|
|
317
|
-
return keptUnless(value !== null);
|
|
318
|
-
},
|
|
319
|
-
tag: (element) => {
|
|
320
|
-
const value = getAttributeAnyPrefix(element, "val");
|
|
321
|
-
if (value !== null) props.tag = value;
|
|
322
|
-
return keptUnless(value !== null);
|
|
323
|
-
},
|
|
324
|
-
id: (element) => {
|
|
325
|
-
const raw = getAttributeAnyPrefix(element, "val");
|
|
326
|
-
const value = raw === null ? NaN : Number.parseInt(raw, 10);
|
|
327
|
-
if (!Number.isNaN(value)) props.id = value;
|
|
328
|
-
return keptUnless(!Number.isNaN(value));
|
|
329
|
-
},
|
|
330
|
-
lock: (element) => {
|
|
331
|
-
const value = narrowEnum(getAttributeAnyPrefix(element, "val"), SdtLockSchema);
|
|
332
|
-
if (value !== void 0) props.lock = value;
|
|
333
|
-
return keptUnless(value !== void 0);
|
|
334
|
-
},
|
|
335
|
-
placeholder: (element) => {
|
|
336
|
-
const value = getAttributeAnyPrefix(findChild(element, "w", "docPart"), "val");
|
|
337
|
-
if (value !== null) props.placeholder = value;
|
|
338
|
-
return keptUnless(value !== null);
|
|
339
|
-
},
|
|
340
|
-
temporary: CAPTURE,
|
|
341
|
-
showingPlcHdr: (element) => {
|
|
342
|
-
props.showingPlaceholder = parseBooleanElement(element, "w");
|
|
343
|
-
},
|
|
344
|
-
dataBinding: CAPTURE,
|
|
345
|
-
label: CAPTURE,
|
|
346
|
-
tabIndex: CAPTURE,
|
|
347
|
-
equation: kind(() => {}),
|
|
348
|
-
comboBox: kind((element) => {
|
|
349
|
-
props.sdtType = "comboBox";
|
|
350
|
-
props.listItems = parseListItems(element);
|
|
351
|
-
readLastValue(element, props);
|
|
352
|
-
}),
|
|
353
|
-
date: kind((element) => {
|
|
354
|
-
props.sdtType = "date";
|
|
355
|
-
const format = getAttributeAnyPrefix(findChild(element, "w", "dateFormat"), "val");
|
|
356
|
-
if (format !== null) props.dateFormat = format;
|
|
357
|
-
const fullDate = getAttributeAnyPrefix(element, "fullDate");
|
|
358
|
-
if (fullDate !== null) props.dateValueISO = fullDate;
|
|
359
|
-
}),
|
|
360
|
-
docPartObj: kind(() => {
|
|
361
|
-
props.sdtType = "buildingBlockGallery";
|
|
362
|
-
}),
|
|
363
|
-
docPartList: kind(() => {
|
|
364
|
-
props.sdtType = "buildingBlockGallery";
|
|
365
|
-
}),
|
|
366
|
-
dropDownList: kind((element) => {
|
|
367
|
-
props.sdtType = "dropdown";
|
|
368
|
-
props.listItems = parseListItems(element);
|
|
369
|
-
readLastValue(element, props);
|
|
370
|
-
}),
|
|
371
|
-
picture: kind(() => {
|
|
372
|
-
props.sdtType = "picture";
|
|
373
|
-
}),
|
|
374
|
-
richText: kind(() => {}),
|
|
375
|
-
text: kind(() => {
|
|
376
|
-
props.sdtType = "plainText";
|
|
377
|
-
}),
|
|
378
|
-
citation: kind(() => {}),
|
|
379
|
-
group: kind(() => {
|
|
380
|
-
props.sdtType = "group";
|
|
381
|
-
}),
|
|
382
|
-
bibliography: kind(() => {})
|
|
383
|
-
},
|
|
389
|
+
handlers: SDT_PROPERTY_HANDLERS,
|
|
384
390
|
capturePosition: sequencePositions("content-control-properties", sdtPr),
|
|
385
|
-
undeclared:
|
|
386
|
-
|
|
387
|
-
const state = findChild(element, "w14", "checked") ?? findChild(element, "w", "checked");
|
|
388
|
-
props.checked = state === null ? false : parseBooleanElement(state, "w14");
|
|
389
|
-
}) }
|
|
391
|
+
undeclared: SDT_PROPERTY_UNDECLARED,
|
|
392
|
+
context: props
|
|
390
393
|
});
|
|
391
394
|
if (preserved !== void 0) props.preserved = preserved;
|
|
392
395
|
}
|