@stll/folio-core 0.44.0 → 0.46.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/__fixtures__/paragraphs.js +2 -2
- package/dist/ai-edits/apply.js +59 -19
- package/dist/ai-edits/headless.js +2 -1
- package/dist/compare/compare.js +2 -5
- package/dist/compare/content-alignment.js +78 -53
- package/dist/compare/inline-atoms.js +34 -20
- package/dist/compare/scenario.js +2 -5
- package/dist/compare/types.d.ts +9 -1
- package/dist/compare/types.js +12 -1
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/content-controls/checkboxDisplay.d.ts +11 -0
- package/dist/content-controls/checkboxDisplay.js +40 -0
- package/dist/content-controls/findContentControls.js +3 -1
- package/dist/content-controls/mutateContentControls.js +21 -4
- package/dist/controller/contentControlWidgetController.d.ts +1 -0
- package/dist/controller/contentControlWidgetController.js +3 -0
- package/dist/controller/hiddenEditorApi.js +3 -1
- package/dist/controller/hiddenEditorManager.d.ts +1 -1
- package/dist/controller/hiddenEditorManager.js +6 -3
- package/dist/display-list/build/buildDisplayList.js +20 -1
- package/dist/display-list/build/imagePrimitives.d.ts +1 -1
- package/dist/display-list/build/imagePrimitives.js +3 -1
- package/dist/display-list/build/paragraphPrimitives.js +21 -2
- package/dist/display-list/dom/renderDisplayListToDom.js +18 -10
- package/dist/display-list/types.d.ts +17 -0
- package/dist/document-operations.js +14 -3
- package/dist/docx/attributeRemainder.d.ts +43 -0
- package/dist/docx/attributeRemainder.js +65 -0
- package/dist/docx/blockContentParser.d.ts +1 -1
- package/dist/docx/blockContentParser.js +87 -63
- package/dist/docx/blockPlainText.d.ts +3 -4
- package/dist/docx/blockPlainText.js +1 -0
- package/dist/docx/bookmarkPlacement.js +2 -0
- package/dist/docx/borderParser.js +5 -5
- package/dist/docx/commentAnchorIndex.d.ts +30 -0
- package/dist/docx/commentAnchorIndex.js +50 -0
- package/dist/docx/commentParser.d.ts +1 -1
- package/dist/docx/commentParser.js +78 -50
- package/dist/docx/commentRangeIntegrity.d.ts +16 -1
- package/dist/docx/commentRangeIntegrity.js +42 -1
- package/dist/docx/commentRangeJoin.d.ts +9 -0
- package/dist/docx/commentRangeJoin.js +33 -0
- package/dist/docx/commentReferenceCompletion.d.ts +9 -0
- package/dist/docx/commentReferenceCompletion.js +47 -0
- package/dist/docx/commentReferenceNormalization.js +1 -0
- package/dist/docx/commentReplyMarkers.js +11 -19
- package/dist/docx/commentThreadKey.d.ts +18 -0
- package/dist/docx/commentThreadKey.js +22 -0
- package/dist/docx/compatibility.js +1 -0
- package/dist/docx/containerChildren.d.ts +111 -0
- package/dist/docx/containerChildren.gen.d.ts +28 -0
- package/dist/docx/containerChildren.gen.js +246 -0
- package/dist/docx/containerChildren.js +103 -0
- package/dist/docx/diagramPreview.js +87 -27
- package/dist/docx/documentParser.d.ts +1 -1
- package/dist/docx/documentParser.js +3 -3
- package/dist/docx/ensureParaIds.js +17 -7
- package/dist/docx/fieldParser.d.ts +1 -1
- package/dist/docx/fieldParser.js +4 -4
- package/dist/docx/fieldState.d.ts +26 -0
- package/dist/docx/fieldState.js +53 -0
- package/dist/docx/footnoteParser.d.ts +1 -1
- package/dist/docx/graphicFrameLocks.d.ts +16 -4
- package/dist/docx/graphicFrameLocks.js +19 -6
- package/dist/docx/groupDrawingParser.js +3 -3
- package/dist/docx/headerFooterParser.js +1 -1
- package/dist/docx/headerFooterReferenceNormalization.js +1 -0
- package/dist/docx/hyperlinkParser.d.ts +27 -8
- package/dist/docx/hyperlinkParser.js +78 -20
- package/dist/docx/imageParser.d.ts +9 -1
- package/dist/docx/imageParser.js +91 -20
- package/dist/docx/imageRawXml.d.ts +14 -1
- package/dist/docx/imageRawXml.js +30 -6
- package/dist/docx/inlineWrapperContent.d.ts +85 -0
- package/dist/docx/inlineWrapperContent.js +84 -0
- package/dist/docx/mathToMathml.js +12 -14
- package/dist/docx/nonVisualDrawingProps.d.ts +34 -0
- package/dist/docx/nonVisualDrawingProps.js +46 -0
- package/dist/docx/normalizeBaseDirection.js +10 -1
- package/dist/docx/paraIdAttribute.d.ts +21 -0
- package/dist/docx/paraIdAttribute.js +64 -0
- package/dist/docx/paragraphParser.d.ts +1 -1
- package/dist/docx/paragraphParser.js +277 -168
- package/dist/docx/paragraphPropertySource.js +5 -1
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +1 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +9 -52
- package/dist/docx/paragraphTraversal.js +7 -4
- package/dist/docx/parseWarningMessage.js +2 -1
- package/dist/docx/parser.js +2 -2
- package/dist/docx/preservedRunContent.d.ts +32 -0
- package/dist/docx/preservedRunContent.js +86 -0
- package/dist/docx/previewBudget.d.ts +64 -0
- package/dist/docx/previewBudget.js +88 -0
- package/dist/docx/renderedPageBreakNormalization.js +2 -4
- package/dist/docx/revisionIdNormalization.js +17 -5
- package/dist/docx/rezip.js +91 -36
- package/dist/docx/runParser.d.ts +1 -1
- package/dist/docx/runParser.js +16 -12
- package/dist/docx/sdtPropertiesPatch.js +24 -18
- package/dist/docx/sectionParser.js +8 -1
- package/dist/docx/sectionReferenceHistory.js +2 -2
- package/dist/docx/selectiveSave.js +6 -6
- package/dist/docx/selectiveXmlPatch.d.ts +46 -2
- package/dist/docx/selectiveXmlPatch.js +86 -39
- package/dist/docx/serializer/blockSdtSerializer.js +38 -26
- package/dist/docx/serializer/borderSerializer.d.ts +1 -1
- package/dist/docx/serializer/borderSerializer.js +15 -14
- package/dist/docx/serializer/commentSerializer.d.ts +41 -16
- package/dist/docx/serializer/commentSerializer.js +87 -92
- package/dist/docx/serializer/documentSerializer.js +8 -11
- package/dist/docx/serializer/fontTableSerializer.js +6 -6
- package/dist/docx/serializer/headerFooterSerializer.js +12 -14
- package/dist/docx/serializer/markupRangeAttributes.js +2 -2
- package/dist/docx/serializer/noteSerializer.js +8 -8
- package/dist/docx/serializer/numberingSerializer.js +7 -6
- package/dist/docx/serializer/paragraphSerializer.js +93 -72
- package/dist/docx/serializer/partNamespaces.js +2 -2
- package/dist/docx/serializer/runSerializer.js +73 -44
- package/dist/docx/serializer/sectionPropertiesSerializer.js +19 -14
- package/dist/docx/serializer/settingsSerializer.js +4 -3
- package/dist/docx/serializer/stylesSerializer.js +6 -6
- package/dist/docx/serializer/tableSerializer.js +28 -17
- package/dist/docx/serializer/textFormattingSerializer.js +29 -28
- package/dist/docx/serializer/themeSerializer.js +6 -6
- package/dist/docx/serializer/trackedChangeAttributes.js +2 -2
- package/dist/docx/serializer/xmlUtils.d.ts +1 -2
- package/dist/docx/serializer/xmlUtils.js +1 -13
- package/dist/docx/server/boundedArchive.d.ts +12 -0
- package/dist/docx/server/boundedArchive.js +20 -1
- package/dist/docx/server/createBilingualDocument.js +3 -1
- package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
- package/dist/docx/server/materializeYjsDocx.js +9 -1
- package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
- package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
- package/dist/docx/server/validateDocxConformance.js +22 -1
- package/dist/docx/shapeParser.js +12 -10
- package/dist/docx/tableParser.d.ts +1 -1
- package/dist/docx/tableParser.js +206 -85
- package/dist/docx/textBoxParser.d.ts +25 -2
- package/dist/docx/textBoxParser.js +59 -4
- package/dist/docx/unzip.d.ts +23 -0
- package/dist/docx/unzip.js +37 -26
- package/dist/docx/verbatimCapture.js +1 -1
- package/dist/docx/vmlImageParser.d.ts +17 -1
- package/dist/docx/vmlImageParser.js +20 -3
- package/dist/docx/vmlPreview.d.ts +1 -3
- package/dist/docx/vmlPreview.js +2 -30
- package/dist/docx/xmlEncoding.d.ts +5 -0
- package/dist/docx/xmlEncoding.js +12 -0
- package/dist/docx/xmlParser.d.ts +26 -2
- package/dist/docx/xmlParser.js +70 -27
- package/dist/docx/xmlResourceLimits.d.ts +89 -9
- package/dist/docx/xmlResourceLimits.js +105 -24
- package/dist/headless-layout.js +10 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +5 -2
- package/dist/internal/paragraphFormattingSerialization.js +3 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +102 -12
- package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
- package/dist/layout-engine/measure/tableCellFloating.js +2 -0
- package/dist/layout-engine/types.d.ts +23 -1
- package/dist/layout-painter/renderImage.d.ts +5 -1
- package/dist/layout-painter/renderImage.js +14 -6
- package/dist/layout-painter/renderPage.d.ts +2 -0
- package/dist/layout-painter/renderPage.js +4 -0
- package/dist/layout-painter/renderParagraph.d.ts +13 -1
- package/dist/layout-painter/renderParagraph.js +26 -6
- package/dist/managers/autoSaveCodec.d.ts +9 -1
- package/dist/managers/autoSaveCodec.js +14 -12
- package/dist/markdown/images.js +1 -4
- package/dist/markdown/renderBlock.js +1 -0
- package/dist/markdown/renderRuns.d.ts +1 -1
- package/dist/markdown/renderRuns.js +28 -5
- package/dist/markdown/renderTable.js +22 -5
- package/dist/markdown/trailers.js +4 -1
- package/dist/pdf/images.js +142 -6
- package/dist/prosemirror/attrs/index.d.ts +14 -3
- package/dist/prosemirror/attrs/index.js +224 -2
- package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
- package/dist/prosemirror/authoredTransformAttrs.js +64 -0
- package/dist/prosemirror/commands/contentControls.js +10 -2
- package/dist/prosemirror/commands/image.d.ts +9 -2
- package/dist/prosemirror/commands/image.js +43 -28
- package/dist/prosemirror/commands/pageBreak.js +1 -1
- package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
- package/dist/prosemirror/commentReferenceAttrs.js +33 -0
- package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
- package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
- package/dist/prosemirror/conversion/fromProseDoc.js +338 -99
- package/dist/prosemirror/conversion/index.d.ts +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
- package/dist/prosemirror/conversion/toProseDoc.js +551 -327
- package/dist/prosemirror/extensions/StarterKit.js +8 -58
- package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -1
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +45 -27
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
- package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
- package/dist/prosemirror/extensions/markRegistry.d.ts +41 -0
- package/dist/prosemirror/extensions/markRegistry.js +75 -0
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +2 -3
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +63 -0
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +47 -4
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +87 -0
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +20 -0
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +10 -2
- package/dist/prosemirror/extensions/nodes/TableExtension.js +3 -2
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +13 -5
- package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
- package/dist/prosemirror/inlineWrapperStack.js +75 -0
- package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
- package/dist/prosemirror/pageBreakRunProjection.js +19 -9
- package/dist/prosemirror/paragraphFormattingProvenance.d.ts +6 -3
- package/dist/prosemirror/paragraphFormattingProvenance.js +12 -3
- package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
- package/dist/prosemirror/replacedAnnotations.js +165 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +3 -1
- package/dist/prosemirror/runFormattingInlineCarriers.js +5 -1
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +25 -1
- package/dist/prosemirror/schema/nodes.d.ts +139 -3
- package/dist/prosemirror/schema/nodes.js +16 -1
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
- package/dist/prosemirror/validation.js +16 -2
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
- package/dist/prosemirror/yjsDocumentMetadata.js +171 -0
- package/dist/prosemirror/zeroWidthAnchors.js +2 -0
- package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
- package/dist/render-dom/commentAnchorAttributes.js +54 -0
- package/dist/server.d.ts +3 -1
- package/dist/server.js +3 -1
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/base64.d.ts +36 -0
- package/dist/utils/base64.js +40 -0
- package/dist/utils/clipboard.d.ts +9 -1
- package/dist/utils/clipboard.js +29 -2
- package/dist/utils/findReplace.js +1 -1
- package/dist/utils/imageLuminance.d.ts +15 -0
- package/dist/utils/imageLuminance.js +32 -0
- package/dist/utils/mergeDocumentContent.js +7 -17
- package/dist/utils/replaceText.js +1 -0
- package/dist/utils/units.d.ts +10 -1
- package/dist/utils/units.js +12 -1
- package/dist/utils/urlSecurity.d.ts +8 -2
- package/dist/utils/urlSecurity.js +21 -3
- package/package.json +2 -2
- package/dist/docx/blockRangeMarkers.d.ts +0 -36
- package/dist/docx/blockRangeMarkers.js +0 -59
- package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
- package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { joinCommentRangesAcrossParagraphs } from "../../docx/commentRangeJoin.js";
|
|
2
|
+
import { completeCommentReferences } from "../../docx/commentReferenceCompletion.js";
|
|
1
3
|
import { EDITED_PREVIEW_FINGERPRINT, imageRawXmlFingerprint } from "../../docx/imageRawXml.js";
|
|
4
|
+
import { isInlineSdtContent } from "../../docx/inlineWrapperContent.js";
|
|
2
5
|
import { isNumberingReference } from "../../docx/numberingReference.js";
|
|
3
6
|
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, ParagraphPropertySourceValidationError, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, linkParagraphPropertySourceCandidate, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceTokenMatchesContract, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings } from "../../docx/paragraphPropertySource.js";
|
|
4
7
|
import { visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
@@ -10,13 +13,17 @@ import { OUTLINE_STYLE_CSS_ALIASES, normalizeShapeTextAnchor } from "../../types
|
|
|
10
13
|
import { canonicalJson } from "../../utils/canonicalJson.js";
|
|
11
14
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
12
15
|
import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
13
|
-
import { pixelsToEmu } from "../../utils/units.js";
|
|
14
|
-
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
16
|
+
import { emuToPixels, emuToStrokePixels, pixelsToEmu } from "../../utils/units.js";
|
|
17
|
+
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectPreservedBlockAttrs, expectPreservedXmlAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
18
|
+
import { readAuthoredTransform } from "../authoredTransformAttrs.js";
|
|
15
19
|
import { autospacingMatchesBase, hasAutospacingBaseSide } from "../autospacingBase.js";
|
|
16
20
|
import { bookmarkBoundaryDisplacement, expectBookmarkBoundaryAttrs } from "../bookmarkBoundaryAttrs.js";
|
|
17
21
|
import { paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges } from "../commands/propertyChangeScope.js";
|
|
22
|
+
import { expectCommentReferenceAttrs } from "../commentReferenceAttrs.js";
|
|
23
|
+
import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
|
|
18
24
|
import { applyRunFormattingOverrideAttrs, buildRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
19
25
|
import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
|
|
26
|
+
import { inlineWrapperMember, inlineWrapperStackKey } from "../inlineWrapperStack.js";
|
|
20
27
|
import { listRenderingFromAttrs as listRenderingFromAttrs$1 } from "../listRenderingAttrs.js";
|
|
21
28
|
import { resolveNumberedRefFields } from "../numberedRefFields.js";
|
|
22
29
|
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
@@ -26,6 +33,7 @@ import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
|
26
33
|
import { authoredRunFormattingFromAttrs, hasAuthoredRunFormattingProvenance } from "../runFormattingProvenance.js";
|
|
27
34
|
import { paragraphFormattingForRun, paragraphRunStyleContext, resolveEffectiveRunStyleFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
28
35
|
import { schema } from "../schema/index.js";
|
|
36
|
+
import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
|
|
29
37
|
import { parseShapeGeometryAdjustments } from "../shapeGeometryAdjustments.js";
|
|
30
38
|
import { expectTextBoxAnchorAttrs } from "../textBoxAnchorAttrs.js";
|
|
31
39
|
import { assertValidProseMirrorDocument } from "../validation.js";
|
|
@@ -51,19 +59,6 @@ function normalizeShapeOutlineStyle(style) {
|
|
|
51
59
|
if (style in OUTLINE_STYLE_CSS_ALIASES) return OUTLINE_STYLE_CSS_ALIASES[style];
|
|
52
60
|
return narrowEnum(style, ShapeOutlineStyleSchema);
|
|
53
61
|
}
|
|
54
|
-
function parseTransformAttr(transformStr) {
|
|
55
|
-
if (!transformStr) return;
|
|
56
|
-
const transform = {};
|
|
57
|
-
const rotateMatch = /rotate\((?<deg>[-\d.]+)deg\)/u.exec(transformStr);
|
|
58
|
-
if (rotateMatch) {
|
|
59
|
-
const rotation = Number.parseFloat(rotateMatch.groups["deg"]);
|
|
60
|
-
if (Number.isFinite(rotation)) transform.rotation = rotation;
|
|
61
|
-
}
|
|
62
|
-
if (transformStr.includes("scaleX(-1)")) transform.flipH = true;
|
|
63
|
-
if (transformStr.includes("scaleY(-1)")) transform.flipV = true;
|
|
64
|
-
if (transform.rotation === void 0 && !transform.flipH && !transform.flipV) return;
|
|
65
|
-
return transform;
|
|
66
|
-
}
|
|
67
62
|
function imagePositionFromAttrs(attrs) {
|
|
68
63
|
const horizontalPosition = attrs?.horizontal;
|
|
69
64
|
const verticalPosition = attrs?.vertical;
|
|
@@ -79,14 +74,35 @@ function imagePositionFromAttrs(attrs) {
|
|
|
79
74
|
vertical
|
|
80
75
|
};
|
|
81
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* The EMUs behind one pixel attribute of a drawing.
|
|
79
|
+
*
|
|
80
|
+
* `toProseDoc` carries the authored EMU beside every pixel value it derived,
|
|
81
|
+
* because EMU → px → EMU does not land back on the same number. While the
|
|
82
|
+
* pixel attribute still projects from the authored EMU nothing has moved it,
|
|
83
|
+
* so the document gets its own value back; once an editor command has, the
|
|
84
|
+
* pixel attribute is the truth and converts.
|
|
85
|
+
*/
|
|
86
|
+
const emuFromPixels = (px, key, authored, project) => {
|
|
87
|
+
const emu = authored?.[key];
|
|
88
|
+
return emu !== void 0 && project(emu) === px ? emu : pixelsToEmu(px);
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Copy the wrap insets onto a wrap. Shared by the image, shape and text-box
|
|
92
|
+
* paths so one rule decides when an inset keeps its authored EMU.
|
|
93
|
+
*/
|
|
94
|
+
const assignWrapDistances = (wrap, attrs) => {
|
|
95
|
+
const authored = attrs._docxAuthoredEmu;
|
|
96
|
+
if (attrs.distTop !== void 0) wrap.distT = emuFromPixels(attrs.distTop, "distTop", authored, emuToPixels);
|
|
97
|
+
if (attrs.distBottom !== void 0) wrap.distB = emuFromPixels(attrs.distBottom, "distBottom", authored, emuToPixels);
|
|
98
|
+
if (attrs.distLeft !== void 0) wrap.distL = emuFromPixels(attrs.distLeft, "distLeft", authored, emuToPixels);
|
|
99
|
+
if (attrs.distRight !== void 0) wrap.distR = emuFromPixels(attrs.distRight, "distRight", authored, emuToPixels);
|
|
100
|
+
};
|
|
82
101
|
function textBoxWrapFromAttrs(attrs) {
|
|
83
102
|
if (!(attrs.wrapType !== void 0 && attrs.wrapType !== "inline" || attrs.wrapText !== void 0 || attrs.distTop !== void 0 || attrs.distBottom !== void 0 || attrs.distLeft !== void 0 || attrs.distRight !== void 0)) return;
|
|
84
103
|
const wrap = { type: attrs.wrapType ?? "inline" };
|
|
85
104
|
if (attrs.wrapText !== void 0) wrap.wrapText = attrs.wrapText;
|
|
86
|
-
|
|
87
|
-
if (attrs.distBottom !== void 0) wrap.distB = pixelsToEmu(attrs.distBottom);
|
|
88
|
-
if (attrs.distLeft !== void 0) wrap.distL = pixelsToEmu(attrs.distLeft);
|
|
89
|
-
if (attrs.distRight !== void 0) wrap.distR = pixelsToEmu(attrs.distRight);
|
|
105
|
+
assignWrapDistances(wrap, attrs);
|
|
90
106
|
return wrap;
|
|
91
107
|
}
|
|
92
108
|
const assignUniqueParagraph = (paragraphs, paraId, paragraph) => {
|
|
@@ -215,6 +231,8 @@ function fromProseDoc(pmDoc, baseDocument) {
|
|
|
215
231
|
if (proseContractAttribute !== null && proseContractAttribute !== void 0 && proseContract === null || (baseContract ?? null) !== proseContract) throw sourceValidationError("contract_mismatch", "The ProseMirror document does not match its paragraph-property source document.");
|
|
216
232
|
const tokenSources = baseContract && proseContract && baseDocument ? validateParagraphPropertySourceTokens(pmDoc, baseDocument, baseContract) : null;
|
|
217
233
|
const blocks = extractBlocks(pmDoc, "resolve", baseDocument?.package.styles ? createStyleEngine(baseDocument.package.styles) : null);
|
|
234
|
+
joinCommentRangesAcrossParagraphs(blocks);
|
|
235
|
+
completeCommentReferences(blocks);
|
|
218
236
|
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
219
237
|
if (tokenSources) restoreParagraphPropertySourcesByToken(blocks, tokenSources);
|
|
220
238
|
else if (baseDocument) restoreParagraphPropertySources(blocks, baseDocument.package.document.content, linkedSources.targets, linkedSources.sources);
|
|
@@ -431,42 +449,9 @@ function materializeNumberedRefValues(doc) {
|
|
|
431
449
|
};
|
|
432
450
|
return visit(doc);
|
|
433
451
|
}
|
|
434
|
-
|
|
435
|
-
const fieldResultHasExplicitPageBreak = (node) => extractParagraphContent(node, void 0, void 0, /* @__PURE__ */ new Map(), false).filter((content) => content.type === "run" || content.type === "hyperlink").some((content) => {
|
|
436
|
-
return (content.type === "run" ? [content] : content.children).some((run) => run.type === "run" && run.content.some((runContent) => runContent.type === "break" && runContent.breakType === "page"));
|
|
437
|
-
});
|
|
438
|
-
/**
|
|
439
|
-
* PAGE and NUMPAGES have a stable visible fallback. Other empty fields may
|
|
440
|
-
* intentionally have no result (for example an empty TOC); inventing a space
|
|
441
|
-
* changes their authored result on every save/reopen cycle. A field whose
|
|
442
|
-
* result already carries an explicit page break owns that break's run, so the
|
|
443
|
-
* fallback would displace it.
|
|
444
|
-
*/
|
|
445
|
-
function materializeSerializerFieldFallbacks(doc) {
|
|
446
|
-
const visit = (node) => {
|
|
447
|
-
if (node.type.name === "field" || node.type.name === "structuredField") {
|
|
448
|
-
const attrs = expectFieldAttrs(node);
|
|
449
|
-
return (attrs.fieldType === "PAGE" || attrs.fieldType === "NUMPAGES") && !attrs.displayText && !fieldResultHasExplicitPageBreak(node) ? recreateProseNodeWithParagraphPropertySource(node, { attrs: {
|
|
450
|
-
...node.attrs,
|
|
451
|
-
displayText: SERIALIZER_EMPTY_PAGE_FIELD_RESULT
|
|
452
|
-
} }) : node;
|
|
453
|
-
}
|
|
454
|
-
if (node.childCount === 0) return node;
|
|
455
|
-
const children = [];
|
|
456
|
-
let changed = false;
|
|
457
|
-
node.forEach((child) => {
|
|
458
|
-
const mappedChild = visit(child);
|
|
459
|
-
children.push(mappedChild);
|
|
460
|
-
changed ||= mappedChild !== child;
|
|
461
|
-
});
|
|
462
|
-
return changed ? recreateProseNodeWithParagraphPropertySource(node, { content: Fragment.fromArray(children) }) : node;
|
|
463
|
-
};
|
|
464
|
-
return visit(doc);
|
|
465
|
-
}
|
|
466
|
-
function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null, emptyFieldResult = "serializerFallback") {
|
|
452
|
+
function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null) {
|
|
467
453
|
const strippedDoc = stripSuggestedProvenance(inputDoc, styleResolver);
|
|
468
|
-
const
|
|
469
|
-
const pmDoc = emptyFieldResult === "serializerFallback" ? materializeSerializerFieldFallbacks(refResolvedDoc) : refResolvedDoc;
|
|
454
|
+
const pmDoc = refResolution === "resolve" ? materializeNumberedRefValues(strippedDoc) : strippedDoc;
|
|
470
455
|
const blocks = [];
|
|
471
456
|
const textBoxAnchorMarkers = /* @__PURE__ */ new Map();
|
|
472
457
|
const documentCounts = buildDocumentTrackedChangeCounts(pmDoc);
|
|
@@ -509,15 +494,69 @@ function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null
|
|
|
509
494
|
pendingPageBreaks = 0;
|
|
510
495
|
} else if (node.type.name === "blockSdt") {
|
|
511
496
|
if (pendingPageBreaks > 0 && !appendPendingPageBreaksToPreviousParagraph()) flushPendingPageBreaks();
|
|
512
|
-
blocks.push(convertPMBlockSdt(node, styleResolver
|
|
497
|
+
blocks.push(convertPMBlockSdt(node, styleResolver));
|
|
498
|
+
previousStandaloneTextBox = null;
|
|
499
|
+
} else if (node.type.name === "preservedBlock") {
|
|
500
|
+
blocks.push({
|
|
501
|
+
type: "preservedBlock",
|
|
502
|
+
xml: expectPreservedBlockAttrs(node).xml
|
|
503
|
+
});
|
|
513
504
|
previousStandaloneTextBox = null;
|
|
514
505
|
}
|
|
515
506
|
});
|
|
516
507
|
if (pendingPageBreaks > 0 && !appendPendingPageBreaksToPreviousParagraph()) flushPendingPageBreaks();
|
|
517
508
|
removeUnresolvedTextBoxAnchors(blocks, textBoxAnchorMarkers);
|
|
509
|
+
keepOneAttributeRemainderPerRecord(blocks);
|
|
518
510
|
return blocks;
|
|
519
511
|
}
|
|
520
|
-
|
|
512
|
+
/**
|
|
513
|
+
* The attribute remainder follows the record it was authored on, and only it.
|
|
514
|
+
*
|
|
515
|
+
* ProseMirror copies a node's attrs when a command splits it, so pressing
|
|
516
|
+
* Enter in the middle of a paragraph produces two nodes holding the *same*
|
|
517
|
+
* remainder array. Writing it back on both would give the new half a
|
|
518
|
+
* revision-session id nobody assigned to it: `w:rsidR` says which editing
|
|
519
|
+
* session wrote this paragraph, and a copy of it is a claim about history the
|
|
520
|
+
* author did not make. The rule is that the half that comes first in document
|
|
521
|
+
* order keeps the authored identity, and the other half is a new record with
|
|
522
|
+
* no remainder — the same answer a paragraph the editor created from scratch
|
|
523
|
+
* gets, which is none.
|
|
524
|
+
*
|
|
525
|
+
* Reference identity is what tells the two cases apart, and it is exact: two
|
|
526
|
+
* records that each parsed their own attributes hold different arrays however
|
|
527
|
+
* equal their contents, and only a copy made by the editor shares one.
|
|
528
|
+
*/
|
|
529
|
+
const keepOneAttributeRemainderPerRecord = (blocks) => {
|
|
530
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
531
|
+
const keepFirst = (record) => {
|
|
532
|
+
const remainder = record.preservedAttributes;
|
|
533
|
+
if (remainder === void 0) return;
|
|
534
|
+
if (seen.has(remainder)) {
|
|
535
|
+
delete record.preservedAttributes;
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
seen.add(remainder);
|
|
539
|
+
};
|
|
540
|
+
const walk = (content) => {
|
|
541
|
+
for (const block of content) switch (block.type) {
|
|
542
|
+
case "paragraph":
|
|
543
|
+
keepFirst(block);
|
|
544
|
+
break;
|
|
545
|
+
case "table":
|
|
546
|
+
for (const row of block.rows) {
|
|
547
|
+
keepFirst(row);
|
|
548
|
+
for (const cell of row.cells) walk(cell.content);
|
|
549
|
+
}
|
|
550
|
+
break;
|
|
551
|
+
case "blockSdt":
|
|
552
|
+
walk(block.content);
|
|
553
|
+
break;
|
|
554
|
+
default: break;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
walk(blocks);
|
|
558
|
+
};
|
|
559
|
+
function convertPMBlockSdt(node, styleResolver) {
|
|
521
560
|
const attrs = expectBlockSdtAttrs(node);
|
|
522
561
|
const properties = { sdtType: attrs.sdtType };
|
|
523
562
|
if (attrs.alias) properties.alias = attrs.alias;
|
|
@@ -535,7 +574,7 @@ function convertPMBlockSdt(node, styleResolver, emptyFieldResult) {
|
|
|
535
574
|
if (attrs.rawEndPropertiesXml) properties.rawEndPropertiesXml = attrs.rawEndPropertiesXml;
|
|
536
575
|
if (attrs.rawSdtChildrenBeforeContent) properties.rawSdtChildrenBeforeContent = attrs.rawSdtChildrenBeforeContent;
|
|
537
576
|
if (attrs.rawSdtChildrenAfterContent) properties.rawSdtChildrenAfterContent = attrs.rawSdtChildrenAfterContent;
|
|
538
|
-
const extracted = extractBlocks(node.type.schema.node("doc", null, node.content), "inherit", styleResolver
|
|
577
|
+
const extracted = extractBlocks(node.type.schema.node("doc", null, node.content), "inherit", styleResolver);
|
|
539
578
|
return {
|
|
540
579
|
type: "blockSdt",
|
|
541
580
|
properties,
|
|
@@ -573,6 +612,7 @@ function appendTextBoxBlock(blocks, node, options) {
|
|
|
573
612
|
if (!mergeTextBoxIntoTrailingInlineSdts(options.previousStandaloneTextBox.paragraph, paragraph, attrs._docxInlineSdts ?? [])) options.previousStandaloneTextBox.paragraph.content.push(...paragraph.content);
|
|
574
613
|
return options.previousStandaloneTextBox;
|
|
575
614
|
}
|
|
615
|
+
if (attrs._docxPlacement === "standalone" && attrs._preservedAttributes?.length) paragraph.preservedAttributes = attrs._preservedAttributes;
|
|
576
616
|
prependPageBreaks(paragraph, options.pendingPageBreaks);
|
|
577
617
|
blocks.push(paragraph);
|
|
578
618
|
return attrs._docxPlacement === "standalone" && attrs._docxGroupId ? {
|
|
@@ -626,7 +666,7 @@ function findTextBoxShapeRun(content) {
|
|
|
626
666
|
if (item.content.some((runContent) => runContent.type === "shape" && runContent.shape.shapeType === "textBox")) return item;
|
|
627
667
|
continue;
|
|
628
668
|
}
|
|
629
|
-
if (item.type === "inlineSdt" || item.type === "hyperlink" || item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
669
|
+
if (item.type === "inlineSdt" || item.type === "hyperlink" || item.type === "inlineWrapper" || item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
630
670
|
const run = findTextBoxShapeRun(item.type === "hyperlink" ? item.children : item.content);
|
|
631
671
|
if (run) return run;
|
|
632
672
|
}
|
|
@@ -642,6 +682,7 @@ function replaceTextBoxAnchorInBlocks(blocks, marker, textBoxRun) {
|
|
|
642
682
|
for (const row of block.rows) for (const cell of row.cells) if (replaceTextBoxAnchorInBlocks(cell.content, marker, textBoxRun)) return true;
|
|
643
683
|
continue;
|
|
644
684
|
}
|
|
685
|
+
if (block.type === "preservedBlock") continue;
|
|
645
686
|
if (replaceTextBoxAnchorInBlocks(block.content, marker, textBoxRun)) return true;
|
|
646
687
|
}
|
|
647
688
|
return false;
|
|
@@ -664,7 +705,7 @@ const textBoxAnchorHost = (item) => {
|
|
|
664
705
|
case "deletion":
|
|
665
706
|
case "moveFrom":
|
|
666
707
|
case "moveTo":
|
|
667
|
-
case "
|
|
708
|
+
case "inlineWrapper": return item.content;
|
|
668
709
|
case "run":
|
|
669
710
|
case "complexField":
|
|
670
711
|
case "bookmarkStart":
|
|
@@ -676,7 +717,8 @@ const textBoxAnchorHost = (item) => {
|
|
|
676
717
|
case "moveFromRangeEnd":
|
|
677
718
|
case "moveToRangeStart":
|
|
678
719
|
case "moveToRangeEnd":
|
|
679
|
-
case "mathEquation":
|
|
720
|
+
case "mathEquation":
|
|
721
|
+
case "preservedInline": return;
|
|
680
722
|
default: panic(`Unsupported paragraph content: ${JSON.stringify(item)}`);
|
|
681
723
|
}
|
|
682
724
|
};
|
|
@@ -709,6 +751,7 @@ function removeTextBoxAnchorFromBlocks(blocks, marker) {
|
|
|
709
751
|
for (const row of block.rows) for (const cell of row.cells) if (removeTextBoxAnchorFromBlocks(cell.content, marker)) return true;
|
|
710
752
|
continue;
|
|
711
753
|
}
|
|
754
|
+
if (block.type === "preservedBlock") continue;
|
|
712
755
|
if (removeTextBoxAnchorFromBlocks(block.content, marker)) return true;
|
|
713
756
|
}
|
|
714
757
|
return false;
|
|
@@ -804,6 +847,7 @@ function convertPMParagraph(node, documentCounts, textBoxAnchorMarkers, styleRes
|
|
|
804
847
|
else if (attrs.sectionBreakType) paragraph.sectionProperties = { sectionStart: attrs.sectionBreakType };
|
|
805
848
|
if (attrs._propertyChanges && attrs._propertyChanges.length > 0) paragraph.propertyChanges = attrs._propertyChanges.map(propertyChangeFromAttrs);
|
|
806
849
|
if (attrs.pPrMark) paragraph.pPrMark = attrs.pPrMark;
|
|
850
|
+
if (attrs._preservedAttributes && attrs._preservedAttributes.length > 0) paragraph.preservedAttributes = attrs._preservedAttributes;
|
|
807
851
|
linkParagraphPropertySourceCandidate(paragraph, node);
|
|
808
852
|
return paragraph;
|
|
809
853
|
}
|
|
@@ -906,6 +950,9 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
906
950
|
else delete result.styleId;
|
|
907
951
|
assignBooleanToggle(result, attrs, orig, "pageBreakBefore");
|
|
908
952
|
assignBooleanToggle(result, attrs, orig, "widowControl");
|
|
953
|
+
assignBooleanToggle(result, attrs, orig, "keepNext");
|
|
954
|
+
assignBooleanToggle(result, attrs, orig, "keepLines");
|
|
955
|
+
assignBooleanToggle(result, attrs, orig, "runInWithNext");
|
|
909
956
|
assignBooleanToggle(result, attrs, orig, "snapToGrid");
|
|
910
957
|
assignBooleanToggle(result, attrs, orig, "kinsoku");
|
|
911
958
|
assignBooleanToggle(result, attrs, orig, "overflowPunctuation");
|
|
@@ -931,10 +978,13 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
931
978
|
const contextualSpacing = authored("contextualSpacing", attrs.contextualSpacing);
|
|
932
979
|
const pageBreakBefore = authored("pageBreakBefore", attrs.pageBreakBefore);
|
|
933
980
|
const widowControl = authored("widowControl", attrs.widowControl);
|
|
981
|
+
const keepNext = authored("keepNext", attrs.keepNext);
|
|
982
|
+
const keepLines = authored("keepLines", attrs.keepLines);
|
|
983
|
+
const runInWithNext = authored("runInWithNext", attrs.runInWithNext);
|
|
934
984
|
const kinsoku = authored("kinsoku", attrs.kinsoku);
|
|
935
985
|
const overflowPunctuation = authored("overflowPunctuation", attrs.overflowPunctuation);
|
|
936
986
|
const suppressAutoHyphens = authored("suppressAutoHyphens", attrs.suppressAutoHyphens);
|
|
937
|
-
if (!(directAlignment !== void 0 || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || hasDirectLineSpacing || hasDirectLineSpacingRule || snapToGrid != null || indentLeft || indentRight || indentFirstLine || attrs.numPr || attrs.styleId || borders || shading || tabs || typeof outlineLevel === "number" || contextualSpacing || attrs.spacingExplicit || bidi != null || pageBreakBefore != null || widowControl != null || kinsoku != null || overflowPunctuation != null || suppressAutoHyphens != null)) return;
|
|
987
|
+
if (!(directAlignment !== void 0 || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || hasDirectLineSpacing || hasDirectLineSpacingRule || snapToGrid != null || indentLeft || indentRight || indentFirstLine || attrs.numPr || attrs.styleId || borders || shading || tabs || typeof outlineLevel === "number" || contextualSpacing || attrs.spacingExplicit || bidi != null || pageBreakBefore != null || widowControl != null || keepNext != null || keepLines != null || runInWithNext != null || kinsoku != null || overflowPunctuation != null || suppressAutoHyphens != null)) return;
|
|
938
988
|
const f = {};
|
|
939
989
|
if (directAlignment !== void 0) f.alignment = directAlignment;
|
|
940
990
|
if (shouldSerializeSpaceBefore) f.spaceBefore = spaceBefore;
|
|
@@ -959,6 +1009,9 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
959
1009
|
if (bidi != null) f.bidi = bidi;
|
|
960
1010
|
if (pageBreakBefore != null) f.pageBreakBefore = pageBreakBefore;
|
|
961
1011
|
if (widowControl != null) f.widowControl = widowControl;
|
|
1012
|
+
if (keepNext != null) f.keepNext = keepNext;
|
|
1013
|
+
if (keepLines != null) f.keepLines = keepLines;
|
|
1014
|
+
if (runInWithNext != null) f.runInWithNext = runInWithNext;
|
|
962
1015
|
if (kinsoku != null) f.kinsoku = kinsoku;
|
|
963
1016
|
if (overflowPunctuation != null) f.overflowPunctuation = overflowPunctuation;
|
|
964
1017
|
if (suppressAutoHyphens != null) f.suppressAutoHyphens = suppressAutoHyphens;
|
|
@@ -987,6 +1040,70 @@ function createTrackedRunWrapper(type, info, child) {
|
|
|
987
1040
|
content
|
|
988
1041
|
};
|
|
989
1042
|
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Comment ids in the order their markers are written at a shared boundary.
|
|
1045
|
+
*
|
|
1046
|
+
* Two ranges that begin or end at the same position have no order in the
|
|
1047
|
+
* editor, where each is a mark, so every emission site orders them by id: a
|
|
1048
|
+
* boundary written in the order the marks happened to open is a different
|
|
1049
|
+
* document each time the same one is saved.
|
|
1050
|
+
*/
|
|
1051
|
+
const byCommentId = (ids) => [...ids].toSorted((a, b) => a - b);
|
|
1052
|
+
/** The wrappers `node` sits inside, outermost first; empty when it sits in none. */
|
|
1053
|
+
const inlineWrapperStackOf = (node) => {
|
|
1054
|
+
const mark = node.marks.find((candidate) => candidate.type.name === INLINE_WRAPPER_MARK_NAME);
|
|
1055
|
+
return mark ? expectInlineWrapperMarkAttrs(mark).stack : [];
|
|
1056
|
+
};
|
|
1057
|
+
const isRevisionWrapper = (item) => item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo";
|
|
1058
|
+
/** `stack` closed around `content`, outermost layer first. */
|
|
1059
|
+
const nestInlineWrappers = (stack, content) => {
|
|
1060
|
+
const innermost = stack.at(-1);
|
|
1061
|
+
if (innermost === void 0) panic("An inline wrapper group carries no layer");
|
|
1062
|
+
let wrapper = inlineWrapperMember(innermost, content);
|
|
1063
|
+
for (const layer of stack.slice(0, -1).toReversed()) wrapper = inlineWrapperMember(layer, [wrapper]);
|
|
1064
|
+
return wrapper;
|
|
1065
|
+
};
|
|
1066
|
+
/**
|
|
1067
|
+
* The emitted sequence with each wrapper group nested back into the wrappers
|
|
1068
|
+
* `toProseDoc` lifted off it.
|
|
1069
|
+
*
|
|
1070
|
+
* The revision stays outermost. folio already writes a revision outside the
|
|
1071
|
+
* hyperlink it spans, the parse leg is revision-owned, and accepting or
|
|
1072
|
+
* rejecting one is a range operation over the revision's own content; a
|
|
1073
|
+
* wrapper placed outside two revisions would also have to mint one revision id
|
|
1074
|
+
* per wrapper. So a revision in the group keeps its place and takes the nest
|
|
1075
|
+
* inside it, and the items around it share a nest of their own.
|
|
1076
|
+
*
|
|
1077
|
+
* A group with nothing in it writes no wrapper: an authored wrapper whose
|
|
1078
|
+
* content was deleted or rejected is gone, and an empty one says nothing.
|
|
1079
|
+
*/
|
|
1080
|
+
const nestInlineWrapperGroups = (items, groups) => {
|
|
1081
|
+
const nested = [];
|
|
1082
|
+
for (const [index, group] of groups.entries()) {
|
|
1083
|
+
const slice = items.slice(group.start, groups[index + 1]?.start ?? items.length);
|
|
1084
|
+
if (group.stack.length === 0) {
|
|
1085
|
+
nested.push(...slice);
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
let pending = [];
|
|
1089
|
+
const closeNest = () => {
|
|
1090
|
+
if (pending.length === 0) return;
|
|
1091
|
+
nested.push(nestInlineWrappers(group.stack, pending));
|
|
1092
|
+
pending = [];
|
|
1093
|
+
};
|
|
1094
|
+
for (const item of slice) {
|
|
1095
|
+
if (!isRevisionWrapper(item)) {
|
|
1096
|
+
pending.push(item);
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
closeNest();
|
|
1100
|
+
if (item.content.length > 0) item.content = [nestInlineWrappers(group.stack, item.content)];
|
|
1101
|
+
nested.push(item);
|
|
1102
|
+
}
|
|
1103
|
+
closeNest();
|
|
1104
|
+
}
|
|
1105
|
+
return nested;
|
|
1106
|
+
};
|
|
990
1107
|
function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, textBoxAnchorMarkers, skipLeadingRenderedPageBreak = false, inheritedFormattingOverride) {
|
|
991
1108
|
const content = [];
|
|
992
1109
|
const paragraphStyleContext = paragraph.type.name === "paragraph" ? paragraphRunStyleContext(paragraph) : void 0;
|
|
@@ -1003,6 +1120,11 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1003
1120
|
})).toSorted((left, right) => left.attrs.offset - right.attrs.offset || left.order - right.order);
|
|
1004
1121
|
let nextEmptyHyperlink = 0;
|
|
1005
1122
|
let leadingRenderedPageBreakPending = skipLeadingRenderedPageBreak;
|
|
1123
|
+
const wrapperGroups = [{
|
|
1124
|
+
start: 0,
|
|
1125
|
+
stack: []
|
|
1126
|
+
}];
|
|
1127
|
+
let wrapperGroupKey = "";
|
|
1006
1128
|
let currentRun = null;
|
|
1007
1129
|
let currentMarksKey = null;
|
|
1008
1130
|
let currentHyperlink = null;
|
|
@@ -1056,14 +1178,14 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1056
1178
|
if (toClose.length === 0 && toOpen.length === 0) return;
|
|
1057
1179
|
flushCurrentInline();
|
|
1058
1180
|
currentTrackedChange = void 0;
|
|
1059
|
-
for (const commentId of toClose
|
|
1181
|
+
for (const commentId of byCommentId(toClose)) {
|
|
1060
1182
|
content.push({
|
|
1061
1183
|
type: "commentRangeEnd",
|
|
1062
1184
|
id: commentId
|
|
1063
1185
|
});
|
|
1064
1186
|
openedComments.delete(commentId);
|
|
1065
1187
|
}
|
|
1066
|
-
for (const commentId of toOpen
|
|
1188
|
+
for (const commentId of byCommentId(toOpen)) {
|
|
1067
1189
|
content.push({
|
|
1068
1190
|
type: "commentRangeStart",
|
|
1069
1191
|
id: commentId
|
|
@@ -1081,13 +1203,45 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1081
1203
|
content.push(createEmptyHyperlink(item.attrs));
|
|
1082
1204
|
}
|
|
1083
1205
|
};
|
|
1206
|
+
/**
|
|
1207
|
+
* Cut the emitted sequence where the wrapper the nodes sit inside changes.
|
|
1208
|
+
*
|
|
1209
|
+
* Nothing that spans nodes may span the cut: a run, a hyperlink and a
|
|
1210
|
+
* revision each sit inside one wrapper or outside it, never half in. The
|
|
1211
|
+
* comment ranges `syncCommentRanges` writes are cut with the rest, which
|
|
1212
|
+
* puts a range that opens or closes inside a wrapper inside it, as Word
|
|
1213
|
+
* writes it; a range marker says the same thing at either level, because the
|
|
1214
|
+
* wrapper is transparent and the position is unchanged.
|
|
1215
|
+
*/
|
|
1216
|
+
const enterWrapperGroup = (node) => {
|
|
1217
|
+
const stack = inlineWrapperStackOf(node);
|
|
1218
|
+
const key = inlineWrapperStackKey(stack);
|
|
1219
|
+
if (key === wrapperGroupKey) return;
|
|
1220
|
+
flushCurrentInline();
|
|
1221
|
+
currentTrackedChange = void 0;
|
|
1222
|
+
wrapperGroupKey = key;
|
|
1223
|
+
wrapperGroups.push({
|
|
1224
|
+
start: content.length,
|
|
1225
|
+
stack
|
|
1226
|
+
});
|
|
1227
|
+
};
|
|
1084
1228
|
const processInlineNode = (node, offset) => {
|
|
1085
1229
|
if (node.type.name === "renderedPageBreak" && leadingRenderedPageBreakPending) {
|
|
1086
1230
|
leadingRenderedPageBreakPending = false;
|
|
1087
1231
|
return;
|
|
1088
1232
|
}
|
|
1089
1233
|
leadingRenderedPageBreakPending = false;
|
|
1234
|
+
enterWrapperGroup(node);
|
|
1090
1235
|
syncCommentRanges(node, offset);
|
|
1236
|
+
if (node.type.name === "commentReference") {
|
|
1237
|
+
flushCurrentInline();
|
|
1238
|
+
currentTrackedChange = void 0;
|
|
1239
|
+
content.push({
|
|
1240
|
+
type: "commentReference",
|
|
1241
|
+
id: expectCommentReferenceAttrs(node).commentId
|
|
1242
|
+
});
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1091
1245
|
const linkMark = node.marks.find((m) => m.type.name === "hyperlink");
|
|
1092
1246
|
const noteRefMark = node.marks.find((m) => m.type.name === "footnoteRef");
|
|
1093
1247
|
const insertionMark = node.marks.find((m) => m.type.name === "insertion");
|
|
@@ -1180,6 +1334,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1180
1334
|
});
|
|
1181
1335
|
return;
|
|
1182
1336
|
}
|
|
1337
|
+
if (isInlineLevelPreservedXml(node)) {
|
|
1338
|
+
currentTrackedChange.hyperlink.children.push(createPreservedInline(node));
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1183
1341
|
const run = createTrackedChangeRun({
|
|
1184
1342
|
...formattingContext,
|
|
1185
1343
|
marks: otherMarks,
|
|
@@ -1226,6 +1384,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1226
1384
|
currentTrackedChange.wrapper.content.push(createMathFromNode(node));
|
|
1227
1385
|
return;
|
|
1228
1386
|
}
|
|
1387
|
+
if (isInlineLevelPreservedXml(node)) {
|
|
1388
|
+
currentTrackedChange.wrapper.content.push(createPreservedInline(node));
|
|
1389
|
+
return;
|
|
1390
|
+
}
|
|
1229
1391
|
const run = createTrackedChangeRun({
|
|
1230
1392
|
...formattingContext,
|
|
1231
1393
|
marks: otherMarks,
|
|
@@ -1295,6 +1457,9 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1295
1457
|
} else if (node.type.name === "symbol") {
|
|
1296
1458
|
flushCurrentInline();
|
|
1297
1459
|
content.push(createSymbolRun(node, node.marks, formattingContext));
|
|
1460
|
+
} else if (node.type.name === "preservedXml") {
|
|
1461
|
+
flushCurrentInline();
|
|
1462
|
+
content.push(isInlineLevelPreservedXml(node) ? createPreservedInline(node) : createPreservedXmlRun(node, node.marks, formattingContext));
|
|
1298
1463
|
} else if (node.type.name === "hardBreak") {
|
|
1299
1464
|
flushCurrentInline();
|
|
1300
1465
|
content.push(createBreakRun(expectHardBreakAttrs(node), node.marks, formattingContext));
|
|
@@ -1349,11 +1514,11 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1349
1514
|
});
|
|
1350
1515
|
flushEmptyHyperlinksThroughOffset(Number.POSITIVE_INFINITY);
|
|
1351
1516
|
flushCurrentInline();
|
|
1352
|
-
for (const commentId of openedComments) content.push({
|
|
1517
|
+
for (const commentId of byCommentId(openedComments)) content.push({
|
|
1353
1518
|
type: "commentRangeEnd",
|
|
1354
1519
|
id: commentId
|
|
1355
1520
|
});
|
|
1356
|
-
return content;
|
|
1521
|
+
return nestInlineWrapperGroups(content, wrapperGroups);
|
|
1357
1522
|
}
|
|
1358
1523
|
function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting, marks, node, paragraphMarkFormatting, paragraphMarkPrecedesStyle, styleResolver }) {
|
|
1359
1524
|
const formattingContext = {
|
|
@@ -1378,6 +1543,7 @@ function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting,
|
|
|
1378
1543
|
};
|
|
1379
1544
|
restoreRunPropertyChanges(run, marks);
|
|
1380
1545
|
} else if (node.type.name === "symbol") run = createSymbolRun(node, marks, formattingContext);
|
|
1546
|
+
else if (node.type.name === "preservedXml") run = createPreservedXmlRun(node, marks, formattingContext);
|
|
1381
1547
|
else if (node.type.name === "hardBreak") run = createBreakRun(expectHardBreakAttrs(node), marks, formattingContext);
|
|
1382
1548
|
else if (node.type.name === "pageBreakRun") {
|
|
1383
1549
|
const { clear } = expectPageBreakRunAttrs(node);
|
|
@@ -1552,6 +1718,16 @@ function addNodeToHyperlink({ baseParagraphFormatting, hyperlink, inheritedForma
|
|
|
1552
1718
|
}));
|
|
1553
1719
|
return;
|
|
1554
1720
|
}
|
|
1721
|
+
if (node.type.name === "preservedXml") {
|
|
1722
|
+
hyperlink.children.push(isInlineLevelPreservedXml(node) ? createPreservedInline(node) : createPreservedXmlRun(node, nonLinkMarks, {
|
|
1723
|
+
baseParagraphFormatting,
|
|
1724
|
+
inheritedFormatting,
|
|
1725
|
+
paragraphMarkFormatting,
|
|
1726
|
+
paragraphMarkPrecedesStyle,
|
|
1727
|
+
styleResolver
|
|
1728
|
+
}));
|
|
1729
|
+
return;
|
|
1730
|
+
}
|
|
1555
1731
|
if (node.type.name === "hardBreak") {
|
|
1556
1732
|
hyperlink.children.push(createBreakRun(expectHardBreakAttrs(node), nonLinkMarks, {
|
|
1557
1733
|
baseParagraphFormatting,
|
|
@@ -1649,6 +1825,44 @@ function createSymbolRun(node, marks, formattingContext) {
|
|
|
1649
1825
|
restoreRunPropertyChanges(run, marks);
|
|
1650
1826
|
return run;
|
|
1651
1827
|
}
|
|
1828
|
+
/**
|
|
1829
|
+
* Whether the atom's markup is a paragraph child rather than a run child.
|
|
1830
|
+
*
|
|
1831
|
+
* The two are the same node in the editor and different elements in the file:
|
|
1832
|
+
* `w:ruby` has to go back inside a `w:r` and `w:permStart` may not, because
|
|
1833
|
+
* the schema admits no such child of a run and Word reports the package as
|
|
1834
|
+
* unreadable content.
|
|
1835
|
+
*/
|
|
1836
|
+
const isInlineLevelPreservedXml = (node) => node.type.name === "preservedXml" && expectPreservedXmlAttrs(node).level === PRESERVED_XML_LEVELS.inline;
|
|
1837
|
+
/** The paragraph-level capture an inline-level atom writes back. */
|
|
1838
|
+
const createPreservedInline = (node) => {
|
|
1839
|
+
const { xml, text } = expectPreservedXmlAttrs(node);
|
|
1840
|
+
return {
|
|
1841
|
+
type: "preservedInline",
|
|
1842
|
+
xml,
|
|
1843
|
+
text
|
|
1844
|
+
};
|
|
1845
|
+
};
|
|
1846
|
+
/**
|
|
1847
|
+
* Rebuild the run around a preserved child. The markup is opaque and comes
|
|
1848
|
+
* back byte for byte; only the run properties around it are rebuilt from the
|
|
1849
|
+
* atom's marks, exactly as for a symbol.
|
|
1850
|
+
*/
|
|
1851
|
+
function createPreservedXmlRun(node, marks, formattingContext) {
|
|
1852
|
+
const { xml, text } = expectPreservedXmlAttrs(node);
|
|
1853
|
+
const run = {
|
|
1854
|
+
type: "run",
|
|
1855
|
+
content: [{
|
|
1856
|
+
type: "preservedXml",
|
|
1857
|
+
xml,
|
|
1858
|
+
text
|
|
1859
|
+
}]
|
|
1860
|
+
};
|
|
1861
|
+
const formatting = getAtomRunFormattingFromMarks(marks, formattingContext);
|
|
1862
|
+
if (formatting) run.formatting = formatting;
|
|
1863
|
+
restoreRunPropertyChanges(run, marks);
|
|
1864
|
+
return run;
|
|
1865
|
+
}
|
|
1652
1866
|
function restoreRunPropertyChanges(run, marks) {
|
|
1653
1867
|
const changeMark = marks.find((mark) => mark.type.name === "runPropertyChange");
|
|
1654
1868
|
if (!changeMark) return;
|
|
@@ -1791,7 +2005,7 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1791
2005
|
paragraphMarkFormatting,
|
|
1792
2006
|
paragraphMarkPrecedesStyle: paragraphMarkPrecedesStyle ?? false,
|
|
1793
2007
|
styleResolver: styleResolver ?? null
|
|
1794
|
-
}).filter((content) => content.type === "run" || content.type === "hyperlink");
|
|
2008
|
+
}).filter((content) => content.type === "run" || content.type === "hyperlink" || content.type === "preservedInline");
|
|
1795
2009
|
const displayText = attrs.displayText ?? "";
|
|
1796
2010
|
const displayRun = {
|
|
1797
2011
|
type: "run",
|
|
@@ -1812,8 +2026,8 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1812
2026
|
fieldCode: [],
|
|
1813
2027
|
fieldResult: fieldContent.length > 0 ? fieldContent.filter((content) => content.type === "run") : fallbackFieldContent
|
|
1814
2028
|
};
|
|
1815
|
-
if (attrs.fldLock) complex.fldLock =
|
|
1816
|
-
if (attrs.dirty) complex.dirty =
|
|
2029
|
+
if (attrs.fldLock !== void 0) complex.fldLock = attrs.fldLock;
|
|
2030
|
+
if (attrs.dirty !== void 0) complex.dirty = attrs.dirty;
|
|
1817
2031
|
return complex;
|
|
1818
2032
|
}
|
|
1819
2033
|
const simple = {
|
|
@@ -1822,8 +2036,8 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1822
2036
|
fieldType: attrs.fieldType,
|
|
1823
2037
|
content: fieldContent.length > 0 ? fieldContent : fallbackFieldContent
|
|
1824
2038
|
};
|
|
1825
|
-
if (attrs.fldLock) simple.fldLock =
|
|
1826
|
-
if (attrs.dirty) simple.dirty =
|
|
2039
|
+
if (attrs.fldLock !== void 0) simple.fldLock = attrs.fldLock;
|
|
2040
|
+
if (attrs.dirty !== void 0) simple.dirty = attrs.dirty;
|
|
1827
2041
|
return simple;
|
|
1828
2042
|
}
|
|
1829
2043
|
const synchronizeFieldDisplayText = (content, displayText, fallbackRun) => {
|
|
@@ -1834,6 +2048,7 @@ const synchronizeFieldDisplayText = (content, displayText, fallbackRun) => {
|
|
|
1834
2048
|
visit(child);
|
|
1835
2049
|
continue;
|
|
1836
2050
|
}
|
|
2051
|
+
if (child.type !== "hyperlink") continue;
|
|
1837
2052
|
for (const hyperlinkChild of child.children) if (hyperlinkChild.type === "run") visit(hyperlinkChild);
|
|
1838
2053
|
}
|
|
1839
2054
|
};
|
|
@@ -1879,7 +2094,7 @@ function createInlineSdtFromNode(node, textBoxAnchorMarkers, formattingContext)
|
|
|
1879
2094
|
return {
|
|
1880
2095
|
type: "inlineSdt",
|
|
1881
2096
|
properties: sdtPropertiesFromAttrs(expectSdtAttrs(node)),
|
|
1882
|
-
content: extractParagraphContent(node, void 0, void 0, textBoxAnchorMarkers, false, formattingContext).filter(
|
|
2097
|
+
content: extractParagraphContent(node, void 0, void 0, textBoxAnchorMarkers, false, formattingContext).filter(isInlineSdtContent)
|
|
1883
2098
|
};
|
|
1884
2099
|
}
|
|
1885
2100
|
/**
|
|
@@ -1896,34 +2111,39 @@ const carriedRunFormatting = (formatting) => formatting && Object.keys(formattin
|
|
|
1896
2111
|
function createImageRun(node) {
|
|
1897
2112
|
const attrs = expectImageAttrs(node);
|
|
1898
2113
|
const wrap = { type: attrs.wrapType || "inline" };
|
|
1899
|
-
|
|
1900
|
-
if (attrs.distBottom !== void 0) wrap.distB = pixelsToEmu(attrs.distBottom);
|
|
1901
|
-
if (attrs.distLeft !== void 0) wrap.distL = pixelsToEmu(attrs.distLeft);
|
|
1902
|
-
if (attrs.distRight !== void 0) wrap.distR = pixelsToEmu(attrs.distRight);
|
|
2114
|
+
assignWrapDistances(wrap, attrs);
|
|
1903
2115
|
if (attrs.wrapText) wrap.wrapText = attrs.wrapText;
|
|
2116
|
+
const authoredEmu = attrs._docxAuthoredEmu;
|
|
1904
2117
|
const image = {
|
|
1905
2118
|
type: "image",
|
|
1906
2119
|
rId: attrs.rId || "",
|
|
1907
2120
|
src: attrs.src,
|
|
1908
2121
|
size: {
|
|
1909
|
-
width:
|
|
1910
|
-
height:
|
|
2122
|
+
width: emuFromPixels(attrs.width || 0, "width", authoredEmu, emuToPixels),
|
|
2123
|
+
height: emuFromPixels(attrs.height || 0, "height", authoredEmu, emuToPixels)
|
|
1911
2124
|
},
|
|
1912
2125
|
wrap
|
|
1913
2126
|
};
|
|
1914
2127
|
if (attrs.docPrName != null) image.docPrName = attrs.docPrName;
|
|
1915
2128
|
if (attrs.alt != null) image.alt = attrs.alt;
|
|
1916
2129
|
if (attrs.title != null) image.title = attrs.title;
|
|
1917
|
-
const imageTransform =
|
|
2130
|
+
const imageTransform = readAuthoredTransform(attrs);
|
|
1918
2131
|
if (imageTransform) image.transform = imageTransform;
|
|
1919
2132
|
if (attrs.opacity != null) image.opacity = attrs.opacity;
|
|
2133
|
+
if (attrs.brightness != null || attrs.contrast != null) image.effects = {
|
|
2134
|
+
...attrs.brightness == null ? {} : { brightness: attrs.brightness },
|
|
2135
|
+
...attrs.contrast == null ? {} : { contrast: attrs.contrast }
|
|
2136
|
+
};
|
|
1920
2137
|
const imagePosition = imagePositionFromAttrs(attrs.position);
|
|
1921
2138
|
if (imagePosition) image.position = imagePosition;
|
|
1922
2139
|
if (attrs.layoutInCell !== void 0) image.layoutInCell = attrs.layoutInCell;
|
|
2140
|
+
if (attrs.decorative !== void 0) image.decorative = attrs.decorative;
|
|
2141
|
+
if (attrs.hidden !== void 0) image.hidden = attrs.hidden;
|
|
2142
|
+
if (attrs.docPrExtensions !== void 0) image.docPrExtensions = [...attrs.docPrExtensions];
|
|
1923
2143
|
if (attrs.frameLocks !== void 0) image.frameLocks = { ...attrs.frameLocks };
|
|
1924
2144
|
if (attrs.borderWidth && attrs.borderWidth > 0) {
|
|
1925
2145
|
const outline = {
|
|
1926
|
-
width:
|
|
2146
|
+
width: emuFromPixels(attrs.borderWidth, "borderWidth", authoredEmu, emuToStrokePixels),
|
|
1927
2147
|
style: attrs.borderStyle ? {
|
|
1928
2148
|
solid: "solid",
|
|
1929
2149
|
dotted: "dot",
|
|
@@ -2003,24 +2223,25 @@ const drawingFromImageAttrs = (image, attrs) => {
|
|
|
2003
2223
|
*/
|
|
2004
2224
|
function createShapeRun(node) {
|
|
2005
2225
|
const attrs = expectShapeAttrs(node);
|
|
2226
|
+
const authoredEmu = attrs._docxAuthoredEmu;
|
|
2006
2227
|
const shape = {
|
|
2007
2228
|
type: "shape",
|
|
2008
2229
|
shapeType: attrs.shapeType || "rect",
|
|
2009
2230
|
size: {
|
|
2010
|
-
width: attrs.width ?
|
|
2011
|
-
height: attrs.height ?
|
|
2231
|
+
width: attrs.width ? emuFromPixels(attrs.width, "width", authoredEmu, emuToPixels) : 0,
|
|
2232
|
+
height: attrs.height ? emuFromPixels(attrs.height, "height", authoredEmu, emuToPixels) : 0
|
|
2012
2233
|
}
|
|
2013
2234
|
};
|
|
2014
2235
|
if (attrs.shapeId) shape.id = attrs.shapeId;
|
|
2236
|
+
if (attrs.shapeName !== void 0) shape.name = attrs.shapeName;
|
|
2237
|
+
if (attrs.alt !== void 0) shape.alt = attrs.alt;
|
|
2238
|
+
if (attrs.title !== void 0) shape.title = attrs.title;
|
|
2015
2239
|
const geometryAdjustments = parseShapeGeometryAdjustments(attrs.geometryAdjustments);
|
|
2016
2240
|
if (geometryAdjustments !== void 0) shape.geometryAdjustments = geometryAdjustments;
|
|
2017
|
-
const shapeTransform =
|
|
2241
|
+
const shapeTransform = readAuthoredTransform(attrs);
|
|
2018
2242
|
if (shapeTransform) shape.transform = shapeTransform;
|
|
2019
2243
|
const wrap = { type: attrs.wrapType || "inline" };
|
|
2020
|
-
|
|
2021
|
-
if (attrs.distBottom !== void 0) wrap.distB = pixelsToEmu(attrs.distBottom);
|
|
2022
|
-
if (attrs.distLeft !== void 0) wrap.distL = pixelsToEmu(attrs.distLeft);
|
|
2023
|
-
if (attrs.distRight !== void 0) wrap.distR = pixelsToEmu(attrs.distRight);
|
|
2244
|
+
assignWrapDistances(wrap, attrs);
|
|
2024
2245
|
if (attrs.wrapText) wrap.wrapText = attrs.wrapText;
|
|
2025
2246
|
shape.wrap = wrap;
|
|
2026
2247
|
const shapePosition = imagePositionFromAttrs(attrs.position);
|
|
@@ -2050,11 +2271,15 @@ function createShapeRun(node) {
|
|
|
2050
2271
|
color: attrs.fillColorValue ?? { rgb: attrs.fillColor.replace("#", "") }
|
|
2051
2272
|
};
|
|
2052
2273
|
else if (attrs.fillType === "none") shape.fill = { type: "none" };
|
|
2053
|
-
if (attrs.outlineStyle !== "none" && (attrs.outlineWidth !== void 0 && attrs.outlineWidth > 0 || attrs.outlineColor || attrs.outlineStyle || attrs.outlineCap || attrs.outlineHeadEnd || attrs.outlineTailEnd)) {
|
|
2274
|
+
if (attrs.outlineStyle !== "none" && (attrs.outlineWidth !== void 0 && attrs.outlineWidth > 0 || attrs.outlineColor || attrs.outlineStyle || attrs.outlineCap || attrs.outlineJoin || attrs.outlineHeadEnd || attrs.outlineTailEnd)) {
|
|
2054
2275
|
const shapeOutline = {};
|
|
2055
|
-
if (attrs.outlineWidth !== void 0 && attrs.outlineWidth > 0) shapeOutline.width =
|
|
2056
|
-
if (attrs.outlineStyle)
|
|
2276
|
+
if (attrs.outlineWidth !== void 0 && attrs.outlineWidth > 0) shapeOutline.width = emuFromPixels(attrs.outlineWidth, "outlineWidth", authoredEmu, emuToStrokePixels);
|
|
2277
|
+
if (attrs.outlineStyle) {
|
|
2278
|
+
const style = normalizeShapeOutlineStyle(attrs.outlineStyle);
|
|
2279
|
+
if (style !== void 0) shapeOutline.style = style;
|
|
2280
|
+
}
|
|
2057
2281
|
if (attrs.outlineCap) shapeOutline.cap = attrs.outlineCap;
|
|
2282
|
+
if (attrs.outlineJoin) shapeOutline.join = attrs.outlineJoin;
|
|
2058
2283
|
if (attrs.outlineHeadEnd) shapeOutline.headEnd = attrs.outlineHeadEnd;
|
|
2059
2284
|
if (attrs.outlineTailEnd) shapeOutline.tailEnd = attrs.outlineTailEnd;
|
|
2060
2285
|
if (attrs.outlineColor) shapeOutline.color = attrs.outlineColorValue ?? { rgb: attrs.outlineColor.replace("#", "") };
|
|
@@ -2824,6 +3049,7 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges, styleReso
|
|
|
2824
3049
|
const rowFormatting = tableRowAttrsToFormatting(attrs);
|
|
2825
3050
|
if (rowFormatting) row.formatting = rowFormatting;
|
|
2826
3051
|
if (Array.isArray(attrs.trPrChange) && attrs.trPrChange.length > 0) row.propertyChanges = [...attrs.trPrChange];
|
|
3052
|
+
if (attrs._preservedAttributes && attrs._preservedAttributes.length > 0) row.preservedAttributes = attrs._preservedAttributes;
|
|
2827
3053
|
if (attrs.trIns) row.structuralChange = {
|
|
2828
3054
|
type: "tableRowInsertion",
|
|
2829
3055
|
info: {
|
|
@@ -2916,6 +3142,13 @@ function convertPMTableCell(node, documentCounts, styleResolver = null) {
|
|
|
2916
3142
|
textBoxAnchorMarkers,
|
|
2917
3143
|
styleResolver
|
|
2918
3144
|
});
|
|
3145
|
+
else if (contentNode.type.name === "preservedBlock") {
|
|
3146
|
+
content.push({
|
|
3147
|
+
type: "preservedBlock",
|
|
3148
|
+
xml: expectPreservedBlockAttrs(contentNode).xml
|
|
3149
|
+
});
|
|
3150
|
+
previousStandaloneTextBox = null;
|
|
3151
|
+
}
|
|
2919
3152
|
});
|
|
2920
3153
|
removeUnresolvedTextBoxAnchors(content, textBoxAnchorMarkers);
|
|
2921
3154
|
const cell = {
|
|
@@ -3015,6 +3248,7 @@ const projectTextBoxBodyContent = (state, blocks) => {
|
|
|
3015
3248
|
*/
|
|
3016
3249
|
function convertPMTextBox(node, styleResolver = null) {
|
|
3017
3250
|
const attrs = expectTextBoxAttrs(node);
|
|
3251
|
+
const authoredEmu = attrs._docxAuthoredEmu;
|
|
3018
3252
|
const verticalAlign = normalizeShapeTextAnchor(attrs.verticalAlign);
|
|
3019
3253
|
const childBlocks = [];
|
|
3020
3254
|
node.forEach((child) => {
|
|
@@ -3026,8 +3260,8 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3026
3260
|
type: "shape",
|
|
3027
3261
|
shapeType: "textBox",
|
|
3028
3262
|
size: {
|
|
3029
|
-
width: attrs.width ?
|
|
3030
|
-
height: attrs.height ?
|
|
3263
|
+
width: attrs.width ? emuFromPixels(attrs.width, "width", authoredEmu, emuToPixels) : 0,
|
|
3264
|
+
height: attrs.height ? emuFromPixels(attrs.height, "height", authoredEmu, emuToPixels) : 0
|
|
3031
3265
|
},
|
|
3032
3266
|
textBody: {
|
|
3033
3267
|
content: textBodyContent.type === "source-empty" ? [] : textBodyContent.content,
|
|
@@ -3037,16 +3271,19 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3037
3271
|
...verticalAlign !== void 0 ? { anchor: verticalAlign } : {},
|
|
3038
3272
|
margins: (() => {
|
|
3039
3273
|
const m = {};
|
|
3040
|
-
if (typeof attrs.marginTop === "number") m.top =
|
|
3041
|
-
if (typeof attrs.marginBottom === "number") m.bottom =
|
|
3042
|
-
if (typeof attrs.marginLeft === "number") m.left =
|
|
3043
|
-
if (typeof attrs.marginRight === "number") m.right =
|
|
3274
|
+
if (typeof attrs.marginTop === "number") m.top = emuFromPixels(attrs.marginTop, "marginTop", authoredEmu, emuToPixels);
|
|
3275
|
+
if (typeof attrs.marginBottom === "number") m.bottom = emuFromPixels(attrs.marginBottom, "marginBottom", authoredEmu, emuToPixels);
|
|
3276
|
+
if (typeof attrs.marginLeft === "number") m.left = emuFromPixels(attrs.marginLeft, "marginLeft", authoredEmu, emuToPixels);
|
|
3277
|
+
if (typeof attrs.marginRight === "number") m.right = emuFromPixels(attrs.marginRight, "marginRight", authoredEmu, emuToPixels);
|
|
3044
3278
|
return m;
|
|
3045
3279
|
})()
|
|
3046
3280
|
}
|
|
3047
3281
|
};
|
|
3048
3282
|
if (attrs.textBoxId) shape.id = attrs.textBoxId;
|
|
3049
|
-
|
|
3283
|
+
if (attrs.textBoxName !== void 0) shape.name = attrs.textBoxName;
|
|
3284
|
+
if (attrs.alt !== void 0) shape.alt = attrs.alt;
|
|
3285
|
+
if (attrs.title !== void 0) shape.title = attrs.title;
|
|
3286
|
+
const transform = readAuthoredTransform(attrs);
|
|
3050
3287
|
if (transform) shape.transform = transform;
|
|
3051
3288
|
if (attrs.fillColor) shape.fill = {
|
|
3052
3289
|
type: "solid",
|
|
@@ -3054,7 +3291,7 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3054
3291
|
};
|
|
3055
3292
|
if (attrs.outlineStyle !== "none" && attrs.outlineWidth && attrs.outlineWidth > 0) {
|
|
3056
3293
|
const tbOutline = {
|
|
3057
|
-
width:
|
|
3294
|
+
width: emuFromPixels(attrs.outlineWidth, "outlineWidth", authoredEmu, emuToStrokePixels),
|
|
3058
3295
|
style: normalizeShapeOutlineStyle(attrs.outlineStyle) ?? "solid"
|
|
3059
3296
|
};
|
|
3060
3297
|
if (attrs.outlineColor) tbOutline.color = { rgb: attrs.outlineColor.replace("#", "") };
|
|
@@ -3116,8 +3353,10 @@ function updateDocumentContent(originalDocument, pmDoc) {
|
|
|
3116
3353
|
* Used for converting edited header/footer PM content back to the document
|
|
3117
3354
|
* model.
|
|
3118
3355
|
*/
|
|
3119
|
-
function proseDocToBlocks(pmDoc, baseContent, styles
|
|
3120
|
-
const blocks = extractBlocks(pmDoc, "resolve", styles ? createStyleEngine(styles) : null
|
|
3356
|
+
function proseDocToBlocks(pmDoc, baseContent, styles) {
|
|
3357
|
+
const blocks = extractBlocks(pmDoc, "resolve", styles ? createStyleEngine(styles) : null);
|
|
3358
|
+
joinCommentRangesAcrossParagraphs(blocks);
|
|
3359
|
+
completeCommentReferences(blocks);
|
|
3121
3360
|
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
3122
3361
|
if (baseContent) restoreParagraphPropertySources(blocks, baseContent, linkedSources.targets, linkedSources.sources);
|
|
3123
3362
|
return blocks;
|