@stll/folio-core 0.45.0 → 0.47.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 +85 -43
- package/dist/ai-edits/headless.js +2 -2
- package/dist/ai-edits/read.d.ts +1 -0
- package/dist/ai-edits/read.js +1 -0
- package/dist/ai-edits/snapshot.js +32 -27
- package/dist/ai-edits/table-cell-mutations.js +15 -7
- package/dist/ai-edits/table-geometry.js +21 -18
- package/dist/ai-edits/table-template.js +2 -2
- package/dist/compare/compare.js +2 -5
- package/dist/compare/content-alignment.js +108 -12
- package/dist/compare/content-types.d.ts +8 -2
- package/dist/compare/content.js +2 -11
- package/dist/compare/plan.js +7 -4
- package/dist/compare/scenario.js +2 -5
- package/dist/compare/section-boundary-properties.js +1 -2
- 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 +17 -0
- package/dist/content-controls/checkboxDisplay.js +46 -0
- package/dist/content-controls/findContentControls.js +3 -1
- package/dist/content-controls/mutateContentControls.js +57 -43
- 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/controller/layoutPipeline.js +8 -3
- package/dist/display-list/build/buildDisplayList.js +20 -1
- package/dist/display-list/build/imagePrimitives.d.ts +4 -4
- package/dist/display-list/build/imagePrimitives.js +38 -18
- package/dist/display-list/build/pageBorderPrimitives.js +2 -1
- package/dist/display-list/build/paragraphPrimitives.js +113 -14
- package/dist/display-list/build/previewPrimitives.d.ts +10 -0
- package/dist/display-list/build/previewPrimitives.js +89 -0
- package/dist/display-list/build/strokes.d.ts +177 -8
- package/dist/display-list/build/strokes.js +167 -47
- package/dist/display-list/build/tablePrimitives.js +4 -2
- package/dist/display-list/build/textBoxPrimitives.js +6 -4
- package/dist/display-list/build/textDecorations.d.ts +15 -1
- package/dist/display-list/build/textDecorations.js +15 -1
- package/dist/display-list/dom/renderDisplayListToDom.js +11 -21
- package/dist/display-list/primitives.d.ts +13 -2
- package/dist/display-list/primitives.js +36 -1
- package/dist/display-list/types.d.ts +17 -0
- package/dist/document-operations.js +2 -1
- package/dist/docx/attributeRemainder.d.ts +76 -0
- package/dist/docx/attributeRemainder.js +111 -0
- package/dist/docx/blockContentParser.d.ts +3 -1
- package/dist/docx/blockContentParser.js +102 -106
- package/dist/docx/blockPlainText.d.ts +3 -4
- package/dist/docx/blockPlainText.js +3 -0
- package/dist/docx/borderParser.js +26 -11
- package/dist/docx/builtInStyles.d.ts +8 -16
- package/dist/docx/builtInStyles.js +54 -17
- 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 +56 -39
- 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 +3 -1
- package/dist/docx/commentReplyMarkers.js +11 -19
- package/dist/docx/compatibility.js +56 -41
- package/dist/docx/containerChildren.d.ts +208 -0
- package/dist/docx/containerChildren.gen.d.ts +43 -0
- package/dist/docx/containerChildren.gen.js +263 -0
- package/dist/docx/containerChildren.js +153 -0
- package/dist/docx/diagramPreview.d.ts +14 -2
- package/dist/docx/diagramPreview.js +81 -169
- package/dist/docx/documentParser.d.ts +1 -1
- package/dist/docx/documentParser.js +7 -4
- package/dist/docx/drawingAnchor.d.ts +87 -0
- package/dist/docx/drawingAnchor.js +201 -0
- package/dist/docx/drawingUtils.d.ts +43 -38
- package/dist/docx/drawingUtils.js +205 -118
- 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/fontTableParser.js +102 -41
- package/dist/docx/footnoteParser.d.ts +1 -1
- package/dist/docx/footnoteParser.js +10 -6
- package/dist/docx/graphicFrameLocks.d.ts +16 -4
- package/dist/docx/graphicFrameLocks.js +19 -6
- package/dist/docx/groupDrawingParser.js +4 -3
- package/dist/docx/headerFooterParser.js +1 -1
- package/dist/docx/headerFooterReferenceNormalization.js +1 -0
- package/dist/docx/hyperlinkParser.d.ts +66 -9
- package/dist/docx/hyperlinkParser.js +153 -26
- package/dist/docx/imageParser.js +160 -115
- package/dist/docx/index.d.ts +2 -1
- package/dist/docx/index.js +2 -1
- package/dist/docx/inlineContentRemovals.d.ts +28 -0
- package/dist/docx/inlineContentRemovals.js +46 -0
- package/dist/docx/inlineWrapperContent.d.ts +166 -0
- package/dist/docx/inlineWrapperContent.js +165 -0
- package/dist/docx/inlineWrapperParser.d.ts +11 -0
- package/dist/docx/inlineWrapperParser.js +60 -0
- package/dist/docx/nonVisualDrawingProps.d.ts +5 -13
- package/dist/docx/normalizeBaseDirection.js +12 -1
- package/dist/docx/numberingParser.d.ts +25 -2
- package/dist/docx/numberingParser.js +264 -361
- package/dist/docx/numberingReference.d.ts +9 -16
- package/dist/docx/numberingReference.js +17 -16
- package/dist/docx/numberingReferenceNormalization.js +7 -7
- package/dist/docx/ooxmlCounterFormatter.d.ts +1 -1
- package/dist/docx/ooxmlCounterFormatter.js +4 -1
- package/dist/docx/paraIdAttribute.d.ts +111 -0
- package/dist/docx/paraIdAttribute.js +142 -0
- package/dist/docx/paragraphParser.d.ts +10 -25
- package/dist/docx/paragraphParser.js +421 -496
- package/dist/docx/paragraphProperties.d.ts +23 -0
- package/dist/docx/paragraphProperties.js +279 -0
- package/dist/docx/paragraphPropertySource.js +7 -1
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +3 -2
- package/dist/docx/paragraphTextBoxEnrichment.js +20 -59
- package/dist/docx/paragraphTraversal.d.ts +14 -10
- package/dist/docx/paragraphTraversal.js +53 -52
- package/dist/docx/parseWarningMessage.js +5 -1
- package/dist/docx/parserEnums.d.ts +6 -8
- package/dist/docx/parserEnums.js +4 -6
- package/dist/docx/preservedRunContent.d.ts +32 -0
- package/dist/docx/preservedRunContent.js +96 -0
- package/dist/docx/previewBudget.d.ts +44 -23
- package/dist/docx/previewBudget.js +61 -30
- package/dist/docx/propertyElementAttributes.d.ts +178 -0
- package/dist/docx/propertyElementAttributes.js +114 -0
- package/dist/docx/renderedPageBreakNormalization.js +4 -6
- package/dist/docx/rezip.d.ts +28 -2
- package/dist/docx/rezip.js +152 -27
- package/dist/docx/runConsolidator.d.ts +42 -2
- package/dist/docx/runConsolidator.js +60 -6
- package/dist/docx/runParser.d.ts +55 -19
- package/dist/docx/runParser.js +394 -306
- package/dist/docx/runPayload.d.ts +5 -0
- package/dist/docx/runPayload.js +4 -0
- package/dist/docx/sdtProperties.d.ts +39 -5
- package/dist/docx/sdtProperties.js +205 -84
- package/dist/docx/sdtPropertiesPatch.d.ts +5 -9
- package/dist/docx/sdtPropertiesPatch.js +68 -112
- package/dist/docx/sectionParser.d.ts +1 -2
- package/dist/docx/sectionParser.js +241 -238
- package/dist/docx/selectiveSave.js +3 -2
- package/dist/docx/selectiveXmlPatch.d.ts +66 -3
- package/dist/docx/selectiveXmlPatch.js +276 -133
- package/dist/docx/serializer/blockSdtSerializer.js +2 -96
- package/dist/docx/serializer/borderSerializer.d.ts +5 -5
- package/dist/docx/serializer/borderSerializer.js +12 -10
- package/dist/docx/serializer/commentSerializer.js +5 -7
- package/dist/docx/serializer/documentSerializer.js +11 -11
- package/dist/docx/serializer/fontTableSerializer.js +31 -3
- package/dist/docx/serializer/headerFooterSerializer.js +10 -9
- package/dist/docx/serializer/markupRangeAttributes.d.ts +9 -1
- package/dist/docx/serializer/markupRangeAttributes.js +9 -1
- package/dist/docx/serializer/noteSerializer.js +11 -8
- package/dist/docx/serializer/numberingSerializer.d.ts +1 -6
- package/dist/docx/serializer/numberingSerializer.js +81 -79
- package/dist/docx/serializer/paragraphSerializer.d.ts +1 -9
- package/dist/docx/serializer/paragraphSerializer.js +156 -236
- package/dist/docx/serializer/runSerializer.d.ts +1 -5
- package/dist/docx/serializer/runSerializer.js +134 -75
- package/dist/docx/serializer/sdtPropertiesSerializer.d.ts +26 -0
- package/dist/docx/serializer/sdtPropertiesSerializer.js +111 -0
- package/dist/docx/serializer/sectionPropertiesSerializer.js +42 -49
- package/dist/docx/serializer/settingsSerializer.js +6 -4
- package/dist/docx/serializer/stylesSerializer.js +8 -11
- package/dist/docx/serializer/tableSerializer.js +283 -105
- package/dist/docx/serializer/textFormattingSerializer.d.ts +28 -4
- package/dist/docx/serializer/textFormattingSerializer.js +111 -101
- package/dist/docx/serializer/xmlUtils.d.ts +1 -1
- package/dist/docx/serializer/xmlUtils.js +1 -1
- package/dist/docx/server/createBilingualDocument.js +20 -16
- 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/settingsParser.js +7 -4
- package/dist/docx/shadingParser.d.ts +2 -1
- package/dist/docx/shadingParser.js +43 -7
- package/dist/docx/shapeParser.js +13 -8
- package/dist/docx/strictNames.d.ts +11 -0
- package/dist/docx/strictNames.gen.d.ts +45 -0
- package/dist/docx/strictNames.gen.js +50 -0
- package/dist/docx/strictNames.js +43 -0
- package/dist/docx/strictValueEncodings.gen.js +133 -131
- package/dist/docx/styleParser.js +17 -349
- package/dist/docx/tableParser.d.ts +11 -2
- package/dist/docx/tableParser.js +665 -220
- package/dist/docx/textBoxParser.d.ts +28 -3
- package/dist/docx/textBoxParser.js +69 -9
- package/dist/docx/themeColorAttribute.d.ts +13 -0
- package/dist/docx/themeColorAttribute.js +24 -0
- package/dist/docx/trackedMoveRangeNormalization.js +2 -1
- package/dist/docx/unzip.js +5 -4
- package/dist/docx/vmlImageParser.d.ts +30 -5
- package/dist/docx/vmlImageParser.js +91 -32
- package/dist/docx/vmlPreview.js +2 -2
- package/dist/docx/wrapPolygon.d.ts +30 -0
- package/dist/docx/wrapPolygon.js +70 -0
- package/dist/docx/xmlEncoding.d.ts +5 -0
- package/dist/docx/xmlEncoding.js +12 -0
- package/dist/docx/xmlParser.d.ts +23 -1
- package/dist/docx/xmlParser.js +31 -2
- package/dist/fonts/embeddedFonts.js +3 -3
- package/dist/headless-layout.js +12 -1
- package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
- package/dist/i18n/messages/catalogs.gen.js +102 -34
- package/dist/i18n/messages/messages.gen.d.ts +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/headlessRevisionResolution.js +9 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +7 -2
- package/dist/internal/paragraphFormattingSerialization.d.ts +20 -9
- package/dist/internal/paragraphFormattingSerialization.js +118 -83
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +17 -12
- package/dist/layout-bridge/convert/toFlowBlocks.js +267 -101
- package/dist/layout-engine/index.d.ts +2 -2
- package/dist/layout-engine/index.js +53 -17
- package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
- package/dist/layout-engine/measure/measureBlocks.js +6 -10
- package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
- package/dist/layout-engine/measure/tableCellFloating.js +2 -0
- package/dist/layout-engine/measure/tableCellGrid.js +2 -1
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
- package/dist/layout-engine/measure/tableInlinePlacement.js +2 -5
- package/dist/layout-engine/paragraphSequence.js +3 -2
- package/dist/layout-engine/renderedBreakReconciliation.js +2 -1
- package/dist/layout-engine/section-breaks.d.ts +49 -2
- package/dist/layout-engine/section-breaks.js +55 -4
- package/dist/layout-engine/types.d.ts +69 -17
- package/dist/layout-engine/types.js +16 -1
- package/dist/layout-painter/borderStroke.d.ts +18 -4
- package/dist/layout-painter/renderImage.d.ts +5 -1
- package/dist/layout-painter/renderImage.js +10 -3
- package/dist/layout-painter/renderPage.d.ts +2 -0
- package/dist/layout-painter/renderPage.js +10 -4
- package/dist/layout-painter/renderParagraph.d.ts +14 -1
- package/dist/layout-painter/renderParagraph.js +34 -28
- package/dist/layout-painter/renderTable.d.ts +4 -1
- package/dist/layout-painter/renderTable.js +22 -22
- package/dist/layout-painter/renderTextBox.js +5 -3
- package/dist/managers/autoSaveCodec.d.ts +9 -1
- package/dist/managers/autoSaveCodec.js +12 -4
- package/dist/markdown/renderBlock.js +3 -0
- package/dist/markdown/renderRuns.d.ts +1 -1
- package/dist/markdown/renderRuns.js +34 -6
- package/dist/markdown/renderTable.js +24 -6
- package/dist/markdown/trailers.js +4 -1
- package/dist/model.d.ts +3 -3
- package/dist/model.js +2 -2
- package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
- package/dist/paged-layout/sectionBlockWidths.js +26 -4
- package/dist/pdf/images.js +142 -6
- package/dist/prosemirror/attrs/index.d.ts +34 -5
- package/dist/prosemirror/attrs/index.js +639 -48
- package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
- package/dist/prosemirror/authoredTransformAttrs.js +64 -0
- package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +9 -1
- package/dist/prosemirror/bookmarkBoundaryAttrs.js +22 -3
- package/dist/prosemirror/commands/comments.js +68 -53
- package/dist/prosemirror/commands/contentControls.js +33 -20
- package/dist/prosemirror/commands/image.d.ts +10 -3
- package/dist/prosemirror/commands/image.js +46 -29
- package/dist/prosemirror/commands/pageBreak.js +1 -1
- package/dist/prosemirror/commands/paragraph.d.ts +2 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +12 -4
- package/dist/prosemirror/commands/propertyChangeScope.js +22 -4
- package/dist/prosemirror/commands/sectionBreak.d.ts +33 -1
- package/dist/prosemirror/commands/sectionBreak.js +187 -11
- 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 +17 -12
- package/dist/prosemirror/conversion/fromProseDoc.js +553 -207
- package/dist/prosemirror/conversion/index.d.ts +2 -2
- package/dist/prosemirror/conversion/preservedSinkCarriers.d.ts +39 -0
- package/dist/prosemirror/conversion/preservedSinkCarriers.js +19 -0
- package/dist/prosemirror/conversion/runShadingMark.js +14 -1
- package/dist/prosemirror/conversion/sdtAttrs.d.ts +10 -1
- package/dist/prosemirror/conversion/sdtAttrs.js +19 -5
- package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
- package/dist/prosemirror/conversion/toProseDoc.js +801 -411
- package/dist/prosemirror/emptyRangeAnchor.d.ts +53 -0
- package/dist/prosemirror/emptyRangeAnchor.js +158 -0
- package/dist/prosemirror/extensions/StarterKit.js +14 -58
- package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +21 -16
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +48 -29
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
- package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
- package/dist/prosemirror/extensions/features/ListExtension.js +43 -24
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +4 -3
- package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +3 -3
- package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +5 -5
- package/dist/prosemirror/extensions/features/pasteCleanup.d.ts +3 -1
- package/dist/prosemirror/extensions/features/pasteCleanup.js +56 -2
- package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +5 -4
- package/dist/prosemirror/extensions/markRegistry.d.ts +65 -0
- package/dist/prosemirror/extensions/markRegistry.js +138 -0
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +77 -0
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +26 -0
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +134 -0
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -1
- package/dist/prosemirror/extensions/marks/UnderlineExtension.js +12 -18
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +49 -5
- package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.d.ts +29 -0
- package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.js +46 -0
- package/dist/prosemirror/extensions/nodes/BlockSdtExtension.d.ts +4 -3
- package/dist/prosemirror/extensions/nodes/BlockSdtExtension.js +18 -13
- package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +28 -53
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +97 -0
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +24 -1
- package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.d.ts +11 -0
- package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.js +43 -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/RangeAnchorExtension.d.ts +13 -0
- package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.js +65 -0
- package/dist/prosemirror/extensions/nodes/SdtExtension.d.ts +3 -1
- package/dist/prosemirror/extensions/nodes/SdtExtension.js +22 -16
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +7 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +142 -123
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +9 -1
- package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.d.ts +23 -0
- package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.js +57 -0
- package/dist/prosemirror/extensions/types.d.ts +12 -3
- package/dist/prosemirror/index.d.ts +4 -2
- package/dist/prosemirror/index.js +2 -1
- package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
- package/dist/prosemirror/inlineWrapperStack.js +92 -0
- package/dist/prosemirror/listMarker.d.ts +2 -2
- package/dist/prosemirror/listMarker.js +7 -8
- package/dist/prosemirror/listRenderingAttrs.js +11 -1
- package/dist/prosemirror/listState.d.ts +62 -0
- package/dist/prosemirror/listState.js +49 -0
- package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +13 -0
- package/dist/prosemirror/moveRangeBoundaryAttrs.js +114 -0
- package/dist/prosemirror/numberedRefFields.js +4 -4
- package/dist/prosemirror/numberingAttr.d.ts +55 -0
- package/dist/prosemirror/numberingAttr.js +74 -0
- package/dist/prosemirror/outlineLevelAttr.d.ts +29 -0
- package/dist/prosemirror/outlineLevelAttr.js +42 -0
- package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
- package/dist/prosemirror/pageBreakRunProjection.js +19 -9
- package/dist/prosemirror/paragraphFormattingProvenance.d.ts +9 -0
- package/dist/prosemirror/paragraphFormattingProvenance.js +4 -1
- package/dist/prosemirror/plugins/selectionTracker.d.ts +3 -6
- package/dist/prosemirror/plugins/selectionTracker.js +3 -10
- package/dist/prosemirror/rangeAnchorAttrs.d.ts +14 -0
- package/dist/prosemirror/rangeAnchorAttrs.js +101 -0
- package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
- package/dist/prosemirror/replacedAnnotations.js +183 -0
- package/dist/prosemirror/revisionCarriers.d.ts +86 -2
- package/dist/prosemirror/revisionCarriers.js +86 -60
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +5 -1
- package/dist/prosemirror/runFormattingInlineCarriers.js +7 -1
- package/dist/prosemirror/runIdentity.d.ts +28 -0
- package/dist/prosemirror/runIdentity.js +36 -0
- package/dist/prosemirror/runStyleFormatting.js +1 -1
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +47 -4
- package/dist/prosemirror/schema/nodes.d.ts +309 -26
- package/dist/prosemirror/schema/nodes.js +16 -1
- package/dist/prosemirror/sectionCarrier.d.ts +37 -0
- package/dist/prosemirror/sectionCarrier.js +40 -0
- package/dist/prosemirror/selectionState.d.ts +3 -0
- package/dist/prosemirror/selectionState.js +4 -1
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +5 -4
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +15 -13
- package/dist/prosemirror/tableResize.js +5 -6
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +4 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +4 -0
- package/dist/prosemirror/utils/extractTrackedChanges.d.ts +10 -11
- package/dist/prosemirror/utils/extractTrackedChanges.js +109 -92
- package/dist/prosemirror/validation.js +31 -6
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
- package/dist/prosemirror/yjsDocumentMetadata.js +592 -0
- package/dist/prosemirror/zeroWidthAnchors.js +6 -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/style-sets/extract.js +4 -4
- package/dist/style-sets/stellaStyle.js +36 -23
- package/dist/types/colors.d.ts +2 -2
- package/dist/types/content.d.ts +2 -2
- package/dist/types/documentEnumValues.d.ts +53 -26
- package/dist/types/documentEnumValues.js +72 -174
- package/dist/types/formatting.d.ts +2 -2
- package/dist/types/index.d.ts +9 -2
- package/dist/utils/borderCss.d.ts +246 -0
- package/dist/utils/borderCss.js +325 -0
- package/dist/utils/clipboard.d.ts +9 -1
- package/dist/utils/clipboard.js +27 -1
- package/dist/utils/colorResolver.d.ts +4 -3
- package/dist/utils/colorResolver.js +45 -76
- package/dist/utils/createDocument.js +24 -6
- package/dist/utils/findReplace.js +52 -10
- package/dist/utils/formatToStyle.d.ts +84 -2
- package/dist/utils/formatToStyle.js +133 -52
- package/dist/utils/headingCollector.js +3 -2
- package/dist/utils/imageLuminance.d.ts +15 -0
- package/dist/utils/imageLuminance.js +32 -0
- package/dist/utils/mergeDocumentContent.js +12 -20
- package/dist/utils/paragraphFormattingMerge.js +27 -6
- package/dist/utils/replaceText.js +1 -0
- package/dist/utils/tableOperations.d.ts +5 -3
- package/dist/utils/tableOperations.js +14 -1
- package/dist/utils/tablePlacement.d.ts +7 -0
- package/dist/utils/tablePlacement.js +14 -0
- package/dist/utils/textDirectionFlow.d.ts +15 -0
- package/dist/utils/textDirectionFlow.js +38 -0
- package/dist/utils/textFormattingMerge.js +16 -4
- package/package.json +10 -10
- package/dist/ai-edits/__fixtures__/paragraphs.d.ts +0 -17
- package/dist/ai-edits/__fixtures__/paragraphs.js +0 -33
- package/dist/compare/__fixtures__/body-sequence.d.ts +0 -119
- package/dist/compare/__fixtures__/body-sequence.js +0 -225
- package/dist/compare/__fixtures__/nested-table.d.ts +0 -16
- package/dist/compare/__fixtures__/nested-table.js +0 -50
- package/dist/compare/__fixtures__/numbered-list.d.ts +0 -34
- package/dist/compare/__fixtures__/numbered-list.js +0 -85
- package/dist/docx/blockRangeMarkers.d.ts +0 -36
- package/dist/docx/blockRangeMarkers.js +0 -59
- package/dist/docx/bookmarkPlacement.d.ts +0 -9
- package/dist/docx/bookmarkPlacement.js +0 -50
- package/dist/fonts/embeddedFontTable.d.ts +0 -45
- package/dist/fonts/embeddedFontTable.js +0 -80
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +0 -13
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +0 -39
- package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
- package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
|
@@ -1,39 +1,54 @@
|
|
|
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";
|
|
2
|
-
import {
|
|
4
|
+
import { isInlineSdtContent, isSimpleFieldContent } from "../../docx/inlineWrapperContent.js";
|
|
5
|
+
import { paragraphNumberingReferenceId as paragraphNumberingReferenceId$1, sameStatedParagraphNumbering as sameStatedParagraphNumbering$1 } 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
|
-
import { visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
5
|
-
import { ShapeOutlineStyleSchema, narrowEnum } from "../../docx/parserEnums.js";
|
|
7
|
+
import { BLOCK_TREE_DESCENT, visitBlockTreeRecords, visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
6
8
|
import { DATE_UTC_ATTRIBUTE } from "../../docx/trackedChangeInfo.js";
|
|
7
|
-
import {
|
|
9
|
+
import { copiedWrapPolygon } from "../../docx/wrapPolygon.js";
|
|
10
|
+
import { isStyleSourcedParagraphNumbering, modelParagraphFormattingEmission } from "../../internal/paragraphFormattingSerialization.js";
|
|
8
11
|
import { createStyleEngine } from "../../style-engine/styleEngine.js";
|
|
9
|
-
import {
|
|
12
|
+
import { normalizeShapeTextAnchor, presetDashForOutlineAttr } from "../../types/documentEnumValues.js";
|
|
13
|
+
import { presetDashForCssBorderStyle } from "../../utils/borderCss.js";
|
|
10
14
|
import { canonicalJson } from "../../utils/canonicalJson.js";
|
|
11
15
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
12
16
|
import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
13
17
|
import { emuToPixels, emuToStrokePixels, pixelsToEmu } from "../../utils/units.js";
|
|
14
|
-
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs,
|
|
18
|
+
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectParagraphAttrs, expectPreservedBlockAttrs, expectPreservedXmlAttrs, expectRunFormattingOverrideMarkAttrs, expectRunIdentityMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
19
|
+
import { readAuthoredTransform } from "../authoredTransformAttrs.js";
|
|
15
20
|
import { autospacingMatchesBase, hasAutospacingBaseSide } from "../autospacingBase.js";
|
|
16
|
-
import {
|
|
21
|
+
import { bookmarkMarkerFromAttrs, expectBookmarkBoundaryAttrs } from "../bookmarkBoundaryAttrs.js";
|
|
17
22
|
import { paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges } from "../commands/propertyChangeScope.js";
|
|
23
|
+
import { expectCommentReferenceAttrs } from "../commentReferenceAttrs.js";
|
|
24
|
+
import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
|
|
18
25
|
import { applyRunFormattingOverrideAttrs, buildRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
19
26
|
import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
|
|
27
|
+
import "../extensions/nodes/MoveRangeBoundaryExtension.js";
|
|
28
|
+
import "../extensions/nodes/RangeAnchorExtension.js";
|
|
29
|
+
import { inlineWrapperMember, inlineWrapperStackKey } from "../inlineWrapperStack.js";
|
|
20
30
|
import { listRenderingFromAttrs as listRenderingFromAttrs$1 } from "../listRenderingAttrs.js";
|
|
31
|
+
import { expectMoveRangeBoundaryAttrs } from "../moveRangeBoundaryAttrs.js";
|
|
21
32
|
import { resolveNumberedRefFields } from "../numberedRefFields.js";
|
|
22
33
|
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
23
34
|
import { directionToBidi } from "../paragraphDirection.js";
|
|
24
35
|
import { directParagraphSpacing } from "../paragraphSpacing.js";
|
|
36
|
+
import { expectRangeAnchorAttrs } from "../rangeAnchorAttrs.js";
|
|
25
37
|
import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
26
38
|
import { authoredRunFormattingFromAttrs, hasAuthoredRunFormattingProvenance } from "../runFormattingProvenance.js";
|
|
39
|
+
import { RUN_IDENTITY_MARK_NAME } from "../runIdentity.js";
|
|
27
40
|
import { paragraphFormattingForRun, paragraphRunStyleContext, resolveEffectiveRunStyleFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
28
41
|
import { schema } from "../schema/index.js";
|
|
42
|
+
import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
|
|
29
43
|
import { parseShapeGeometryAdjustments } from "../shapeGeometryAdjustments.js";
|
|
30
44
|
import { expectTextBoxAnchorAttrs } from "../textBoxAnchorAttrs.js";
|
|
31
45
|
import { assertValidProseMirrorDocument } from "../validation.js";
|
|
46
|
+
import { hasSinkChildren } from "./preservedSinkCarriers.js";
|
|
32
47
|
import { runShadingAttrsToShading, shadingToRunShadingAttrs } from "./runShadingMark.js";
|
|
33
48
|
import { decodeSdtListItems, sdtPropertiesFromAttrs, sdtPropertiesMatchAttrs } from "./sdtAttrs.js";
|
|
34
49
|
import { panic } from "better-result";
|
|
50
|
+
import { DRAWING_RAW_XML_MODES, relationshipIdOf } from "@stll/docx-core/model";
|
|
35
51
|
import { Fragment } from "prosemirror-model";
|
|
36
|
-
import { DRAWING_RAW_XML_MODES } from "@stll/docx-core/model";
|
|
37
52
|
//#region src/prosemirror/conversion/fromProseDoc.ts
|
|
38
53
|
/**
|
|
39
54
|
* ProseMirror to Document Conversion
|
|
@@ -46,23 +61,16 @@ import { DRAWING_RAW_XML_MODES } from "@stll/docx-core/model";
|
|
|
46
61
|
* - Preserve paragraph attributes (paraId, textId, formatting)
|
|
47
62
|
* - Handle marks -> TextFormatting conversion
|
|
48
63
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
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;
|
|
64
|
+
/**
|
|
65
|
+
* The dash an `outlineStyle` attribute names.
|
|
66
|
+
*
|
|
67
|
+
* `"none"` is the explicit no-outline sentinel rather than a dash, so it
|
|
68
|
+
* returns undefined here: the serializer's no-outline guard drops the `<a:ln>`
|
|
69
|
+
* before this is called.
|
|
70
|
+
*/
|
|
71
|
+
function normalizeShapeOutlineDash(style) {
|
|
72
|
+
const dash = presetDashForOutlineAttr(style);
|
|
73
|
+
return dash === void 0 || dash === "none" ? void 0 : dash;
|
|
66
74
|
}
|
|
67
75
|
function imagePositionFromAttrs(attrs) {
|
|
68
76
|
const horizontalPosition = attrs?.horizontal;
|
|
@@ -93,8 +101,9 @@ const emuFromPixels = (px, key, authored, project) => {
|
|
|
93
101
|
return emu !== void 0 && project(emu) === px ? emu : pixelsToEmu(px);
|
|
94
102
|
};
|
|
95
103
|
/**
|
|
96
|
-
* Copy the wrap insets
|
|
97
|
-
*
|
|
104
|
+
* Copy the wrap insets, the slot each was authored on, and the wrap polygon
|
|
105
|
+
* onto a wrap. Shared by the image, shape and text-box paths so one rule
|
|
106
|
+
* decides when an inset keeps its authored EMU.
|
|
98
107
|
*/
|
|
99
108
|
const assignWrapDistances = (wrap, attrs) => {
|
|
100
109
|
const authored = attrs._docxAuthoredEmu;
|
|
@@ -102,6 +111,22 @@ const assignWrapDistances = (wrap, attrs) => {
|
|
|
102
111
|
if (attrs.distBottom !== void 0) wrap.distB = emuFromPixels(attrs.distBottom, "distBottom", authored, emuToPixels);
|
|
103
112
|
if (attrs.distLeft !== void 0) wrap.distL = emuFromPixels(attrs.distLeft, "distLeft", authored, emuToPixels);
|
|
104
113
|
if (attrs.distRight !== void 0) wrap.distR = emuFromPixels(attrs.distRight, "distRight", authored, emuToPixels);
|
|
114
|
+
const slots = copiedWrapDistanceSlots(attrs.wrapDistanceSlots);
|
|
115
|
+
if (slots !== void 0) wrap.distanceSlots = slots;
|
|
116
|
+
const extents = copiedEffectExtentSlots(attrs.wrapEffectExtentSlots);
|
|
117
|
+
if (extents !== void 0) wrap.effectExtentSlots = extents;
|
|
118
|
+
const polygon = copiedWrapPolygon(attrs.wrapPolygon);
|
|
119
|
+
if (polygon !== void 0) wrap.polygon = polygon;
|
|
120
|
+
};
|
|
121
|
+
/** A copy, so the model cannot share a slot record with a ProseMirror attr. */
|
|
122
|
+
const copiedWrapDistanceSlots = (slots) => slots === void 0 ? void 0 : {
|
|
123
|
+
...slots.drawing === void 0 ? {} : { drawing: { ...slots.drawing } },
|
|
124
|
+
...slots.wrapChild === void 0 ? {} : { wrapChild: { ...slots.wrapChild } }
|
|
125
|
+
};
|
|
126
|
+
/** The same copy, one carrier over. */
|
|
127
|
+
const copiedEffectExtentSlots = (slots) => slots === void 0 ? void 0 : {
|
|
128
|
+
...slots.drawing === void 0 ? {} : { drawing: { ...slots.drawing } },
|
|
129
|
+
...slots.wrapChild === void 0 ? {} : { wrapChild: { ...slots.wrapChild } }
|
|
105
130
|
};
|
|
106
131
|
function textBoxWrapFromAttrs(attrs) {
|
|
107
132
|
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;
|
|
@@ -228,7 +253,12 @@ const restoreLinkedParagraphPropertySources = (content) => {
|
|
|
228
253
|
};
|
|
229
254
|
};
|
|
230
255
|
/** Convert a ProseMirror document to the document model. */
|
|
231
|
-
function fromProseDoc(pmDoc, baseDocument) {
|
|
256
|
+
function fromProseDoc(pmDoc, baseDocument, { reuse = "none" } = {}) {
|
|
257
|
+
switch (reuse) {
|
|
258
|
+
case "none": break;
|
|
259
|
+
case "matched": panic("fromProseDoc: reuse \"matched\" is not implemented");
|
|
260
|
+
default: panic(`fromProseDoc: unhandled reuse ${String(reuse)}`);
|
|
261
|
+
}
|
|
232
262
|
assertValidProseMirrorDocument(pmDoc, "Cannot convert invalid ProseMirror document to DOCX model");
|
|
233
263
|
const baseContract = baseDocument ? getDocumentParagraphPropertySourceContract(baseDocument) : void 0;
|
|
234
264
|
const proseContractAttribute = pmDoc.attrs[PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR];
|
|
@@ -236,6 +266,8 @@ function fromProseDoc(pmDoc, baseDocument) {
|
|
|
236
266
|
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.");
|
|
237
267
|
const tokenSources = baseContract && proseContract && baseDocument ? validateParagraphPropertySourceTokens(pmDoc, baseDocument, baseContract) : null;
|
|
238
268
|
const blocks = extractBlocks(pmDoc, "resolve", baseDocument?.package.styles ? createStyleEngine(baseDocument.package.styles) : null);
|
|
269
|
+
joinCommentRangesAcrossParagraphs(blocks);
|
|
270
|
+
completeCommentReferences(blocks);
|
|
239
271
|
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
240
272
|
if (tokenSources) restoreParagraphPropertySourcesByToken(blocks, tokenSources);
|
|
241
273
|
else if (baseDocument) restoreParagraphPropertySources(blocks, baseDocument.package.document.content, linkedSources.targets, linkedSources.sources);
|
|
@@ -452,42 +484,9 @@ function materializeNumberedRefValues(doc) {
|
|
|
452
484
|
};
|
|
453
485
|
return visit(doc);
|
|
454
486
|
}
|
|
455
|
-
|
|
456
|
-
const fieldResultHasExplicitPageBreak = (node) => extractParagraphContent(node, void 0, void 0, /* @__PURE__ */ new Map(), false).filter((content) => content.type === "run" || content.type === "hyperlink").some((content) => {
|
|
457
|
-
return (content.type === "run" ? [content] : content.children).some((run) => run.type === "run" && run.content.some((runContent) => runContent.type === "break" && runContent.breakType === "page"));
|
|
458
|
-
});
|
|
459
|
-
/**
|
|
460
|
-
* PAGE and NUMPAGES have a stable visible fallback. Other empty fields may
|
|
461
|
-
* intentionally have no result (for example an empty TOC); inventing a space
|
|
462
|
-
* changes their authored result on every save/reopen cycle. A field whose
|
|
463
|
-
* result already carries an explicit page break owns that break's run, so the
|
|
464
|
-
* fallback would displace it.
|
|
465
|
-
*/
|
|
466
|
-
function materializeSerializerFieldFallbacks(doc) {
|
|
467
|
-
const visit = (node) => {
|
|
468
|
-
if (node.type.name === "field" || node.type.name === "structuredField") {
|
|
469
|
-
const attrs = expectFieldAttrs(node);
|
|
470
|
-
return (attrs.fieldType === "PAGE" || attrs.fieldType === "NUMPAGES") && !attrs.displayText && !fieldResultHasExplicitPageBreak(node) ? recreateProseNodeWithParagraphPropertySource(node, { attrs: {
|
|
471
|
-
...node.attrs,
|
|
472
|
-
displayText: SERIALIZER_EMPTY_PAGE_FIELD_RESULT
|
|
473
|
-
} }) : node;
|
|
474
|
-
}
|
|
475
|
-
if (node.childCount === 0) return node;
|
|
476
|
-
const children = [];
|
|
477
|
-
let changed = false;
|
|
478
|
-
node.forEach((child) => {
|
|
479
|
-
const mappedChild = visit(child);
|
|
480
|
-
children.push(mappedChild);
|
|
481
|
-
changed ||= mappedChild !== child;
|
|
482
|
-
});
|
|
483
|
-
return changed ? recreateProseNodeWithParagraphPropertySource(node, { content: Fragment.fromArray(children) }) : node;
|
|
484
|
-
};
|
|
485
|
-
return visit(doc);
|
|
486
|
-
}
|
|
487
|
-
function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null, emptyFieldResult = "serializerFallback") {
|
|
487
|
+
function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null) {
|
|
488
488
|
const strippedDoc = stripSuggestedProvenance(inputDoc, styleResolver);
|
|
489
|
-
const
|
|
490
|
-
const pmDoc = emptyFieldResult === "serializerFallback" ? materializeSerializerFieldFallbacks(refResolvedDoc) : refResolvedDoc;
|
|
489
|
+
const pmDoc = refResolution === "resolve" ? materializeNumberedRefValues(strippedDoc) : strippedDoc;
|
|
491
490
|
const blocks = [];
|
|
492
491
|
const textBoxAnchorMarkers = /* @__PURE__ */ new Map();
|
|
493
492
|
const documentCounts = buildDocumentTrackedChangeCounts(pmDoc);
|
|
@@ -530,15 +529,116 @@ function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null
|
|
|
530
529
|
pendingPageBreaks = 0;
|
|
531
530
|
} else if (node.type.name === "blockSdt") {
|
|
532
531
|
if (pendingPageBreaks > 0 && !appendPendingPageBreaksToPreviousParagraph()) flushPendingPageBreaks();
|
|
533
|
-
blocks.push(convertPMBlockSdt(node, styleResolver
|
|
532
|
+
blocks.push(convertPMBlockSdt(node, styleResolver));
|
|
533
|
+
previousStandaloneTextBox = null;
|
|
534
|
+
} else if (node.type.name === "preservedBlock") {
|
|
535
|
+
blocks.push({
|
|
536
|
+
type: "preservedBlock",
|
|
537
|
+
xml: expectPreservedBlockAttrs(node).xml
|
|
538
|
+
});
|
|
539
|
+
previousStandaloneTextBox = null;
|
|
540
|
+
} else if (node.type.name === "blockBookmarkBoundary") {
|
|
541
|
+
blocks.push(blockBookmarkMarker(node));
|
|
534
542
|
previousStandaloneTextBox = null;
|
|
535
543
|
}
|
|
536
544
|
});
|
|
537
545
|
if (pendingPageBreaks > 0 && !appendPendingPageBreaksToPreviousParagraph()) flushPendingPageBreaks();
|
|
538
546
|
removeUnresolvedTextBoxAnchors(blocks, textBoxAnchorMarkers);
|
|
547
|
+
keepOneRecordCarriedByIdentity(blocks);
|
|
548
|
+
keepTheSectionBreakOnTheLastParagraphThatCarriesIt(blocks);
|
|
539
549
|
return blocks;
|
|
540
550
|
}
|
|
541
|
-
|
|
551
|
+
/**
|
|
552
|
+
* What an authored element carried follows its record, and only it.
|
|
553
|
+
*
|
|
554
|
+
* Two things ride a node's attrs by reference rather than by value: the
|
|
555
|
+
* attribute remainder (`w:rsidR` and its family) and the ordered verbatim sink
|
|
556
|
+
* (the markup a container held beside its modelled children). ProseMirror
|
|
557
|
+
* copies a node's attrs when a command splits or duplicates it, so pressing
|
|
558
|
+
* Enter in the middle of a paragraph produces two nodes holding the *same*
|
|
559
|
+
* remainder array, and copying a table produces two tables holding the same
|
|
560
|
+
* sink. Writing either back on both is a claim the author did not make:
|
|
561
|
+
* `w:rsidR` says which editing session wrote this paragraph, and a second copy
|
|
562
|
+
* of a `w:bookmarkEnd` is a bookmark boundary nobody wrote. The rule is that
|
|
563
|
+
* the record that comes first in document order keeps what was authored, and
|
|
564
|
+
* the other is a new record with none — the same answer a record the editor
|
|
565
|
+
* created from scratch gets.
|
|
566
|
+
*
|
|
567
|
+
* Reference identity is what tells the two cases apart, and it is exact: two
|
|
568
|
+
* records that each parsed their own children and attributes hold different
|
|
569
|
+
* objects however equal their contents, and only a copy made by the editor
|
|
570
|
+
* shares one.
|
|
571
|
+
*
|
|
572
|
+
* The rule holds per block container or it does not hold: a walk that reaches
|
|
573
|
+
* the body, a cell and an `w:sdt` but not a text box leaves the records inside
|
|
574
|
+
* one free to claim an authored revision session each. `visitBlockTreeRecords`
|
|
575
|
+
* is the one traversal, and it is exhaustive over the block union.
|
|
576
|
+
*/
|
|
577
|
+
const keepOneRecordCarriedByIdentity = (blocks) => {
|
|
578
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
579
|
+
/** Whether this object is the authored one rather than a copy's reference. */
|
|
580
|
+
const isAuthored = (value) => {
|
|
581
|
+
if (value === void 0) return true;
|
|
582
|
+
if (seen.has(value)) return false;
|
|
583
|
+
seen.add(value);
|
|
584
|
+
return true;
|
|
585
|
+
};
|
|
586
|
+
const keepFirst = (record) => {
|
|
587
|
+
if (!isAuthored(record.preservedAttributes)) delete record.preservedAttributes;
|
|
588
|
+
if (!isAuthored(record.bookmarks)) delete record.bookmarks;
|
|
589
|
+
if (!isAuthored(record.preserved)) delete record.preserved;
|
|
590
|
+
};
|
|
591
|
+
visitBlockTreeRecords(blocks, (record) => {
|
|
592
|
+
keepFirst(record);
|
|
593
|
+
return BLOCK_TREE_DESCENT.descend;
|
|
594
|
+
});
|
|
595
|
+
};
|
|
596
|
+
/**
|
|
597
|
+
* The section break belongs to the last paragraph that carries it.
|
|
598
|
+
*
|
|
599
|
+
* A `w:sectPr` inside a `w:pPr` says "the section ends at this paragraph's
|
|
600
|
+
* mark". ProseMirror copies a node's attrs when a command splits it, so
|
|
601
|
+
* pressing Enter inside a section-ending paragraph produces two nodes over the
|
|
602
|
+
* *same* `_sectionProperties` object; writing it back on both ends the section
|
|
603
|
+
* twice. The document gains a section nobody added, and its `w:sectPr` repeats
|
|
604
|
+
* the `w:rsidSect` of the real one, so the copy also claims that section's
|
|
605
|
+
* revision history. On a split the trailing half is the half that still ends
|
|
606
|
+
* the section, and the leading half becomes an ordinary paragraph — Word's own
|
|
607
|
+
* rule, and the exact opposite of the remainder's, which stays with the
|
|
608
|
+
* authored half above.
|
|
609
|
+
*
|
|
610
|
+
* The rule lives on the from-leg rather than in the split commands because the
|
|
611
|
+
* commands cannot be enumerated: Enter, a paste that lands several paragraphs
|
|
612
|
+
* in a section-ending one, an AI edit and a tracked-change resolution each
|
|
613
|
+
* split a paragraph by their own route, and a split merged in from another
|
|
614
|
+
* client reaches no local command at all. Every route arrives here.
|
|
615
|
+
*
|
|
616
|
+
* Reference identity is what tells a copy from a second authored break, and it
|
|
617
|
+
* is exact: two paragraphs that each parsed their own `w:sectPr` hold
|
|
618
|
+
* different objects however equal their contents, and only a copy made by the
|
|
619
|
+
* editor shares one. The projection passes the object through by reference and
|
|
620
|
+
* never clones it, which is what keeps that signal alive.
|
|
621
|
+
*/
|
|
622
|
+
const keepTheSectionBreakOnTheLastParagraphThatCarriesIt = (blocks) => {
|
|
623
|
+
const lastCarrier = /* @__PURE__ */ new Map();
|
|
624
|
+
visitBlockTreeRecords(blocks, (record) => {
|
|
625
|
+
if (record.type !== "paragraph" || record.sectionProperties === void 0) return BLOCK_TREE_DESCENT.descend;
|
|
626
|
+
const earlier = lastCarrier.get(record.sectionProperties);
|
|
627
|
+
if (earlier) delete earlier.sectionProperties;
|
|
628
|
+
lastCarrier.set(record.sectionProperties, record);
|
|
629
|
+
return BLOCK_TREE_DESCENT.descend;
|
|
630
|
+
});
|
|
631
|
+
};
|
|
632
|
+
/**
|
|
633
|
+
* A bookmark marker standing between two blocks, back in the model.
|
|
634
|
+
*
|
|
635
|
+
* The node's place in the document is the whole of its position, so nothing is
|
|
636
|
+
* read off it but the marker's own attributes.
|
|
637
|
+
*/
|
|
638
|
+
function blockBookmarkMarker(node) {
|
|
639
|
+
return bookmarkMarkerFromAttrs(expectBookmarkBoundaryAttrs(node));
|
|
640
|
+
}
|
|
641
|
+
function convertPMBlockSdt(node, styleResolver) {
|
|
542
642
|
const attrs = expectBlockSdtAttrs(node);
|
|
543
643
|
const properties = { sdtType: attrs.sdtType };
|
|
544
644
|
if (attrs.alias) properties.alias = attrs.alias;
|
|
@@ -552,11 +652,12 @@ function convertPMBlockSdt(node, styleResolver, emptyFieldResult) {
|
|
|
552
652
|
if (attrs.listItems) properties.listItems = decodeSdtListItems(attrs.listItems);
|
|
553
653
|
if (typeof attrs.dropdownLastValue === "string") properties.dropdownLastValue = attrs.dropdownLastValue;
|
|
554
654
|
if (typeof attrs.checked === "boolean") properties.checked = attrs.checked;
|
|
555
|
-
if (attrs.
|
|
655
|
+
if (attrs._preserved) properties.preserved = attrs._preserved;
|
|
556
656
|
if (attrs.rawEndPropertiesXml) properties.rawEndPropertiesXml = attrs.rawEndPropertiesXml;
|
|
657
|
+
if (attrs.endProperties) properties.endProperties = attrs.endProperties;
|
|
557
658
|
if (attrs.rawSdtChildrenBeforeContent) properties.rawSdtChildrenBeforeContent = attrs.rawSdtChildrenBeforeContent;
|
|
558
659
|
if (attrs.rawSdtChildrenAfterContent) properties.rawSdtChildrenAfterContent = attrs.rawSdtChildrenAfterContent;
|
|
559
|
-
const extracted = extractBlocks(node.type.schema.node("doc", null, node.content), "inherit", styleResolver
|
|
660
|
+
const extracted = extractBlocks(node.type.schema.node("doc", null, node.content), "inherit", styleResolver);
|
|
560
661
|
return {
|
|
561
662
|
type: "blockSdt",
|
|
562
663
|
properties,
|
|
@@ -594,6 +695,7 @@ function appendTextBoxBlock(blocks, node, options) {
|
|
|
594
695
|
if (!mergeTextBoxIntoTrailingInlineSdts(options.previousStandaloneTextBox.paragraph, paragraph, attrs._docxInlineSdts ?? [])) options.previousStandaloneTextBox.paragraph.content.push(...paragraph.content);
|
|
595
696
|
return options.previousStandaloneTextBox;
|
|
596
697
|
}
|
|
698
|
+
if (attrs._docxPlacement === "standalone" && attrs._preservedAttributes?.length) paragraph.preservedAttributes = attrs._preservedAttributes;
|
|
597
699
|
prependPageBreaks(paragraph, options.pendingPageBreaks);
|
|
598
700
|
blocks.push(paragraph);
|
|
599
701
|
return attrs._docxPlacement === "standalone" && attrs._docxGroupId ? {
|
|
@@ -647,7 +749,7 @@ function findTextBoxShapeRun(content) {
|
|
|
647
749
|
if (item.content.some((runContent) => runContent.type === "shape" && runContent.shape.shapeType === "textBox")) return item;
|
|
648
750
|
continue;
|
|
649
751
|
}
|
|
650
|
-
if (item.type === "inlineSdt" || item.type === "hyperlink" || item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
752
|
+
if (item.type === "inlineSdt" || item.type === "hyperlink" || item.type === "inlineWrapper" || item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
651
753
|
const run = findTextBoxShapeRun(item.type === "hyperlink" ? item.children : item.content);
|
|
652
754
|
if (run) return run;
|
|
653
755
|
}
|
|
@@ -663,6 +765,7 @@ function replaceTextBoxAnchorInBlocks(blocks, marker, textBoxRun) {
|
|
|
663
765
|
for (const row of block.rows) for (const cell of row.cells) if (replaceTextBoxAnchorInBlocks(cell.content, marker, textBoxRun)) return true;
|
|
664
766
|
continue;
|
|
665
767
|
}
|
|
768
|
+
if (block.type !== "blockSdt") continue;
|
|
666
769
|
if (replaceTextBoxAnchorInBlocks(block.content, marker, textBoxRun)) return true;
|
|
667
770
|
}
|
|
668
771
|
return false;
|
|
@@ -685,7 +788,7 @@ const textBoxAnchorHost = (item) => {
|
|
|
685
788
|
case "deletion":
|
|
686
789
|
case "moveFrom":
|
|
687
790
|
case "moveTo":
|
|
688
|
-
case "
|
|
791
|
+
case "inlineWrapper": return item.content;
|
|
689
792
|
case "run":
|
|
690
793
|
case "complexField":
|
|
691
794
|
case "bookmarkStart":
|
|
@@ -697,7 +800,8 @@ const textBoxAnchorHost = (item) => {
|
|
|
697
800
|
case "moveFromRangeEnd":
|
|
698
801
|
case "moveToRangeStart":
|
|
699
802
|
case "moveToRangeEnd":
|
|
700
|
-
case "mathEquation":
|
|
803
|
+
case "mathEquation":
|
|
804
|
+
case "preservedInline": return;
|
|
701
805
|
default: panic(`Unsupported paragraph content: ${JSON.stringify(item)}`);
|
|
702
806
|
}
|
|
703
807
|
};
|
|
@@ -730,6 +834,7 @@ function removeTextBoxAnchorFromBlocks(blocks, marker) {
|
|
|
730
834
|
for (const row of block.rows) for (const cell of row.cells) if (removeTextBoxAnchorFromBlocks(cell.content, marker)) return true;
|
|
731
835
|
continue;
|
|
732
836
|
}
|
|
837
|
+
if (block.type !== "blockSdt") continue;
|
|
733
838
|
if (removeTextBoxAnchorFromBlocks(block.content, marker)) return true;
|
|
734
839
|
}
|
|
735
840
|
return false;
|
|
@@ -741,8 +846,8 @@ function removeTextBoxAnchorFromBlocks(blocks, marker) {
|
|
|
741
846
|
* list markers on the way out of the editor.
|
|
742
847
|
*/
|
|
743
848
|
function listRenderingFromAttrs(attrs) {
|
|
744
|
-
const numId = attrs.numPr
|
|
745
|
-
if (
|
|
849
|
+
const numId = paragraphNumberingReferenceId$1(attrs.numPr);
|
|
850
|
+
if (numId === void 0) return;
|
|
746
851
|
if (!(attrs.listMarker != null || attrs.listIsBullet || attrs.listNumFmt != null)) return;
|
|
747
852
|
return listRenderingFromAttrs$1({
|
|
748
853
|
attrs,
|
|
@@ -822,9 +927,9 @@ function convertPMParagraph(node, documentCounts, textBoxAnchorMarkers, styleRes
|
|
|
822
927
|
if (listRendering) paragraph.listRendering = listRendering;
|
|
823
928
|
if (attrs.renderedPageBreakBefore) paragraph.renderedPageBreakBefore = true;
|
|
824
929
|
if (attrs._sectionProperties) paragraph.sectionProperties = attrs._sectionProperties;
|
|
825
|
-
else if (attrs.sectionBreakType) paragraph.sectionProperties = { sectionStart: attrs.sectionBreakType };
|
|
826
930
|
if (attrs._propertyChanges && attrs._propertyChanges.length > 0) paragraph.propertyChanges = attrs._propertyChanges.map(propertyChangeFromAttrs);
|
|
827
931
|
if (attrs.pPrMark) paragraph.pPrMark = attrs.pPrMark;
|
|
932
|
+
if (attrs._preservedAttributes && attrs._preservedAttributes.length > 0) paragraph.preservedAttributes = attrs._preservedAttributes;
|
|
828
933
|
linkParagraphPropertySourceCandidate(paragraph, node);
|
|
829
934
|
return paragraph;
|
|
830
935
|
}
|
|
@@ -842,7 +947,7 @@ const propertyChangeFromAttrs = (change) => {
|
|
|
842
947
|
currentFormatting
|
|
843
948
|
};
|
|
844
949
|
const { numPr, ...previousWithoutNumPr } = previousFormatting;
|
|
845
|
-
const normalizedPrevious = numPr
|
|
950
|
+
const normalizedPrevious = numPr == null ? previousWithoutNumPr : {
|
|
846
951
|
...previousWithoutNumPr,
|
|
847
952
|
numPr
|
|
848
953
|
};
|
|
@@ -915,11 +1020,12 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
915
1020
|
else Reflect.deleteProperty(result, "lineSpacingRule");
|
|
916
1021
|
if (directAlignment === void 0) Reflect.deleteProperty(result, "alignment");
|
|
917
1022
|
else result.alignment = directAlignment;
|
|
918
|
-
|
|
1023
|
+
const statedNumbering = attrs.numPr;
|
|
1024
|
+
if (isStyleSourcedParagraphNumbering(statedNumbering, attrs.numPrFromStyle)) {
|
|
919
1025
|
delete result.numPr;
|
|
920
1026
|
delete result.numPrFromStyle;
|
|
921
|
-
} else if (
|
|
922
|
-
if (
|
|
1027
|
+
} else if (!sameStatedParagraphNumbering$1(statedNumbering, orig.numPr)) {
|
|
1028
|
+
if (statedNumbering !== void 0) result.numPr = statedNumbering;
|
|
923
1029
|
else delete result.numPr;
|
|
924
1030
|
delete result.numPrFromStyle;
|
|
925
1031
|
}
|
|
@@ -961,7 +1067,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
961
1067
|
const kinsoku = authored("kinsoku", attrs.kinsoku);
|
|
962
1068
|
const overflowPunctuation = authored("overflowPunctuation", attrs.overflowPunctuation);
|
|
963
1069
|
const suppressAutoHyphens = authored("suppressAutoHyphens", attrs.suppressAutoHyphens);
|
|
964
|
-
if (!(directAlignment !== void 0 || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || hasDirectLineSpacing || hasDirectLineSpacingRule || snapToGrid != null || indentLeft || indentRight || indentFirstLine || attrs.numPr || attrs.styleId || borders || shading || tabs ||
|
|
1070
|
+
if (!(directAlignment !== void 0 || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || hasDirectLineSpacing || hasDirectLineSpacingRule || snapToGrid != null || indentLeft || indentRight || indentFirstLine || attrs.numPr || attrs.styleId || borders || shading || tabs || outlineLevel !== void 0 || contextualSpacing || attrs.spacingExplicit || bidi != null || pageBreakBefore != null || widowControl != null || keepNext != null || keepLines != null || runInWithNext != null || kinsoku != null || overflowPunctuation != null || suppressAutoHyphens != null)) return;
|
|
965
1071
|
const f = {};
|
|
966
1072
|
if (directAlignment !== void 0) f.alignment = directAlignment;
|
|
967
1073
|
if (shouldSerializeSpaceBefore) f.spaceBefore = spaceBefore;
|
|
@@ -976,12 +1082,12 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
976
1082
|
if (indentRight) f.indentRight = indentRight;
|
|
977
1083
|
if (indentFirstLine) f.indentFirstLine = indentFirstLine;
|
|
978
1084
|
if (attrs.hangingIndent && indentFirstLine) f.hangingIndent = attrs.hangingIndent;
|
|
979
|
-
if (attrs.numPr && !isStyleSourcedParagraphNumbering(attrs.numPr, attrs.numPrFromStyle)) f.numPr = attrs.numPr;
|
|
1085
|
+
if (attrs.numPr !== void 0 && !isStyleSourcedParagraphNumbering(attrs.numPr, attrs.numPrFromStyle)) f.numPr = attrs.numPr;
|
|
980
1086
|
if (attrs.styleId) f.styleId = attrs.styleId;
|
|
981
1087
|
if (borders) f.borders = borders;
|
|
982
1088
|
if (shading) f.shading = shading;
|
|
983
1089
|
if (tabs) f.tabs = tabs;
|
|
984
|
-
if (
|
|
1090
|
+
if (outlineLevel !== void 0) f.outlineLevel = outlineLevel;
|
|
985
1091
|
if (contextualSpacing) f.contextualSpacing = contextualSpacing;
|
|
986
1092
|
if (bidi != null) f.bidi = bidi;
|
|
987
1093
|
if (pageBreakBefore != null) f.pageBreakBefore = pageBreakBefore;
|
|
@@ -1017,6 +1123,70 @@ function createTrackedRunWrapper(type, info, child) {
|
|
|
1017
1123
|
content
|
|
1018
1124
|
};
|
|
1019
1125
|
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Comment ids in the order their markers are written at a shared boundary.
|
|
1128
|
+
*
|
|
1129
|
+
* Two ranges that begin or end at the same position have no order in the
|
|
1130
|
+
* editor, where each is a mark, so every emission site orders them by id: a
|
|
1131
|
+
* boundary written in the order the marks happened to open is a different
|
|
1132
|
+
* document each time the same one is saved.
|
|
1133
|
+
*/
|
|
1134
|
+
const byCommentId = (ids) => [...ids].toSorted((a, b) => a - b);
|
|
1135
|
+
/** The wrappers `node` sits inside, outermost first; empty when it sits in none. */
|
|
1136
|
+
const inlineWrapperStackOf = (node) => {
|
|
1137
|
+
const mark = node.marks.find((candidate) => candidate.type.name === INLINE_WRAPPER_MARK_NAME);
|
|
1138
|
+
return mark ? expectInlineWrapperMarkAttrs(mark).stack : [];
|
|
1139
|
+
};
|
|
1140
|
+
const isRevisionWrapper = (item) => item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo";
|
|
1141
|
+
/** `stack` closed around `content`, outermost layer first. */
|
|
1142
|
+
const nestInlineWrappers = (stack, content) => {
|
|
1143
|
+
const innermost = stack.at(-1);
|
|
1144
|
+
if (innermost === void 0) panic("An inline wrapper group carries no layer");
|
|
1145
|
+
let wrapper = inlineWrapperMember(innermost, content);
|
|
1146
|
+
for (const layer of stack.slice(0, -1).toReversed()) wrapper = inlineWrapperMember(layer, [wrapper]);
|
|
1147
|
+
return wrapper;
|
|
1148
|
+
};
|
|
1149
|
+
/**
|
|
1150
|
+
* The emitted sequence with each wrapper group nested back into the wrappers
|
|
1151
|
+
* `toProseDoc` lifted off it.
|
|
1152
|
+
*
|
|
1153
|
+
* The revision stays outermost. folio already writes a revision outside the
|
|
1154
|
+
* hyperlink it spans, the parse leg is revision-owned, and accepting or
|
|
1155
|
+
* rejecting one is a range operation over the revision's own content; a
|
|
1156
|
+
* wrapper placed outside two revisions would also have to mint one revision id
|
|
1157
|
+
* per wrapper. So a revision in the group keeps its place and takes the nest
|
|
1158
|
+
* inside it, and the items around it share a nest of their own.
|
|
1159
|
+
*
|
|
1160
|
+
* A group with nothing in it writes no wrapper: an authored wrapper whose
|
|
1161
|
+
* content was deleted or rejected is gone, and an empty one says nothing.
|
|
1162
|
+
*/
|
|
1163
|
+
const nestInlineWrapperGroups = (items, groups) => {
|
|
1164
|
+
const nested = [];
|
|
1165
|
+
for (const [index, group] of groups.entries()) {
|
|
1166
|
+
const slice = items.slice(group.start, groups[index + 1]?.start ?? items.length);
|
|
1167
|
+
if (group.stack.length === 0) {
|
|
1168
|
+
nested.push(...slice);
|
|
1169
|
+
continue;
|
|
1170
|
+
}
|
|
1171
|
+
let pending = [];
|
|
1172
|
+
const closeNest = () => {
|
|
1173
|
+
if (pending.length === 0) return;
|
|
1174
|
+
nested.push(nestInlineWrappers(group.stack, pending));
|
|
1175
|
+
pending = [];
|
|
1176
|
+
};
|
|
1177
|
+
for (const item of slice) {
|
|
1178
|
+
if (!isRevisionWrapper(item)) {
|
|
1179
|
+
pending.push(item);
|
|
1180
|
+
continue;
|
|
1181
|
+
}
|
|
1182
|
+
closeNest();
|
|
1183
|
+
if (item.content.length > 0) item.content = [nestInlineWrappers(group.stack, item.content)];
|
|
1184
|
+
nested.push(item);
|
|
1185
|
+
}
|
|
1186
|
+
closeNest();
|
|
1187
|
+
}
|
|
1188
|
+
return nested;
|
|
1189
|
+
};
|
|
1020
1190
|
function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, textBoxAnchorMarkers, skipLeadingRenderedPageBreak = false, inheritedFormattingOverride) {
|
|
1021
1191
|
const content = [];
|
|
1022
1192
|
const paragraphStyleContext = paragraph.type.name === "paragraph" ? paragraphRunStyleContext(paragraph) : void 0;
|
|
@@ -1033,6 +1203,11 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1033
1203
|
})).toSorted((left, right) => left.attrs.offset - right.attrs.offset || left.order - right.order);
|
|
1034
1204
|
let nextEmptyHyperlink = 0;
|
|
1035
1205
|
let leadingRenderedPageBreakPending = skipLeadingRenderedPageBreak;
|
|
1206
|
+
const wrapperGroups = [{
|
|
1207
|
+
start: 0,
|
|
1208
|
+
stack: []
|
|
1209
|
+
}];
|
|
1210
|
+
let wrapperGroupKey = "";
|
|
1036
1211
|
let currentRun = null;
|
|
1037
1212
|
let currentMarksKey = null;
|
|
1038
1213
|
let currentHyperlink = null;
|
|
@@ -1058,7 +1233,7 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1058
1233
|
};
|
|
1059
1234
|
const appendDirectRun = (node, run, coalescePlainText = false) => {
|
|
1060
1235
|
const marksKey = getMarksKey(node.marks);
|
|
1061
|
-
const ownerId =
|
|
1236
|
+
const ownerId = runIdentityId(node);
|
|
1062
1237
|
const currentOwnerId = currentRun ? sourceRunOwners.get(currentRun) : void 0;
|
|
1063
1238
|
const currentRunIsPlainText = currentRun?.content.every((runContent) => runContent.type === "text");
|
|
1064
1239
|
const joinsOwnedSourceRun = ownerId !== void 0 && ownerId === currentOwnerId && currentRun !== null && runsShareProperties(currentRun, run);
|
|
@@ -1086,14 +1261,14 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1086
1261
|
if (toClose.length === 0 && toOpen.length === 0) return;
|
|
1087
1262
|
flushCurrentInline();
|
|
1088
1263
|
currentTrackedChange = void 0;
|
|
1089
|
-
for (const commentId of toClose
|
|
1264
|
+
for (const commentId of byCommentId(toClose)) {
|
|
1090
1265
|
content.push({
|
|
1091
1266
|
type: "commentRangeEnd",
|
|
1092
1267
|
id: commentId
|
|
1093
1268
|
});
|
|
1094
1269
|
openedComments.delete(commentId);
|
|
1095
1270
|
}
|
|
1096
|
-
for (const commentId of toOpen
|
|
1271
|
+
for (const commentId of byCommentId(toOpen)) {
|
|
1097
1272
|
content.push({
|
|
1098
1273
|
type: "commentRangeStart",
|
|
1099
1274
|
id: commentId
|
|
@@ -1111,13 +1286,58 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1111
1286
|
content.push(createEmptyHyperlink(item.attrs));
|
|
1112
1287
|
}
|
|
1113
1288
|
};
|
|
1289
|
+
/**
|
|
1290
|
+
* Cut the emitted sequence where the wrapper the nodes sit inside changes.
|
|
1291
|
+
*
|
|
1292
|
+
* Nothing that spans nodes may span the cut: a run, a hyperlink and a
|
|
1293
|
+
* revision each sit inside one wrapper or outside it, never half in. The
|
|
1294
|
+
* comment ranges `syncCommentRanges` writes are cut with the rest, which
|
|
1295
|
+
* puts a range that opens or closes inside a wrapper inside it, as Word
|
|
1296
|
+
* writes it; a range marker says the same thing at either level, because the
|
|
1297
|
+
* wrapper is transparent and the position is unchanged.
|
|
1298
|
+
*/
|
|
1299
|
+
const enterWrapperGroup = (node) => {
|
|
1300
|
+
const stack = inlineWrapperStackOf(node);
|
|
1301
|
+
const key = inlineWrapperStackKey(stack);
|
|
1302
|
+
if (key === wrapperGroupKey) return;
|
|
1303
|
+
flushCurrentInline();
|
|
1304
|
+
currentTrackedChange = void 0;
|
|
1305
|
+
wrapperGroupKey = key;
|
|
1306
|
+
wrapperGroups.push({
|
|
1307
|
+
start: content.length,
|
|
1308
|
+
stack
|
|
1309
|
+
});
|
|
1310
|
+
};
|
|
1114
1311
|
const processInlineNode = (node, offset) => {
|
|
1115
1312
|
if (node.type.name === "renderedPageBreak" && leadingRenderedPageBreakPending) {
|
|
1116
1313
|
leadingRenderedPageBreakPending = false;
|
|
1117
1314
|
return;
|
|
1118
1315
|
}
|
|
1119
1316
|
leadingRenderedPageBreakPending = false;
|
|
1317
|
+
enterWrapperGroup(node);
|
|
1120
1318
|
syncCommentRanges(node, offset);
|
|
1319
|
+
if (node.type.name === "commentReference") {
|
|
1320
|
+
flushCurrentInline();
|
|
1321
|
+
currentTrackedChange = void 0;
|
|
1322
|
+
content.push({
|
|
1323
|
+
type: "commentReference",
|
|
1324
|
+
id: expectCommentReferenceAttrs(node).commentId
|
|
1325
|
+
});
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
if (node.type.name === "rangeAnchor") {
|
|
1329
|
+
flushCurrentInline();
|
|
1330
|
+
currentTrackedChange = void 0;
|
|
1331
|
+
const { start, end } = expectRangeAnchorAttrs(node);
|
|
1332
|
+
content.push({ ...start }, { ...end });
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1335
|
+
if (node.type.name === "moveRangeBoundary") {
|
|
1336
|
+
flushCurrentInline();
|
|
1337
|
+
currentTrackedChange = void 0;
|
|
1338
|
+
content.push({ ...expectMoveRangeBoundaryAttrs(node) });
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1121
1341
|
const linkMark = node.marks.find((m) => m.type.name === "hyperlink");
|
|
1122
1342
|
const noteRefMark = node.marks.find((m) => m.type.name === "footnoteRef");
|
|
1123
1343
|
const insertionMark = node.marks.find((m) => m.type.name === "insertion");
|
|
@@ -1210,6 +1430,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1210
1430
|
});
|
|
1211
1431
|
return;
|
|
1212
1432
|
}
|
|
1433
|
+
if (isInlineLevelPreservedXml(node)) {
|
|
1434
|
+
currentTrackedChange.hyperlink.children.push(createPreservedInline(node));
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1213
1437
|
const run = createTrackedChangeRun({
|
|
1214
1438
|
...formattingContext,
|
|
1215
1439
|
marks: otherMarks,
|
|
@@ -1228,20 +1452,7 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1228
1452
|
};
|
|
1229
1453
|
}
|
|
1230
1454
|
if (node.type.name === "bookmarkBoundary") {
|
|
1231
|
-
|
|
1232
|
-
const boundary = attrs.type === "start" ? {
|
|
1233
|
-
type: "bookmarkStart",
|
|
1234
|
-
id: attrs.id,
|
|
1235
|
-
name: attrs.name,
|
|
1236
|
-
...attrs.colFirst !== void 0 ? { colFirst: attrs.colFirst } : {},
|
|
1237
|
-
...attrs.colLast !== void 0 ? { colLast: attrs.colLast } : {},
|
|
1238
|
-
...bookmarkBoundaryDisplacement(attrs)
|
|
1239
|
-
} : {
|
|
1240
|
-
type: "bookmarkEnd",
|
|
1241
|
-
id: attrs.id,
|
|
1242
|
-
...bookmarkBoundaryDisplacement(attrs)
|
|
1243
|
-
};
|
|
1244
|
-
currentTrackedChange.wrapper.content.push(boundary);
|
|
1455
|
+
currentTrackedChange.wrapper.content.push(bookmarkMarkerFromAttrs(expectBookmarkBoundaryAttrs(node)));
|
|
1245
1456
|
return;
|
|
1246
1457
|
}
|
|
1247
1458
|
if (node.type.name === "field" || node.type.name === "structuredField") {
|
|
@@ -1256,6 +1467,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1256
1467
|
currentTrackedChange.wrapper.content.push(createMathFromNode(node));
|
|
1257
1468
|
return;
|
|
1258
1469
|
}
|
|
1470
|
+
if (isInlineLevelPreservedXml(node)) {
|
|
1471
|
+
currentTrackedChange.wrapper.content.push(createPreservedInline(node));
|
|
1472
|
+
return;
|
|
1473
|
+
}
|
|
1259
1474
|
const run = createTrackedChangeRun({
|
|
1260
1475
|
...formattingContext,
|
|
1261
1476
|
marks: otherMarks,
|
|
@@ -1264,7 +1479,7 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1264
1479
|
if (run) appendRunToTrackedWrapper(currentTrackedChange.wrapper, run, node, sourceRunOwners);
|
|
1265
1480
|
return;
|
|
1266
1481
|
}
|
|
1267
|
-
const ownedRun = linkMark ||
|
|
1482
|
+
const ownedRun = linkMark || runIdentityId(node) === void 0 ? null : createTrackedChangeRun({
|
|
1268
1483
|
...formattingContext,
|
|
1269
1484
|
marks: node.marks,
|
|
1270
1485
|
node
|
|
@@ -1296,20 +1511,7 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1296
1511
|
if (currentHyperlink) flushCurrentInline();
|
|
1297
1512
|
if (node.type.name === "bookmarkBoundary") {
|
|
1298
1513
|
flushCurrentInline();
|
|
1299
|
-
|
|
1300
|
-
if (attrs.type === "start") content.push({
|
|
1301
|
-
type: "bookmarkStart",
|
|
1302
|
-
id: attrs.id,
|
|
1303
|
-
name: attrs.name,
|
|
1304
|
-
...attrs.colFirst !== void 0 ? { colFirst: attrs.colFirst } : {},
|
|
1305
|
-
...attrs.colLast !== void 0 ? { colLast: attrs.colLast } : {},
|
|
1306
|
-
...bookmarkBoundaryDisplacement(attrs)
|
|
1307
|
-
});
|
|
1308
|
-
else content.push({
|
|
1309
|
-
type: "bookmarkEnd",
|
|
1310
|
-
id: attrs.id,
|
|
1311
|
-
...bookmarkBoundaryDisplacement(attrs)
|
|
1312
|
-
});
|
|
1514
|
+
content.push(bookmarkMarkerFromAttrs(expectBookmarkBoundaryAttrs(node)));
|
|
1313
1515
|
} else if (node.isText) appendDirectRun(node, createRunFromText({
|
|
1314
1516
|
...formattingContext,
|
|
1315
1517
|
marks: node.marks,
|
|
@@ -1325,6 +1527,9 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1325
1527
|
} else if (node.type.name === "symbol") {
|
|
1326
1528
|
flushCurrentInline();
|
|
1327
1529
|
content.push(createSymbolRun(node, node.marks, formattingContext));
|
|
1530
|
+
} else if (node.type.name === "preservedXml") {
|
|
1531
|
+
flushCurrentInline();
|
|
1532
|
+
content.push(isInlineLevelPreservedXml(node) ? createPreservedInline(node) : createPreservedXmlRun(node, node.marks, formattingContext));
|
|
1328
1533
|
} else if (node.type.name === "hardBreak") {
|
|
1329
1534
|
flushCurrentInline();
|
|
1330
1535
|
content.push(createBreakRun(expectHardBreakAttrs(node), node.marks, formattingContext));
|
|
@@ -1379,11 +1584,11 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1379
1584
|
});
|
|
1380
1585
|
flushEmptyHyperlinksThroughOffset(Number.POSITIVE_INFINITY);
|
|
1381
1586
|
flushCurrentInline();
|
|
1382
|
-
for (const commentId of openedComments) content.push({
|
|
1587
|
+
for (const commentId of byCommentId(openedComments)) content.push({
|
|
1383
1588
|
type: "commentRangeEnd",
|
|
1384
1589
|
id: commentId
|
|
1385
1590
|
});
|
|
1386
|
-
return content;
|
|
1591
|
+
return nestInlineWrapperGroups(content, wrapperGroups);
|
|
1387
1592
|
}
|
|
1388
1593
|
function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting, marks, node, paragraphMarkFormatting, paragraphMarkPrecedesStyle, styleResolver }) {
|
|
1389
1594
|
const formattingContext = {
|
|
@@ -1406,8 +1611,9 @@ function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting,
|
|
|
1406
1611
|
}] : [],
|
|
1407
1612
|
...Object.keys(formatting).length > 0 ? { formatting } : {}
|
|
1408
1613
|
};
|
|
1409
|
-
|
|
1614
|
+
restoreRunRecord(run, marks);
|
|
1410
1615
|
} else if (node.type.name === "symbol") run = createSymbolRun(node, marks, formattingContext);
|
|
1616
|
+
else if (node.type.name === "preservedXml") run = createPreservedXmlRun(node, marks, formattingContext);
|
|
1411
1617
|
else if (node.type.name === "hardBreak") run = createBreakRun(expectHardBreakAttrs(node), marks, formattingContext);
|
|
1412
1618
|
else if (node.type.name === "pageBreakRun") {
|
|
1413
1619
|
const { clear } = expectPageBreakRunAttrs(node);
|
|
@@ -1420,11 +1626,11 @@ function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting,
|
|
|
1420
1626
|
else if (node.type.name === "shape") run = createShapeRun(node);
|
|
1421
1627
|
else if (node.type.name === "tab") run = createTabRun(node, marks, formattingContext);
|
|
1422
1628
|
else if (node.type.name === "renderedPageBreak") run = createRenderedPageBreakRun();
|
|
1423
|
-
if (!run ||
|
|
1629
|
+
if (!run || runIdentityId(node) === void 0) return run;
|
|
1424
1630
|
if (node.type.name === "image" || node.type.name === "shape" || node.type.name === "renderedPageBreak") {
|
|
1425
1631
|
const formatting = getRunFormattingFromMarks(marks, formattingContext);
|
|
1426
1632
|
if (formatting) run.formatting = formatting;
|
|
1427
|
-
|
|
1633
|
+
restoreRunRecord(run, marks);
|
|
1428
1634
|
}
|
|
1429
1635
|
return run;
|
|
1430
1636
|
}
|
|
@@ -1515,20 +1721,7 @@ function createHyperlink(linkMark) {
|
|
|
1515
1721
|
}
|
|
1516
1722
|
function addNodeToHyperlink({ baseParagraphFormatting, hyperlink, inheritedFormatting, node, paragraphMarkFormatting, paragraphMarkPrecedesStyle, sourceRunOwners, styleResolver }) {
|
|
1517
1723
|
if (node.type.name === "bookmarkBoundary") {
|
|
1518
|
-
|
|
1519
|
-
if (attrs.type === "start") hyperlink.children.push({
|
|
1520
|
-
type: "bookmarkStart",
|
|
1521
|
-
id: attrs.id,
|
|
1522
|
-
name: attrs.name,
|
|
1523
|
-
...attrs.colFirst !== void 0 ? { colFirst: attrs.colFirst } : {},
|
|
1524
|
-
...attrs.colLast !== void 0 ? { colLast: attrs.colLast } : {},
|
|
1525
|
-
...bookmarkBoundaryDisplacement(attrs)
|
|
1526
|
-
});
|
|
1527
|
-
else hyperlink.children.push({
|
|
1528
|
-
type: "bookmarkEnd",
|
|
1529
|
-
id: attrs.id,
|
|
1530
|
-
...bookmarkBoundaryDisplacement(attrs)
|
|
1531
|
-
});
|
|
1724
|
+
hyperlink.children.push(bookmarkMarkerFromAttrs(expectBookmarkBoundaryAttrs(node)));
|
|
1532
1725
|
return;
|
|
1533
1726
|
}
|
|
1534
1727
|
const formattingContext = {
|
|
@@ -1539,7 +1732,7 @@ function addNodeToHyperlink({ baseParagraphFormatting, hyperlink, inheritedForma
|
|
|
1539
1732
|
styleResolver
|
|
1540
1733
|
};
|
|
1541
1734
|
const nonLinkMarks = node.marks.filter((mark) => mark.type.name !== "hyperlink");
|
|
1542
|
-
const ownedRun =
|
|
1735
|
+
const ownedRun = runIdentityId(node) === void 0 ? null : createTrackedChangeRun({
|
|
1543
1736
|
...formattingContext,
|
|
1544
1737
|
marks: nonLinkMarks,
|
|
1545
1738
|
node
|
|
@@ -1582,6 +1775,16 @@ function addNodeToHyperlink({ baseParagraphFormatting, hyperlink, inheritedForma
|
|
|
1582
1775
|
}));
|
|
1583
1776
|
return;
|
|
1584
1777
|
}
|
|
1778
|
+
if (node.type.name === "preservedXml") {
|
|
1779
|
+
hyperlink.children.push(isInlineLevelPreservedXml(node) ? createPreservedInline(node) : createPreservedXmlRun(node, nonLinkMarks, {
|
|
1780
|
+
baseParagraphFormatting,
|
|
1781
|
+
inheritedFormatting,
|
|
1782
|
+
paragraphMarkFormatting,
|
|
1783
|
+
paragraphMarkPrecedesStyle,
|
|
1784
|
+
styleResolver
|
|
1785
|
+
}));
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1585
1788
|
if (node.type.name === "hardBreak") {
|
|
1586
1789
|
hyperlink.children.push(createBreakRun(expectHardBreakAttrs(node), nonLinkMarks, {
|
|
1587
1790
|
baseParagraphFormatting,
|
|
@@ -1642,7 +1845,7 @@ function createNoteReferenceRun(noteRefMark, marks, formattingContext) {
|
|
|
1642
1845
|
...formatting,
|
|
1643
1846
|
vertAlign
|
|
1644
1847
|
};
|
|
1645
|
-
|
|
1848
|
+
restoreRunRecord(run, marks);
|
|
1646
1849
|
return run;
|
|
1647
1850
|
}
|
|
1648
1851
|
function createRunFromText({ baseParagraphFormatting, inheritedFormatting, marks, paragraphMarkFormatting, paragraphMarkPrecedesStyle, styleResolver, text }) {
|
|
@@ -1661,7 +1864,7 @@ function createRunFromText({ baseParagraphFormatting, inheritedFormatting, marks
|
|
|
1661
1864
|
}]
|
|
1662
1865
|
};
|
|
1663
1866
|
if (formatting) run.formatting = formatting;
|
|
1664
|
-
|
|
1867
|
+
restoreRunRecord(run, marks);
|
|
1665
1868
|
return run;
|
|
1666
1869
|
}
|
|
1667
1870
|
function createSymbolRun(node, marks, formattingContext) {
|
|
@@ -1676,15 +1879,77 @@ function createSymbolRun(node, marks, formattingContext) {
|
|
|
1676
1879
|
};
|
|
1677
1880
|
const formatting = getAtomRunFormattingFromMarks(marks, formattingContext);
|
|
1678
1881
|
if (formatting) run.formatting = formatting;
|
|
1679
|
-
|
|
1882
|
+
restoreRunRecord(run, marks);
|
|
1680
1883
|
return run;
|
|
1681
1884
|
}
|
|
1682
|
-
|
|
1885
|
+
/**
|
|
1886
|
+
* Whether the atom's markup is a paragraph child rather than a run child.
|
|
1887
|
+
*
|
|
1888
|
+
* The two are the same node in the editor and different elements in the file:
|
|
1889
|
+
* `w:ruby` has to go back inside a `w:r` and `w:permStart` may not, because
|
|
1890
|
+
* the schema admits no such child of a run and Word reports the package as
|
|
1891
|
+
* unreadable content.
|
|
1892
|
+
*/
|
|
1893
|
+
const isInlineLevelPreservedXml = (node) => node.type.name === "preservedXml" && expectPreservedXmlAttrs(node).level === PRESERVED_XML_LEVELS.inline;
|
|
1894
|
+
/** The paragraph-level capture an inline-level atom writes back. */
|
|
1895
|
+
const createPreservedInline = (node) => {
|
|
1896
|
+
const { xml, text } = expectPreservedXmlAttrs(node);
|
|
1897
|
+
return {
|
|
1898
|
+
type: "preservedInline",
|
|
1899
|
+
xml,
|
|
1900
|
+
text
|
|
1901
|
+
};
|
|
1902
|
+
};
|
|
1903
|
+
/**
|
|
1904
|
+
* Rebuild the run around a preserved child. The markup is opaque and comes
|
|
1905
|
+
* back byte for byte; only the run properties around it are rebuilt from the
|
|
1906
|
+
* atom's marks, exactly as for a symbol.
|
|
1907
|
+
*/
|
|
1908
|
+
function createPreservedXmlRun(node, marks, formattingContext) {
|
|
1909
|
+
const { xml, text } = expectPreservedXmlAttrs(node);
|
|
1910
|
+
const run = {
|
|
1911
|
+
type: "run",
|
|
1912
|
+
content: [{
|
|
1913
|
+
type: "preservedXml",
|
|
1914
|
+
xml,
|
|
1915
|
+
text
|
|
1916
|
+
}]
|
|
1917
|
+
};
|
|
1918
|
+
const formatting = getAtomRunFormattingFromMarks(marks, formattingContext);
|
|
1919
|
+
if (formatting) run.formatting = formatting;
|
|
1920
|
+
restoreRunRecord(run, marks);
|
|
1921
|
+
return run;
|
|
1922
|
+
}
|
|
1923
|
+
/**
|
|
1924
|
+
* Put back everything about the authored `w:r` that the marks still carry:
|
|
1925
|
+
* its property revision, its attribute remainder and its `w:rPr` sink.
|
|
1926
|
+
*
|
|
1927
|
+
* One helper for the three, called at every site that builds a run, because a
|
|
1928
|
+
* site that restored two of them would write a `w:r` that has lost the third
|
|
1929
|
+
* without anything saying so. A leaf with no identity mark produces a run with
|
|
1930
|
+
* neither remainder nor sink, which is what typed text is.
|
|
1931
|
+
*/
|
|
1932
|
+
function restoreRunRecord(run, marks) {
|
|
1683
1933
|
const changeMark = marks.find((mark) => mark.type.name === "runPropertyChange");
|
|
1684
|
-
if (
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1934
|
+
if (changeMark) {
|
|
1935
|
+
const { changes } = expectRunPropertyChangeMarkAttrs(changeMark);
|
|
1936
|
+
if (changes.length > 0) run.propertyChanges = [...changes];
|
|
1937
|
+
}
|
|
1938
|
+
const identityMark = marks.find((mark) => mark.type.name === RUN_IDENTITY_MARK_NAME);
|
|
1939
|
+
if (!identityMark) return;
|
|
1940
|
+
const { preservedAttributes, preserved } = expectRunIdentityMarkAttrs(identityMark);
|
|
1941
|
+
if (preservedAttributes && preservedAttributes.length > 0) run.preservedAttributes = preservedAttributes.map(({ namespace, name, value }) => namespace === void 0 ? {
|
|
1942
|
+
name,
|
|
1943
|
+
value
|
|
1944
|
+
} : {
|
|
1945
|
+
namespace,
|
|
1946
|
+
name,
|
|
1947
|
+
value
|
|
1948
|
+
});
|
|
1949
|
+
if (preserved && (preserved.children?.length ?? 0) > 0) run.formatting = {
|
|
1950
|
+
...run.formatting,
|
|
1951
|
+
preserved
|
|
1952
|
+
};
|
|
1688
1953
|
}
|
|
1689
1954
|
function getRunFormattingFromMarks(marks, options) {
|
|
1690
1955
|
if (!marks || marks.length === 0 && !options) return;
|
|
@@ -1715,17 +1980,25 @@ function runsShareProperties(left, right) {
|
|
|
1715
1980
|
propertyChanges: right.propertyChanges
|
|
1716
1981
|
});
|
|
1717
1982
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1983
|
+
/**
|
|
1984
|
+
* The authored `w:r` this leaf came from, when it names one.
|
|
1985
|
+
*
|
|
1986
|
+
* Two leaves that share an id are two pieces of one authored run — the cut a
|
|
1987
|
+
* page-break atom makes — and the save leg rejoins them. Two leaves with
|
|
1988
|
+
* different ids are two runs however alike their formatting, which is what
|
|
1989
|
+
* keeps both sides' `w:rsid*` alive across a paragraph the editor rebuilt.
|
|
1990
|
+
*/
|
|
1991
|
+
function runIdentityId(node) {
|
|
1992
|
+
const mark = node.marks.find(({ type }) => type.name === RUN_IDENTITY_MARK_NAME);
|
|
1993
|
+
return mark ? expectRunIdentityMarkAttrs(mark).id : void 0;
|
|
1721
1994
|
}
|
|
1722
1995
|
function canJoinOwnedRuns(previous, run, node, sourceRunOwners) {
|
|
1723
1996
|
if (!previous || !runsShareProperties(previous, run)) return false;
|
|
1724
|
-
const ownerId =
|
|
1997
|
+
const ownerId = runIdentityId(node);
|
|
1725
1998
|
return ownerId !== void 0 && sourceRunOwners.get(previous) === ownerId;
|
|
1726
1999
|
}
|
|
1727
2000
|
function rememberSourceRunOwner(run, node, sourceRunOwners) {
|
|
1728
|
-
const ownerId =
|
|
2001
|
+
const ownerId = runIdentityId(node);
|
|
1729
2002
|
if (ownerId !== void 0) sourceRunOwners.set(run, ownerId);
|
|
1730
2003
|
}
|
|
1731
2004
|
function appendRunToTrackedWrapper(wrapper, run, node, sourceRunOwners) {
|
|
@@ -1763,7 +2036,7 @@ function createPageBreakCarrierRun({ baseParagraphFormatting, clear, inheritedFo
|
|
|
1763
2036
|
styleResolver
|
|
1764
2037
|
});
|
|
1765
2038
|
if (formatting) run.formatting = formatting;
|
|
1766
|
-
if (marks)
|
|
2039
|
+
if (marks) restoreRunRecord(run, marks);
|
|
1767
2040
|
return run;
|
|
1768
2041
|
}
|
|
1769
2042
|
/**
|
|
@@ -1780,7 +2053,7 @@ function createBreakRun(attrs, marks, formattingContext) {
|
|
|
1780
2053
|
};
|
|
1781
2054
|
const formatting = getAtomRunFormattingFromMarks(marks, formattingContext);
|
|
1782
2055
|
if (formatting) run.formatting = formatting;
|
|
1783
|
-
if (marks)
|
|
2056
|
+
if (marks) restoreRunRecord(run, marks);
|
|
1784
2057
|
return run;
|
|
1785
2058
|
}
|
|
1786
2059
|
function createRenderedPageBreakRun() {
|
|
@@ -1803,7 +2076,7 @@ function createTabRun(node, marks, formattingContext) {
|
|
|
1803
2076
|
};
|
|
1804
2077
|
const formatting = getAtomRunFormattingFromMarks(marks, formattingContext);
|
|
1805
2078
|
if (formatting) run.formatting = formatting;
|
|
1806
|
-
if (marks)
|
|
2079
|
+
if (marks) restoreRunRecord(run, marks);
|
|
1807
2080
|
return run;
|
|
1808
2081
|
}
|
|
1809
2082
|
function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormatting, marks, paragraphMarkFormatting, paragraphMarkPrecedesStyle, styleResolver, textBoxAnchorMarkers }) {
|
|
@@ -1821,7 +2094,7 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1821
2094
|
paragraphMarkFormatting,
|
|
1822
2095
|
paragraphMarkPrecedesStyle: paragraphMarkPrecedesStyle ?? false,
|
|
1823
2096
|
styleResolver: styleResolver ?? null
|
|
1824
|
-
}).filter(
|
|
2097
|
+
}).filter(isSimpleFieldContent);
|
|
1825
2098
|
const displayText = attrs.displayText ?? "";
|
|
1826
2099
|
const displayRun = {
|
|
1827
2100
|
type: "run",
|
|
@@ -1831,7 +2104,7 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1831
2104
|
}],
|
|
1832
2105
|
...formatting && Object.keys(formatting).length > 0 ? { formatting } : {}
|
|
1833
2106
|
};
|
|
1834
|
-
if (marks && node.type.name === "field")
|
|
2107
|
+
if (marks && node.type.name === "field") restoreRunRecord(displayRun, marks);
|
|
1835
2108
|
const fieldContent = extractedContent.length > 0 ? synchronizeFieldDisplayText(extractedContent, displayText, displayRun) : [];
|
|
1836
2109
|
const fallbackFieldContent = displayText ? [displayRun] : [];
|
|
1837
2110
|
if (attrs.fieldKind === "complex") {
|
|
@@ -1842,8 +2115,8 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1842
2115
|
fieldCode: [],
|
|
1843
2116
|
fieldResult: fieldContent.length > 0 ? fieldContent.filter((content) => content.type === "run") : fallbackFieldContent
|
|
1844
2117
|
};
|
|
1845
|
-
if (attrs.fldLock) complex.fldLock =
|
|
1846
|
-
if (attrs.dirty) complex.dirty =
|
|
2118
|
+
if (attrs.fldLock !== void 0) complex.fldLock = attrs.fldLock;
|
|
2119
|
+
if (attrs.dirty !== void 0) complex.dirty = attrs.dirty;
|
|
1847
2120
|
return complex;
|
|
1848
2121
|
}
|
|
1849
2122
|
const simple = {
|
|
@@ -1852,21 +2125,24 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1852
2125
|
fieldType: attrs.fieldType,
|
|
1853
2126
|
content: fieldContent.length > 0 ? fieldContent : fallbackFieldContent
|
|
1854
2127
|
};
|
|
1855
|
-
if (attrs.fldLock) simple.fldLock =
|
|
1856
|
-
if (attrs.dirty) simple.dirty =
|
|
2128
|
+
if (attrs.fldLock !== void 0) simple.fldLock = attrs.fldLock;
|
|
2129
|
+
if (attrs.dirty !== void 0) simple.dirty = attrs.dirty;
|
|
1857
2130
|
return simple;
|
|
1858
2131
|
}
|
|
1859
2132
|
const synchronizeFieldDisplayText = (content, displayText, fallbackRun) => {
|
|
1860
2133
|
let currentText = "";
|
|
1861
|
-
const
|
|
1862
|
-
for (const child of
|
|
2134
|
+
const visitRunsIn = (items, visit) => {
|
|
2135
|
+
for (const child of items) {
|
|
1863
2136
|
if (child.type === "run") {
|
|
1864
2137
|
visit(child);
|
|
1865
2138
|
continue;
|
|
1866
2139
|
}
|
|
1867
|
-
|
|
2140
|
+
if (child.type === "hyperlink" || child.type === "inlineWrapper") visitRunsIn(child.type === "hyperlink" ? child.children : child.content, visit);
|
|
1868
2141
|
}
|
|
1869
2142
|
};
|
|
2143
|
+
const visitRuns = (visit) => {
|
|
2144
|
+
visitRunsIn(content, visit);
|
|
2145
|
+
};
|
|
1870
2146
|
visitRuns((run) => {
|
|
1871
2147
|
for (const runContent of run.content) if (runContent.type === "text") currentText += runContent.text;
|
|
1872
2148
|
});
|
|
@@ -1903,14 +2179,42 @@ function createMathFromNode(node) {
|
|
|
1903
2179
|
return math;
|
|
1904
2180
|
}
|
|
1905
2181
|
/**
|
|
2182
|
+
* A revision covering every child of a control, written around the control.
|
|
2183
|
+
*
|
|
2184
|
+
* `w:ins > w:sdt` and `w:sdt > w:ins` reach the editor as the same revision
|
|
2185
|
+
* mark on the same leaves, so the save leg has to pick one and writes the
|
|
2186
|
+
* canonical order: the revision outermost, as it already is around a hyperlink
|
|
2187
|
+
* and around a transparent wrapper. Outermost is also the only form in which
|
|
2188
|
+
* accepting or rejecting the change is an operation over the whole control —
|
|
2189
|
+
* the reader who inserted a bound field inserted the field, not its text.
|
|
2190
|
+
*
|
|
2191
|
+
* A revision that covers only part of the content has no such form and stays
|
|
2192
|
+
* where the editor holds it, per child.
|
|
2193
|
+
*/
|
|
2194
|
+
const hoistUniformRevision = (sdt) => {
|
|
2195
|
+
const only = sdt.content.length === 1 ? sdt.content.at(0) : void 0;
|
|
2196
|
+
if (only === void 0 || !isRevisionWrapper(only)) return sdt;
|
|
2197
|
+
const admitted = only.content.filter(isInlineSdtContent);
|
|
2198
|
+
if (admitted.length !== only.content.length) return sdt;
|
|
2199
|
+
return {
|
|
2200
|
+
...only,
|
|
2201
|
+
content: [{
|
|
2202
|
+
...sdt,
|
|
2203
|
+
content: admitted
|
|
2204
|
+
}]
|
|
2205
|
+
};
|
|
2206
|
+
};
|
|
2207
|
+
/**
|
|
1906
2208
|
* Create an InlineSdt from a PM sdt node
|
|
1907
2209
|
*/
|
|
1908
2210
|
function createInlineSdtFromNode(node, textBoxAnchorMarkers, formattingContext) {
|
|
1909
|
-
|
|
2211
|
+
const properties = sdtPropertiesFromAttrs(expectSdtAttrs(node));
|
|
2212
|
+
const content = extractParagraphContent(node, void 0, void 0, textBoxAnchorMarkers, false, formattingContext).filter(isInlineSdtContent);
|
|
2213
|
+
return hoistUniformRevision({
|
|
1910
2214
|
type: "inlineSdt",
|
|
1911
|
-
properties
|
|
1912
|
-
content
|
|
1913
|
-
};
|
|
2215
|
+
properties,
|
|
2216
|
+
content
|
|
2217
|
+
});
|
|
1914
2218
|
}
|
|
1915
2219
|
/**
|
|
1916
2220
|
* Create a Run containing an image
|
|
@@ -1923,15 +2227,24 @@ function createInlineSdtFromNode(node, textBoxAnchorMarkers, formattingContext)
|
|
|
1923
2227
|
* around one has no other record of the properties it was authored with.
|
|
1924
2228
|
*/
|
|
1925
2229
|
const carriedRunFormatting = (formatting) => formatting && Object.keys(formatting).length > 0 ? { formatting } : {};
|
|
2230
|
+
/**
|
|
2231
|
+
* The anchor record off a node's attrs, copied so the model never aliases a
|
|
2232
|
+
* ProseMirror attribute object.
|
|
2233
|
+
*/
|
|
2234
|
+
const restoredDrawingAnchor = (anchor) => anchor === void 0 ? void 0 : {
|
|
2235
|
+
...anchor,
|
|
2236
|
+
...anchor.simplePosition === void 0 ? {} : { simplePosition: { ...anchor.simplePosition } }
|
|
2237
|
+
};
|
|
1926
2238
|
function createImageRun(node) {
|
|
1927
2239
|
const attrs = expectImageAttrs(node);
|
|
1928
2240
|
const wrap = { type: attrs.wrapType || "inline" };
|
|
1929
2241
|
assignWrapDistances(wrap, attrs);
|
|
1930
2242
|
if (attrs.wrapText) wrap.wrapText = attrs.wrapText;
|
|
1931
2243
|
const authoredEmu = attrs._docxAuthoredEmu;
|
|
2244
|
+
const rId = relationshipIdOf(attrs.rId);
|
|
1932
2245
|
const image = {
|
|
1933
2246
|
type: "image",
|
|
1934
|
-
rId:
|
|
2247
|
+
...rId === void 0 ? {} : { rId },
|
|
1935
2248
|
src: attrs.src,
|
|
1936
2249
|
size: {
|
|
1937
2250
|
width: emuFromPixels(attrs.width || 0, "width", authoredEmu, emuToPixels),
|
|
@@ -1942,12 +2255,17 @@ function createImageRun(node) {
|
|
|
1942
2255
|
if (attrs.docPrName != null) image.docPrName = attrs.docPrName;
|
|
1943
2256
|
if (attrs.alt != null) image.alt = attrs.alt;
|
|
1944
2257
|
if (attrs.title != null) image.title = attrs.title;
|
|
1945
|
-
const imageTransform =
|
|
2258
|
+
const imageTransform = readAuthoredTransform(attrs);
|
|
1946
2259
|
if (imageTransform) image.transform = imageTransform;
|
|
1947
2260
|
if (attrs.opacity != null) image.opacity = attrs.opacity;
|
|
2261
|
+
if (attrs.brightness != null || attrs.contrast != null) image.effects = {
|
|
2262
|
+
...attrs.brightness == null ? {} : { brightness: attrs.brightness },
|
|
2263
|
+
...attrs.contrast == null ? {} : { contrast: attrs.contrast }
|
|
2264
|
+
};
|
|
1948
2265
|
const imagePosition = imagePositionFromAttrs(attrs.position);
|
|
1949
2266
|
if (imagePosition) image.position = imagePosition;
|
|
1950
|
-
|
|
2267
|
+
const imageAnchor = restoredDrawingAnchor(attrs.anchor);
|
|
2268
|
+
if (imageAnchor) image.anchor = imageAnchor;
|
|
1951
2269
|
if (attrs.decorative !== void 0) image.decorative = attrs.decorative;
|
|
1952
2270
|
if (attrs.hidden !== void 0) image.hidden = attrs.hidden;
|
|
1953
2271
|
if (attrs.docPrExtensions !== void 0) image.docPrExtensions = [...attrs.docPrExtensions];
|
|
@@ -1955,21 +2273,15 @@ function createImageRun(node) {
|
|
|
1955
2273
|
if (attrs.borderWidth && attrs.borderWidth > 0) {
|
|
1956
2274
|
const outline = {
|
|
1957
2275
|
width: emuFromPixels(attrs.borderWidth, "borderWidth", authoredEmu, emuToStrokePixels),
|
|
1958
|
-
|
|
1959
|
-
solid: "solid",
|
|
1960
|
-
dotted: "dot",
|
|
1961
|
-
dashed: "dash",
|
|
1962
|
-
double: "solid",
|
|
1963
|
-
groove: "solid",
|
|
1964
|
-
ridge: "solid",
|
|
1965
|
-
inset: "solid",
|
|
1966
|
-
outset: "solid"
|
|
1967
|
-
}[attrs.borderStyle] || "solid" : "solid"
|
|
2276
|
+
dash: presetDashForCssBorderStyle(attrs.borderStyle)
|
|
1968
2277
|
};
|
|
1969
2278
|
if (attrs.borderColor) outline.color = { rgb: attrs.borderColor.replace("#", "") };
|
|
1970
2279
|
image.outline = outline;
|
|
1971
2280
|
}
|
|
1972
2281
|
if (attrs.hlinkHref) image.hlinkHref = attrs.hlinkHref;
|
|
2282
|
+
if (attrs.docPrId !== void 0) image.id = attrs.docPrId;
|
|
2283
|
+
if (attrs.hlinkClickSource !== void 0) image.hlinkClickSource = { ...attrs.hlinkClickSource };
|
|
2284
|
+
if (attrs.hlinkHoverXml !== void 0) image.hlinkHoverXml = attrs.hlinkHoverXml;
|
|
1973
2285
|
if (attrs.hlinkRId) image.hlinkRId = attrs.hlinkRId;
|
|
1974
2286
|
const cropTop = attrs.cropTop != null && attrs.cropTop > 0 ? attrs.cropTop : void 0;
|
|
1975
2287
|
const cropRight = attrs.cropRight != null && attrs.cropRight > 0 ? attrs.cropRight : void 0;
|
|
@@ -1992,11 +2304,13 @@ function createImageRun(node) {
|
|
|
1992
2304
|
if (paddingLeft !== void 0) padding.left = paddingLeft;
|
|
1993
2305
|
image.padding = padding;
|
|
1994
2306
|
}
|
|
1995
|
-
|
|
2307
|
+
const run = {
|
|
1996
2308
|
type: "run",
|
|
1997
2309
|
...carriedRunFormatting(attrs._docxRunFormatting),
|
|
1998
2310
|
content: [drawingFromImageAttrs(image, attrs)]
|
|
1999
2311
|
};
|
|
2312
|
+
restoreRunRecord(run, node.marks);
|
|
2313
|
+
return run;
|
|
2000
2314
|
}
|
|
2001
2315
|
/**
|
|
2002
2316
|
* Rebuild the `DrawingContent` union member the image node came from.
|
|
@@ -2049,7 +2363,7 @@ function createShapeRun(node) {
|
|
|
2049
2363
|
if (attrs.title !== void 0) shape.title = attrs.title;
|
|
2050
2364
|
const geometryAdjustments = parseShapeGeometryAdjustments(attrs.geometryAdjustments);
|
|
2051
2365
|
if (geometryAdjustments !== void 0) shape.geometryAdjustments = geometryAdjustments;
|
|
2052
|
-
const shapeTransform =
|
|
2366
|
+
const shapeTransform = readAuthoredTransform(attrs);
|
|
2053
2367
|
if (shapeTransform) shape.transform = shapeTransform;
|
|
2054
2368
|
const wrap = { type: attrs.wrapType || "inline" };
|
|
2055
2369
|
assignWrapDistances(wrap, attrs);
|
|
@@ -2057,6 +2371,8 @@ function createShapeRun(node) {
|
|
|
2057
2371
|
shape.wrap = wrap;
|
|
2058
2372
|
const shapePosition = imagePositionFromAttrs(attrs.position);
|
|
2059
2373
|
if (shapePosition) shape.position = shapePosition;
|
|
2374
|
+
const shapeAnchor = restoredDrawingAnchor(attrs.anchor);
|
|
2375
|
+
if (shapeAnchor) shape.anchor = shapeAnchor;
|
|
2060
2376
|
if (attrs.fillType === "gradient" && attrs.gradientStops) try {
|
|
2061
2377
|
const parsed = JSON.parse(attrs.gradientStops);
|
|
2062
2378
|
const gradient = {
|
|
@@ -2086,8 +2402,8 @@ function createShapeRun(node) {
|
|
|
2086
2402
|
const shapeOutline = {};
|
|
2087
2403
|
if (attrs.outlineWidth !== void 0 && attrs.outlineWidth > 0) shapeOutline.width = emuFromPixels(attrs.outlineWidth, "outlineWidth", authoredEmu, emuToStrokePixels);
|
|
2088
2404
|
if (attrs.outlineStyle) {
|
|
2089
|
-
const
|
|
2090
|
-
if (
|
|
2405
|
+
const dash = normalizeShapeOutlineDash(attrs.outlineStyle);
|
|
2406
|
+
if (dash !== void 0) shapeOutline.dash = dash;
|
|
2091
2407
|
}
|
|
2092
2408
|
if (attrs.outlineCap) shapeOutline.cap = attrs.outlineCap;
|
|
2093
2409
|
if (attrs.outlineJoin) shapeOutline.join = attrs.outlineJoin;
|
|
@@ -2100,11 +2416,13 @@ function createShapeRun(node) {
|
|
|
2100
2416
|
type: "shape",
|
|
2101
2417
|
shape
|
|
2102
2418
|
};
|
|
2103
|
-
|
|
2419
|
+
const run = {
|
|
2104
2420
|
type: "run",
|
|
2105
2421
|
...carriedRunFormatting(attrs._docxRunFormatting),
|
|
2106
2422
|
content: [shapeContent]
|
|
2107
2423
|
};
|
|
2424
|
+
restoreRunRecord(run, node.marks);
|
|
2425
|
+
return run;
|
|
2108
2426
|
}
|
|
2109
2427
|
const RUN_FORMATTING_VISUAL_GROUPS = {
|
|
2110
2428
|
bold: "bold",
|
|
@@ -2138,7 +2456,8 @@ const RUN_FORMATTING_VISUAL_GROUPS = {
|
|
|
2138
2456
|
shadow: "shadow",
|
|
2139
2457
|
rtl: "rtl",
|
|
2140
2458
|
cs: null,
|
|
2141
|
-
styleId: null
|
|
2459
|
+
styleId: null,
|
|
2460
|
+
preserved: null
|
|
2142
2461
|
};
|
|
2143
2462
|
const RUN_FORMATTING_FAST_PATH_DISPOSITION = {
|
|
2144
2463
|
bold: "visual",
|
|
@@ -2172,7 +2491,8 @@ const RUN_FORMATTING_FAST_PATH_DISPOSITION = {
|
|
|
2172
2491
|
shadow: "visual",
|
|
2173
2492
|
rtl: "visual",
|
|
2174
2493
|
cs: "structural",
|
|
2175
|
-
styleId: "character-style"
|
|
2494
|
+
styleId: "character-style",
|
|
2495
|
+
preserved: "structural"
|
|
2176
2496
|
};
|
|
2177
2497
|
const hasOnlyCarrierlessVisualFormatting = (formatting) => {
|
|
2178
2498
|
for (const property of Object.keys(formatting)) if (RUN_FORMATTING_FAST_PATH_DISPOSITION[property] !== "visual") return false;
|
|
@@ -2706,7 +3026,7 @@ function convertPMTable(node, documentCounts, styleResolver = null) {
|
|
|
2706
3026
|
rows
|
|
2707
3027
|
};
|
|
2708
3028
|
if (attrs.columnWidths) minTable.columnWidths = attrs.columnWidths;
|
|
2709
|
-
|
|
3029
|
+
restoreCarriedTableAttrs(minTable, attrs);
|
|
2710
3030
|
return minTable;
|
|
2711
3031
|
}
|
|
2712
3032
|
}
|
|
@@ -2716,16 +3036,22 @@ function convertPMTable(node, documentCounts, styleResolver = null) {
|
|
|
2716
3036
|
};
|
|
2717
3037
|
if (attrs.columnWidths) table.columnWidths = attrs.columnWidths;
|
|
2718
3038
|
if (formatting && Object.keys(formatting).length > 0) table.formatting = formatting;
|
|
2719
|
-
|
|
3039
|
+
restoreCarriedTableAttrs(table, attrs);
|
|
2720
3040
|
return table;
|
|
2721
3041
|
}
|
|
2722
3042
|
/**
|
|
2723
|
-
* Restore
|
|
2724
|
-
*
|
|
2725
|
-
*
|
|
3043
|
+
* Restore what PM carried opaquely on the table attrs, on both paths out of
|
|
3044
|
+
* {@link convertPMTable}.
|
|
3045
|
+
*
|
|
3046
|
+
* `w:tblPrChange` (same rationale as the paragraph `_propertyChanges` attr)
|
|
3047
|
+
* must survive an edit so the saved DOCX keeps the tracked property-change
|
|
3048
|
+
* history, and the child sink must survive it so the markup the table held
|
|
3049
|
+
* beside its rows comes back between the same two.
|
|
2726
3050
|
*/
|
|
2727
|
-
function
|
|
3051
|
+
function restoreCarriedTableAttrs(table, attrs) {
|
|
2728
3052
|
if (Array.isArray(attrs.tblPrChange) && attrs.tblPrChange.length > 0) table.propertyChanges = [...attrs.tblPrChange];
|
|
3053
|
+
if (attrs._bookmarks && attrs._bookmarks.length > 0) table.bookmarks = attrs._bookmarks;
|
|
3054
|
+
if (hasSinkChildren(attrs._preserved)) table.preserved = attrs._preserved;
|
|
2729
3055
|
}
|
|
2730
3056
|
function convertPMTableRows(node, documentCounts, styleResolver = null) {
|
|
2731
3057
|
const rows = [];
|
|
@@ -2836,10 +3162,15 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges, styleReso
|
|
|
2836
3162
|
}
|
|
2837
3163
|
};
|
|
2838
3164
|
node.forEach((cellNode) => {
|
|
2839
|
-
appendActiveVerticalMerges();
|
|
2840
3165
|
if (cellNode.type.name === "tableCell" || cellNode.type.name === "tableHeader") {
|
|
2841
3166
|
const cellAttrs = expectTableCellAttrs(cellNode);
|
|
2842
3167
|
const colspan = Math.max(cellAttrs.colspan, 1);
|
|
3168
|
+
if (cellAttrs._omittedGridSlot) {
|
|
3169
|
+
if (!(cellNode.childCount === 1 && cellNode.child(0).type.name === "paragraph" && cellNode.child(0).content.size === 0)) panic("An omitted table grid slot acquired authored content");
|
|
3170
|
+
gridColumn += colspan;
|
|
3171
|
+
return;
|
|
3172
|
+
}
|
|
3173
|
+
appendActiveVerticalMerges();
|
|
2843
3174
|
cells.push(convertPMTableCell(cellNode, documentCounts, styleResolver));
|
|
2844
3175
|
if (cellAttrs.rowspan > 1) {
|
|
2845
3176
|
const continuationCells = cellAttrs._docxVMergeContinuationCells !== void 0 && cellAttrs._docxVMergeContinuationCells !== null ? restoreTableCellsWithParagraphPropertySources(decodeTableCellParagraphSourcePayload(cellAttrs._docxVMergeContinuationCells)) : void 0;
|
|
@@ -2859,7 +3190,13 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges, styleReso
|
|
|
2859
3190
|
};
|
|
2860
3191
|
const rowFormatting = tableRowAttrsToFormatting(attrs);
|
|
2861
3192
|
if (rowFormatting) row.formatting = rowFormatting;
|
|
3193
|
+
if (attrs._tablePropertyExceptions) row.tablePropertyExceptions = attrs._tablePropertyExceptions;
|
|
3194
|
+
if (Array.isArray(attrs.tblPrExChange) && attrs.tblPrExChange.length > 0) row.tablePropertyExceptionChanges = [...attrs.tblPrExChange];
|
|
2862
3195
|
if (Array.isArray(attrs.trPrChange) && attrs.trPrChange.length > 0) row.propertyChanges = [...attrs.trPrChange];
|
|
3196
|
+
if (attrs._preservedAttributes && attrs._preservedAttributes.length > 0) row.preservedAttributes = attrs._preservedAttributes;
|
|
3197
|
+
if (attrs._bookmarks && attrs._bookmarks.length > 0) row.bookmarks = attrs._bookmarks;
|
|
3198
|
+
if (attrs.contentControls && attrs.contentControls.length > 0) row.contentControls = attrs.contentControls;
|
|
3199
|
+
if (hasSinkChildren(attrs._preserved)) row.preserved = attrs._preserved;
|
|
2863
3200
|
if (attrs.trIns) row.structuralChange = {
|
|
2864
3201
|
type: "tableRowInsertion",
|
|
2865
3202
|
info: {
|
|
@@ -2916,11 +3253,11 @@ function tableRowAttrsToFormatting(attrs) {
|
|
|
2916
3253
|
else delete result.heightRule;
|
|
2917
3254
|
if (attrs.isHeader !== (orig.header ?? void 0)) if (attrs.isHeader) result.header = attrs.isHeader;
|
|
2918
3255
|
else delete result.header;
|
|
2919
|
-
if (attrs.hidden !==
|
|
2920
|
-
else
|
|
3256
|
+
if (attrs.hidden !== orig.hidden) if (attrs.hidden === void 0) delete result.hidden;
|
|
3257
|
+
else result.hidden = attrs.hidden;
|
|
2921
3258
|
return result;
|
|
2922
3259
|
}
|
|
2923
|
-
if (!(attrs.height || attrs.isHeader || attrs.hidden)) return;
|
|
3260
|
+
if (!(attrs.height || attrs.isHeader || attrs.hidden !== void 0)) return;
|
|
2924
3261
|
const f = {};
|
|
2925
3262
|
if (attrs.height) f.height = {
|
|
2926
3263
|
value: attrs.height,
|
|
@@ -2928,7 +3265,7 @@ function tableRowAttrsToFormatting(attrs) {
|
|
|
2928
3265
|
};
|
|
2929
3266
|
if (attrs.heightRule) f.heightRule = attrs.heightRule;
|
|
2930
3267
|
if (attrs.isHeader) f.header = attrs.isHeader;
|
|
2931
|
-
if (attrs.hidden) f.hidden = attrs.hidden;
|
|
3268
|
+
if (attrs.hidden !== void 0) f.hidden = attrs.hidden;
|
|
2932
3269
|
return f;
|
|
2933
3270
|
}
|
|
2934
3271
|
/**
|
|
@@ -2952,6 +3289,16 @@ function convertPMTableCell(node, documentCounts, styleResolver = null) {
|
|
|
2952
3289
|
textBoxAnchorMarkers,
|
|
2953
3290
|
styleResolver
|
|
2954
3291
|
});
|
|
3292
|
+
else if (contentNode.type.name === "preservedBlock") {
|
|
3293
|
+
content.push({
|
|
3294
|
+
type: "preservedBlock",
|
|
3295
|
+
xml: expectPreservedBlockAttrs(contentNode).xml
|
|
3296
|
+
});
|
|
3297
|
+
previousStandaloneTextBox = null;
|
|
3298
|
+
} else if (contentNode.type.name === "blockBookmarkBoundary") {
|
|
3299
|
+
content.push(blockBookmarkMarker(contentNode));
|
|
3300
|
+
previousStandaloneTextBox = null;
|
|
3301
|
+
}
|
|
2955
3302
|
});
|
|
2956
3303
|
removeUnresolvedTextBoxAnchors(content, textBoxAnchorMarkers);
|
|
2957
3304
|
const cell = {
|
|
@@ -2961,6 +3308,7 @@ function convertPMTableCell(node, documentCounts, styleResolver = null) {
|
|
|
2961
3308
|
const cellFormatting = tableCellAttrsToFormatting(attrs);
|
|
2962
3309
|
if (cellFormatting) cell.formatting = cellFormatting;
|
|
2963
3310
|
if (Array.isArray(attrs.tcPrChange) && attrs.tcPrChange.length > 0) cell.propertyChanges = [...attrs.tcPrChange];
|
|
3311
|
+
if (attrs.contentControls && attrs.contentControls.length > 0) cell.contentControls = attrs.contentControls;
|
|
2964
3312
|
if (attrs.cellMarker) {
|
|
2965
3313
|
const info = {
|
|
2966
3314
|
id: attrs.cellMarker.info.revisionId,
|
|
@@ -2996,11 +3344,8 @@ function tableCellAttrsToFormatting(attrs) {
|
|
|
2996
3344
|
else delete result.gridSpan;
|
|
2997
3345
|
if (attrs.rowspan > 1) result.vMerge = "restart";
|
|
2998
3346
|
else if (result.vMerge === "restart" && !attrs._preserveVMergeRestart) delete result.vMerge;
|
|
2999
|
-
const
|
|
3000
|
-
if (
|
|
3001
|
-
value: cellWidth,
|
|
3002
|
-
type: attrs.widthType ?? "dxa"
|
|
3003
|
-
};
|
|
3347
|
+
const authoredWidth = attrs._authoredWidth;
|
|
3348
|
+
if (authoredWidth) result.width = authoredWidth;
|
|
3004
3349
|
else delete result.width;
|
|
3005
3350
|
if (attrs.verticalAlign !== (orig.verticalAlign ?? void 0)) if (attrs.verticalAlign) result.verticalAlign = attrs.verticalAlign;
|
|
3006
3351
|
else delete result.verticalAlign;
|
|
@@ -3011,15 +3356,12 @@ function tableCellAttrsToFormatting(attrs) {
|
|
|
3011
3356
|
else delete result.textDirection;
|
|
3012
3357
|
return result;
|
|
3013
3358
|
}
|
|
3014
|
-
const
|
|
3015
|
-
if (!(attrs.colspan > 1 || attrs.rowspan > 1 ||
|
|
3359
|
+
const authoredWidth = attrs._authoredWidth;
|
|
3360
|
+
if (!(attrs.colspan > 1 || attrs.rowspan > 1 || authoredWidth !== void 0 || attrs.verticalAlign || backgroundChanged || attrs.borders || attrs.margins || attrs.textDirection)) return;
|
|
3016
3361
|
const f = {};
|
|
3017
3362
|
if (attrs.colspan > 1) f.gridSpan = attrs.colspan;
|
|
3018
3363
|
if (attrs.rowspan > 1) f.vMerge = "restart";
|
|
3019
|
-
if (
|
|
3020
|
-
value: cellWidth,
|
|
3021
|
-
type: attrs.widthType ?? "dxa"
|
|
3022
|
-
};
|
|
3364
|
+
if (authoredWidth) f.width = authoredWidth;
|
|
3023
3365
|
if (attrs.verticalAlign) f.verticalAlign = attrs.verticalAlign;
|
|
3024
3366
|
if (attrs.textDirection) f.textDirection = attrs.textDirection;
|
|
3025
3367
|
if (backgroundChanged) f.shading = cellShadingFromAttrs(attrs);
|
|
@@ -3086,7 +3428,7 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3086
3428
|
if (attrs.textBoxName !== void 0) shape.name = attrs.textBoxName;
|
|
3087
3429
|
if (attrs.alt !== void 0) shape.alt = attrs.alt;
|
|
3088
3430
|
if (attrs.title !== void 0) shape.title = attrs.title;
|
|
3089
|
-
const transform =
|
|
3431
|
+
const transform = readAuthoredTransform(attrs);
|
|
3090
3432
|
if (transform) shape.transform = transform;
|
|
3091
3433
|
if (attrs.fillColor) shape.fill = {
|
|
3092
3434
|
type: "solid",
|
|
@@ -3095,7 +3437,7 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3095
3437
|
if (attrs.outlineStyle !== "none" && attrs.outlineWidth && attrs.outlineWidth > 0) {
|
|
3096
3438
|
const tbOutline = {
|
|
3097
3439
|
width: emuFromPixels(attrs.outlineWidth, "outlineWidth", authoredEmu, emuToStrokePixels),
|
|
3098
|
-
|
|
3440
|
+
dash: normalizeShapeOutlineDash(attrs.outlineStyle) ?? "solid"
|
|
3099
3441
|
};
|
|
3100
3442
|
if (attrs.outlineColor) tbOutline.color = { rgb: attrs.outlineColor.replace("#", "") };
|
|
3101
3443
|
shape.outline = tbOutline;
|
|
@@ -3104,6 +3446,8 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3104
3446
|
if (wrap) shape.wrap = wrap;
|
|
3105
3447
|
const position = imagePositionFromAttrs(attrs.position);
|
|
3106
3448
|
if (position) shape.position = position;
|
|
3449
|
+
const anchor = restoredDrawingAnchor(attrs.anchor);
|
|
3450
|
+
if (anchor) shape.anchor = anchor;
|
|
3107
3451
|
const run = {
|
|
3108
3452
|
type: "run",
|
|
3109
3453
|
content: [{
|
|
@@ -3156,8 +3500,10 @@ function updateDocumentContent(originalDocument, pmDoc) {
|
|
|
3156
3500
|
* Used for converting edited header/footer PM content back to the document
|
|
3157
3501
|
* model.
|
|
3158
3502
|
*/
|
|
3159
|
-
function proseDocToBlocks(pmDoc, baseContent, styles
|
|
3160
|
-
const blocks = extractBlocks(pmDoc, "resolve", styles ? createStyleEngine(styles) : null
|
|
3503
|
+
function proseDocToBlocks(pmDoc, baseContent, styles) {
|
|
3504
|
+
const blocks = extractBlocks(pmDoc, "resolve", styles ? createStyleEngine(styles) : null);
|
|
3505
|
+
joinCommentRangesAcrossParagraphs(blocks);
|
|
3506
|
+
completeCommentReferences(blocks);
|
|
3161
3507
|
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
3162
3508
|
if (baseContent) restoreParagraphPropertySources(blocks, baseContent, linkedSources.targets, linkedSources.sources);
|
|
3163
3509
|
return blocks;
|