@stll/folio-core 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.js +59 -19
- package/dist/ai-edits/headless.js +1 -1
- package/dist/compare/compare.js +2 -5
- package/dist/compare/scenario.js +2 -5
- package/dist/compare/types.d.ts +9 -1
- package/dist/compare/types.js +12 -1
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/content-controls/checkboxDisplay.d.ts +11 -0
- package/dist/content-controls/checkboxDisplay.js +40 -0
- package/dist/content-controls/findContentControls.js +3 -1
- package/dist/content-controls/mutateContentControls.js +17 -2
- package/dist/controller/contentControlWidgetController.d.ts +1 -0
- package/dist/controller/contentControlWidgetController.js +3 -0
- package/dist/controller/hiddenEditorApi.js +3 -1
- package/dist/controller/hiddenEditorManager.d.ts +1 -1
- package/dist/controller/hiddenEditorManager.js +6 -3
- package/dist/display-list/build/buildDisplayList.js +20 -1
- package/dist/display-list/build/imagePrimitives.d.ts +1 -1
- package/dist/display-list/build/imagePrimitives.js +3 -1
- package/dist/display-list/build/paragraphPrimitives.js +21 -2
- package/dist/display-list/dom/renderDisplayListToDom.js +10 -2
- package/dist/display-list/types.d.ts +17 -0
- package/dist/docx/attributeRemainder.d.ts +43 -0
- package/dist/docx/attributeRemainder.js +65 -0
- package/dist/docx/blockContentParser.d.ts +1 -1
- package/dist/docx/blockContentParser.js +87 -63
- package/dist/docx/blockPlainText.d.ts +3 -4
- package/dist/docx/blockPlainText.js +1 -0
- package/dist/docx/bookmarkPlacement.js +2 -0
- package/dist/docx/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 +54 -37
- package/dist/docx/commentRangeIntegrity.d.ts +16 -1
- package/dist/docx/commentRangeIntegrity.js +42 -1
- package/dist/docx/commentRangeJoin.d.ts +9 -0
- package/dist/docx/commentRangeJoin.js +33 -0
- package/dist/docx/commentReferenceCompletion.d.ts +9 -0
- package/dist/docx/commentReferenceCompletion.js +47 -0
- package/dist/docx/commentReferenceNormalization.js +1 -0
- package/dist/docx/commentReplyMarkers.js +11 -19
- package/dist/docx/compatibility.js +1 -0
- package/dist/docx/containerChildren.d.ts +111 -0
- package/dist/docx/containerChildren.gen.d.ts +28 -0
- package/dist/docx/containerChildren.gen.js +246 -0
- package/dist/docx/containerChildren.js +103 -0
- package/dist/docx/documentParser.d.ts +1 -1
- package/dist/docx/documentParser.js +3 -3
- package/dist/docx/ensureParaIds.js +17 -7
- package/dist/docx/fieldParser.d.ts +1 -1
- package/dist/docx/fieldParser.js +4 -4
- package/dist/docx/fieldState.d.ts +26 -0
- package/dist/docx/fieldState.js +53 -0
- package/dist/docx/footnoteParser.d.ts +1 -1
- package/dist/docx/graphicFrameLocks.d.ts +16 -4
- package/dist/docx/graphicFrameLocks.js +19 -6
- package/dist/docx/headerFooterParser.js +1 -1
- package/dist/docx/headerFooterReferenceNormalization.js +1 -0
- package/dist/docx/hyperlinkParser.d.ts +27 -8
- package/dist/docx/hyperlinkParser.js +76 -18
- package/dist/docx/imageParser.js +33 -8
- package/dist/docx/inlineWrapperContent.d.ts +85 -0
- package/dist/docx/inlineWrapperContent.js +84 -0
- package/dist/docx/normalizeBaseDirection.js +10 -1
- package/dist/docx/paraIdAttribute.d.ts +21 -0
- package/dist/docx/paraIdAttribute.js +64 -0
- package/dist/docx/paragraphParser.d.ts +1 -1
- package/dist/docx/paragraphParser.js +277 -168
- package/dist/docx/paragraphPropertySource.js +5 -1
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +1 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +6 -52
- package/dist/docx/paragraphTraversal.js +7 -4
- package/dist/docx/parseWarningMessage.js +2 -1
- package/dist/docx/preservedRunContent.d.ts +32 -0
- package/dist/docx/preservedRunContent.js +86 -0
- package/dist/docx/renderedPageBreakNormalization.js +2 -4
- package/dist/docx/rezip.js +74 -18
- package/dist/docx/runParser.d.ts +1 -1
- package/dist/docx/runParser.js +16 -12
- package/dist/docx/sectionParser.js +8 -1
- package/dist/docx/selectiveXmlPatch.d.ts +46 -2
- package/dist/docx/selectiveXmlPatch.js +86 -39
- package/dist/docx/serializer/borderSerializer.js +2 -2
- package/dist/docx/serializer/commentSerializer.js +5 -7
- package/dist/docx/serializer/documentSerializer.js +8 -11
- package/dist/docx/serializer/headerFooterSerializer.js +7 -9
- package/dist/docx/serializer/noteSerializer.js +8 -8
- package/dist/docx/serializer/paragraphSerializer.js +76 -56
- package/dist/docx/serializer/runSerializer.js +25 -16
- package/dist/docx/serializer/sectionPropertiesSerializer.js +8 -4
- package/dist/docx/serializer/tableSerializer.js +18 -8
- package/dist/docx/server/createBilingualDocument.js +3 -1
- package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
- package/dist/docx/server/materializeYjsDocx.js +9 -1
- package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
- package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
- package/dist/docx/shapeParser.js +5 -5
- package/dist/docx/tableParser.d.ts +1 -1
- package/dist/docx/tableParser.js +206 -85
- package/dist/docx/textBoxParser.d.ts +25 -2
- package/dist/docx/textBoxParser.js +52 -2
- package/dist/docx/unzip.js +5 -4
- package/dist/docx/vmlImageParser.d.ts +17 -1
- package/dist/docx/vmlImageParser.js +17 -1
- package/dist/docx/xmlEncoding.d.ts +5 -0
- package/dist/docx/xmlEncoding.js +12 -0
- package/dist/docx/xmlParser.d.ts +10 -1
- package/dist/docx/xmlParser.js +14 -1
- package/dist/headless-layout.js +10 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +5 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +102 -12
- package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
- package/dist/layout-engine/measure/tableCellFloating.js +2 -0
- package/dist/layout-engine/types.d.ts +23 -1
- package/dist/layout-painter/renderImage.d.ts +5 -1
- package/dist/layout-painter/renderImage.js +10 -3
- package/dist/layout-painter/renderPage.d.ts +2 -0
- package/dist/layout-painter/renderPage.js +4 -0
- package/dist/layout-painter/renderParagraph.d.ts +13 -1
- package/dist/layout-painter/renderParagraph.js +22 -3
- package/dist/managers/autoSaveCodec.d.ts +9 -1
- package/dist/managers/autoSaveCodec.js +12 -4
- package/dist/markdown/renderBlock.js +1 -0
- package/dist/markdown/renderRuns.d.ts +1 -1
- package/dist/markdown/renderRuns.js +28 -5
- package/dist/markdown/renderTable.js +22 -5
- package/dist/markdown/trailers.js +4 -1
- package/dist/pdf/images.js +142 -6
- package/dist/prosemirror/attrs/index.d.ts +14 -3
- package/dist/prosemirror/attrs/index.js +155 -2
- package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
- package/dist/prosemirror/authoredTransformAttrs.js +64 -0
- package/dist/prosemirror/commands/contentControls.js +10 -2
- package/dist/prosemirror/commands/image.d.ts +9 -2
- package/dist/prosemirror/commands/image.js +42 -28
- package/dist/prosemirror/commands/pageBreak.js +1 -1
- package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
- package/dist/prosemirror/commentReferenceAttrs.js +33 -0
- package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
- package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
- package/dist/prosemirror/conversion/fromProseDoc.js +269 -70
- package/dist/prosemirror/conversion/index.d.ts +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
- package/dist/prosemirror/conversion/toProseDoc.js +468 -308
- package/dist/prosemirror/extensions/StarterKit.js +8 -58
- package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -1
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +45 -27
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
- package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
- package/dist/prosemirror/extensions/markRegistry.d.ts +41 -0
- package/dist/prosemirror/extensions/markRegistry.js +75 -0
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +63 -0
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +47 -4
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +87 -0
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +16 -0
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +3 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +3 -2
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +5 -1
- package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
- package/dist/prosemirror/inlineWrapperStack.js +75 -0
- package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
- package/dist/prosemirror/pageBreakRunProjection.js +19 -9
- package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
- package/dist/prosemirror/replacedAnnotations.js +165 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +3 -1
- package/dist/prosemirror/runFormattingInlineCarriers.js +5 -1
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +25 -1
- package/dist/prosemirror/schema/nodes.d.ts +90 -3
- package/dist/prosemirror/schema/nodes.js +16 -1
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
- package/dist/prosemirror/validation.js +16 -2
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
- package/dist/prosemirror/yjsDocumentMetadata.js +171 -0
- package/dist/prosemirror/zeroWidthAnchors.js +2 -0
- package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
- package/dist/render-dom/commentAnchorAttributes.js +54 -0
- package/dist/server.d.ts +3 -1
- package/dist/server.js +3 -1
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/clipboard.d.ts +9 -1
- package/dist/utils/clipboard.js +27 -1
- package/dist/utils/findReplace.js +1 -1
- package/dist/utils/imageLuminance.d.ts +15 -0
- package/dist/utils/imageLuminance.js +32 -0
- package/dist/utils/mergeDocumentContent.js +7 -17
- package/dist/utils/replaceText.js +1 -0
- package/package.json +2 -2
- package/dist/docx/blockRangeMarkers.d.ts +0 -36
- package/dist/docx/blockRangeMarkers.js +0 -59
- package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
- package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { joinCommentRangesAcrossParagraphs } from "../../docx/commentRangeJoin.js";
|
|
2
|
+
import { completeCommentReferences } from "../../docx/commentReferenceCompletion.js";
|
|
1
3
|
import { EDITED_PREVIEW_FINGERPRINT, imageRawXmlFingerprint } from "../../docx/imageRawXml.js";
|
|
4
|
+
import { isInlineSdtContent } from "../../docx/inlineWrapperContent.js";
|
|
2
5
|
import { isNumberingReference } from "../../docx/numberingReference.js";
|
|
3
6
|
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, ParagraphPropertySourceValidationError, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, linkParagraphPropertySourceCandidate, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceTokenMatchesContract, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings } from "../../docx/paragraphPropertySource.js";
|
|
4
7
|
import { visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
@@ -11,12 +14,16 @@ import { canonicalJson } from "../../utils/canonicalJson.js";
|
|
|
11
14
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
12
15
|
import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
13
16
|
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, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
17
|
+
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectPreservedBlockAttrs, expectPreservedXmlAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
18
|
+
import { readAuthoredTransform } from "../authoredTransformAttrs.js";
|
|
15
19
|
import { autospacingMatchesBase, hasAutospacingBaseSide } from "../autospacingBase.js";
|
|
16
20
|
import { bookmarkBoundaryDisplacement, expectBookmarkBoundaryAttrs } from "../bookmarkBoundaryAttrs.js";
|
|
17
21
|
import { paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges } from "../commands/propertyChangeScope.js";
|
|
22
|
+
import { expectCommentReferenceAttrs } from "../commentReferenceAttrs.js";
|
|
23
|
+
import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
|
|
18
24
|
import { applyRunFormattingOverrideAttrs, buildRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
19
25
|
import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
|
|
26
|
+
import { inlineWrapperMember, inlineWrapperStackKey } from "../inlineWrapperStack.js";
|
|
20
27
|
import { listRenderingFromAttrs as listRenderingFromAttrs$1 } from "../listRenderingAttrs.js";
|
|
21
28
|
import { resolveNumberedRefFields } from "../numberedRefFields.js";
|
|
22
29
|
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
@@ -26,6 +33,7 @@ import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
|
26
33
|
import { authoredRunFormattingFromAttrs, hasAuthoredRunFormattingProvenance } from "../runFormattingProvenance.js";
|
|
27
34
|
import { paragraphFormattingForRun, paragraphRunStyleContext, resolveEffectiveRunStyleFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
28
35
|
import { schema } from "../schema/index.js";
|
|
36
|
+
import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
|
|
29
37
|
import { parseShapeGeometryAdjustments } from "../shapeGeometryAdjustments.js";
|
|
30
38
|
import { expectTextBoxAnchorAttrs } from "../textBoxAnchorAttrs.js";
|
|
31
39
|
import { assertValidProseMirrorDocument } from "../validation.js";
|
|
@@ -51,19 +59,6 @@ function normalizeShapeOutlineStyle(style) {
|
|
|
51
59
|
if (style in OUTLINE_STYLE_CSS_ALIASES) return OUTLINE_STYLE_CSS_ALIASES[style];
|
|
52
60
|
return narrowEnum(style, ShapeOutlineStyleSchema);
|
|
53
61
|
}
|
|
54
|
-
function parseTransformAttr(transformStr) {
|
|
55
|
-
if (!transformStr) return;
|
|
56
|
-
const transform = {};
|
|
57
|
-
const rotateMatch = /rotate\((?<deg>[-\d.]+)deg\)/u.exec(transformStr);
|
|
58
|
-
if (rotateMatch) {
|
|
59
|
-
const rotation = Number.parseFloat(rotateMatch.groups["deg"]);
|
|
60
|
-
if (Number.isFinite(rotation)) transform.rotation = rotation;
|
|
61
|
-
}
|
|
62
|
-
if (transformStr.includes("scaleX(-1)")) transform.flipH = true;
|
|
63
|
-
if (transformStr.includes("scaleY(-1)")) transform.flipV = true;
|
|
64
|
-
if (transform.rotation === void 0 && !transform.flipH && !transform.flipV) return;
|
|
65
|
-
return transform;
|
|
66
|
-
}
|
|
67
62
|
function imagePositionFromAttrs(attrs) {
|
|
68
63
|
const horizontalPosition = attrs?.horizontal;
|
|
69
64
|
const verticalPosition = attrs?.vertical;
|
|
@@ -236,6 +231,8 @@ function fromProseDoc(pmDoc, baseDocument) {
|
|
|
236
231
|
if (proseContractAttribute !== null && proseContractAttribute !== void 0 && proseContract === null || (baseContract ?? null) !== proseContract) throw sourceValidationError("contract_mismatch", "The ProseMirror document does not match its paragraph-property source document.");
|
|
237
232
|
const tokenSources = baseContract && proseContract && baseDocument ? validateParagraphPropertySourceTokens(pmDoc, baseDocument, baseContract) : null;
|
|
238
233
|
const blocks = extractBlocks(pmDoc, "resolve", baseDocument?.package.styles ? createStyleEngine(baseDocument.package.styles) : null);
|
|
234
|
+
joinCommentRangesAcrossParagraphs(blocks);
|
|
235
|
+
completeCommentReferences(blocks);
|
|
239
236
|
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
240
237
|
if (tokenSources) restoreParagraphPropertySourcesByToken(blocks, tokenSources);
|
|
241
238
|
else if (baseDocument) restoreParagraphPropertySources(blocks, baseDocument.package.document.content, linkedSources.targets, linkedSources.sources);
|
|
@@ -452,42 +449,9 @@ function materializeNumberedRefValues(doc) {
|
|
|
452
449
|
};
|
|
453
450
|
return visit(doc);
|
|
454
451
|
}
|
|
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") {
|
|
452
|
+
function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null) {
|
|
488
453
|
const strippedDoc = stripSuggestedProvenance(inputDoc, styleResolver);
|
|
489
|
-
const
|
|
490
|
-
const pmDoc = emptyFieldResult === "serializerFallback" ? materializeSerializerFieldFallbacks(refResolvedDoc) : refResolvedDoc;
|
|
454
|
+
const pmDoc = refResolution === "resolve" ? materializeNumberedRefValues(strippedDoc) : strippedDoc;
|
|
491
455
|
const blocks = [];
|
|
492
456
|
const textBoxAnchorMarkers = /* @__PURE__ */ new Map();
|
|
493
457
|
const documentCounts = buildDocumentTrackedChangeCounts(pmDoc);
|
|
@@ -530,15 +494,69 @@ function extractBlocks(inputDoc, refResolution = "resolve", styleResolver = null
|
|
|
530
494
|
pendingPageBreaks = 0;
|
|
531
495
|
} else if (node.type.name === "blockSdt") {
|
|
532
496
|
if (pendingPageBreaks > 0 && !appendPendingPageBreaksToPreviousParagraph()) flushPendingPageBreaks();
|
|
533
|
-
blocks.push(convertPMBlockSdt(node, styleResolver
|
|
497
|
+
blocks.push(convertPMBlockSdt(node, styleResolver));
|
|
498
|
+
previousStandaloneTextBox = null;
|
|
499
|
+
} else if (node.type.name === "preservedBlock") {
|
|
500
|
+
blocks.push({
|
|
501
|
+
type: "preservedBlock",
|
|
502
|
+
xml: expectPreservedBlockAttrs(node).xml
|
|
503
|
+
});
|
|
534
504
|
previousStandaloneTextBox = null;
|
|
535
505
|
}
|
|
536
506
|
});
|
|
537
507
|
if (pendingPageBreaks > 0 && !appendPendingPageBreaksToPreviousParagraph()) flushPendingPageBreaks();
|
|
538
508
|
removeUnresolvedTextBoxAnchors(blocks, textBoxAnchorMarkers);
|
|
509
|
+
keepOneAttributeRemainderPerRecord(blocks);
|
|
539
510
|
return blocks;
|
|
540
511
|
}
|
|
541
|
-
|
|
512
|
+
/**
|
|
513
|
+
* The attribute remainder follows the record it was authored on, and only it.
|
|
514
|
+
*
|
|
515
|
+
* ProseMirror copies a node's attrs when a command splits it, so pressing
|
|
516
|
+
* Enter in the middle of a paragraph produces two nodes holding the *same*
|
|
517
|
+
* remainder array. Writing it back on both would give the new half a
|
|
518
|
+
* revision-session id nobody assigned to it: `w:rsidR` says which editing
|
|
519
|
+
* session wrote this paragraph, and a copy of it is a claim about history the
|
|
520
|
+
* author did not make. The rule is that the half that comes first in document
|
|
521
|
+
* order keeps the authored identity, and the other half is a new record with
|
|
522
|
+
* no remainder — the same answer a paragraph the editor created from scratch
|
|
523
|
+
* gets, which is none.
|
|
524
|
+
*
|
|
525
|
+
* Reference identity is what tells the two cases apart, and it is exact: two
|
|
526
|
+
* records that each parsed their own attributes hold different arrays however
|
|
527
|
+
* equal their contents, and only a copy made by the editor shares one.
|
|
528
|
+
*/
|
|
529
|
+
const keepOneAttributeRemainderPerRecord = (blocks) => {
|
|
530
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
531
|
+
const keepFirst = (record) => {
|
|
532
|
+
const remainder = record.preservedAttributes;
|
|
533
|
+
if (remainder === void 0) return;
|
|
534
|
+
if (seen.has(remainder)) {
|
|
535
|
+
delete record.preservedAttributes;
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
seen.add(remainder);
|
|
539
|
+
};
|
|
540
|
+
const walk = (content) => {
|
|
541
|
+
for (const block of content) switch (block.type) {
|
|
542
|
+
case "paragraph":
|
|
543
|
+
keepFirst(block);
|
|
544
|
+
break;
|
|
545
|
+
case "table":
|
|
546
|
+
for (const row of block.rows) {
|
|
547
|
+
keepFirst(row);
|
|
548
|
+
for (const cell of row.cells) walk(cell.content);
|
|
549
|
+
}
|
|
550
|
+
break;
|
|
551
|
+
case "blockSdt":
|
|
552
|
+
walk(block.content);
|
|
553
|
+
break;
|
|
554
|
+
default: break;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
walk(blocks);
|
|
558
|
+
};
|
|
559
|
+
function convertPMBlockSdt(node, styleResolver) {
|
|
542
560
|
const attrs = expectBlockSdtAttrs(node);
|
|
543
561
|
const properties = { sdtType: attrs.sdtType };
|
|
544
562
|
if (attrs.alias) properties.alias = attrs.alias;
|
|
@@ -556,7 +574,7 @@ function convertPMBlockSdt(node, styleResolver, emptyFieldResult) {
|
|
|
556
574
|
if (attrs.rawEndPropertiesXml) properties.rawEndPropertiesXml = attrs.rawEndPropertiesXml;
|
|
557
575
|
if (attrs.rawSdtChildrenBeforeContent) properties.rawSdtChildrenBeforeContent = attrs.rawSdtChildrenBeforeContent;
|
|
558
576
|
if (attrs.rawSdtChildrenAfterContent) properties.rawSdtChildrenAfterContent = attrs.rawSdtChildrenAfterContent;
|
|
559
|
-
const extracted = extractBlocks(node.type.schema.node("doc", null, node.content), "inherit", styleResolver
|
|
577
|
+
const extracted = extractBlocks(node.type.schema.node("doc", null, node.content), "inherit", styleResolver);
|
|
560
578
|
return {
|
|
561
579
|
type: "blockSdt",
|
|
562
580
|
properties,
|
|
@@ -594,6 +612,7 @@ function appendTextBoxBlock(blocks, node, options) {
|
|
|
594
612
|
if (!mergeTextBoxIntoTrailingInlineSdts(options.previousStandaloneTextBox.paragraph, paragraph, attrs._docxInlineSdts ?? [])) options.previousStandaloneTextBox.paragraph.content.push(...paragraph.content);
|
|
595
613
|
return options.previousStandaloneTextBox;
|
|
596
614
|
}
|
|
615
|
+
if (attrs._docxPlacement === "standalone" && attrs._preservedAttributes?.length) paragraph.preservedAttributes = attrs._preservedAttributes;
|
|
597
616
|
prependPageBreaks(paragraph, options.pendingPageBreaks);
|
|
598
617
|
blocks.push(paragraph);
|
|
599
618
|
return attrs._docxPlacement === "standalone" && attrs._docxGroupId ? {
|
|
@@ -647,7 +666,7 @@ function findTextBoxShapeRun(content) {
|
|
|
647
666
|
if (item.content.some((runContent) => runContent.type === "shape" && runContent.shape.shapeType === "textBox")) return item;
|
|
648
667
|
continue;
|
|
649
668
|
}
|
|
650
|
-
if (item.type === "inlineSdt" || item.type === "hyperlink" || item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
669
|
+
if (item.type === "inlineSdt" || item.type === "hyperlink" || item.type === "inlineWrapper" || item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
651
670
|
const run = findTextBoxShapeRun(item.type === "hyperlink" ? item.children : item.content);
|
|
652
671
|
if (run) return run;
|
|
653
672
|
}
|
|
@@ -663,6 +682,7 @@ function replaceTextBoxAnchorInBlocks(blocks, marker, textBoxRun) {
|
|
|
663
682
|
for (const row of block.rows) for (const cell of row.cells) if (replaceTextBoxAnchorInBlocks(cell.content, marker, textBoxRun)) return true;
|
|
664
683
|
continue;
|
|
665
684
|
}
|
|
685
|
+
if (block.type === "preservedBlock") continue;
|
|
666
686
|
if (replaceTextBoxAnchorInBlocks(block.content, marker, textBoxRun)) return true;
|
|
667
687
|
}
|
|
668
688
|
return false;
|
|
@@ -685,7 +705,7 @@ const textBoxAnchorHost = (item) => {
|
|
|
685
705
|
case "deletion":
|
|
686
706
|
case "moveFrom":
|
|
687
707
|
case "moveTo":
|
|
688
|
-
case "
|
|
708
|
+
case "inlineWrapper": return item.content;
|
|
689
709
|
case "run":
|
|
690
710
|
case "complexField":
|
|
691
711
|
case "bookmarkStart":
|
|
@@ -697,7 +717,8 @@ const textBoxAnchorHost = (item) => {
|
|
|
697
717
|
case "moveFromRangeEnd":
|
|
698
718
|
case "moveToRangeStart":
|
|
699
719
|
case "moveToRangeEnd":
|
|
700
|
-
case "mathEquation":
|
|
720
|
+
case "mathEquation":
|
|
721
|
+
case "preservedInline": return;
|
|
701
722
|
default: panic(`Unsupported paragraph content: ${JSON.stringify(item)}`);
|
|
702
723
|
}
|
|
703
724
|
};
|
|
@@ -730,6 +751,7 @@ function removeTextBoxAnchorFromBlocks(blocks, marker) {
|
|
|
730
751
|
for (const row of block.rows) for (const cell of row.cells) if (removeTextBoxAnchorFromBlocks(cell.content, marker)) return true;
|
|
731
752
|
continue;
|
|
732
753
|
}
|
|
754
|
+
if (block.type === "preservedBlock") continue;
|
|
733
755
|
if (removeTextBoxAnchorFromBlocks(block.content, marker)) return true;
|
|
734
756
|
}
|
|
735
757
|
return false;
|
|
@@ -825,6 +847,7 @@ function convertPMParagraph(node, documentCounts, textBoxAnchorMarkers, styleRes
|
|
|
825
847
|
else if (attrs.sectionBreakType) paragraph.sectionProperties = { sectionStart: attrs.sectionBreakType };
|
|
826
848
|
if (attrs._propertyChanges && attrs._propertyChanges.length > 0) paragraph.propertyChanges = attrs._propertyChanges.map(propertyChangeFromAttrs);
|
|
827
849
|
if (attrs.pPrMark) paragraph.pPrMark = attrs.pPrMark;
|
|
850
|
+
if (attrs._preservedAttributes && attrs._preservedAttributes.length > 0) paragraph.preservedAttributes = attrs._preservedAttributes;
|
|
828
851
|
linkParagraphPropertySourceCandidate(paragraph, node);
|
|
829
852
|
return paragraph;
|
|
830
853
|
}
|
|
@@ -1017,6 +1040,70 @@ function createTrackedRunWrapper(type, info, child) {
|
|
|
1017
1040
|
content
|
|
1018
1041
|
};
|
|
1019
1042
|
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Comment ids in the order their markers are written at a shared boundary.
|
|
1045
|
+
*
|
|
1046
|
+
* Two ranges that begin or end at the same position have no order in the
|
|
1047
|
+
* editor, where each is a mark, so every emission site orders them by id: a
|
|
1048
|
+
* boundary written in the order the marks happened to open is a different
|
|
1049
|
+
* document each time the same one is saved.
|
|
1050
|
+
*/
|
|
1051
|
+
const byCommentId = (ids) => [...ids].toSorted((a, b) => a - b);
|
|
1052
|
+
/** The wrappers `node` sits inside, outermost first; empty when it sits in none. */
|
|
1053
|
+
const inlineWrapperStackOf = (node) => {
|
|
1054
|
+
const mark = node.marks.find((candidate) => candidate.type.name === INLINE_WRAPPER_MARK_NAME);
|
|
1055
|
+
return mark ? expectInlineWrapperMarkAttrs(mark).stack : [];
|
|
1056
|
+
};
|
|
1057
|
+
const isRevisionWrapper = (item) => item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo";
|
|
1058
|
+
/** `stack` closed around `content`, outermost layer first. */
|
|
1059
|
+
const nestInlineWrappers = (stack, content) => {
|
|
1060
|
+
const innermost = stack.at(-1);
|
|
1061
|
+
if (innermost === void 0) panic("An inline wrapper group carries no layer");
|
|
1062
|
+
let wrapper = inlineWrapperMember(innermost, content);
|
|
1063
|
+
for (const layer of stack.slice(0, -1).toReversed()) wrapper = inlineWrapperMember(layer, [wrapper]);
|
|
1064
|
+
return wrapper;
|
|
1065
|
+
};
|
|
1066
|
+
/**
|
|
1067
|
+
* The emitted sequence with each wrapper group nested back into the wrappers
|
|
1068
|
+
* `toProseDoc` lifted off it.
|
|
1069
|
+
*
|
|
1070
|
+
* The revision stays outermost. folio already writes a revision outside the
|
|
1071
|
+
* hyperlink it spans, the parse leg is revision-owned, and accepting or
|
|
1072
|
+
* rejecting one is a range operation over the revision's own content; a
|
|
1073
|
+
* wrapper placed outside two revisions would also have to mint one revision id
|
|
1074
|
+
* per wrapper. So a revision in the group keeps its place and takes the nest
|
|
1075
|
+
* inside it, and the items around it share a nest of their own.
|
|
1076
|
+
*
|
|
1077
|
+
* A group with nothing in it writes no wrapper: an authored wrapper whose
|
|
1078
|
+
* content was deleted or rejected is gone, and an empty one says nothing.
|
|
1079
|
+
*/
|
|
1080
|
+
const nestInlineWrapperGroups = (items, groups) => {
|
|
1081
|
+
const nested = [];
|
|
1082
|
+
for (const [index, group] of groups.entries()) {
|
|
1083
|
+
const slice = items.slice(group.start, groups[index + 1]?.start ?? items.length);
|
|
1084
|
+
if (group.stack.length === 0) {
|
|
1085
|
+
nested.push(...slice);
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
let pending = [];
|
|
1089
|
+
const closeNest = () => {
|
|
1090
|
+
if (pending.length === 0) return;
|
|
1091
|
+
nested.push(nestInlineWrappers(group.stack, pending));
|
|
1092
|
+
pending = [];
|
|
1093
|
+
};
|
|
1094
|
+
for (const item of slice) {
|
|
1095
|
+
if (!isRevisionWrapper(item)) {
|
|
1096
|
+
pending.push(item);
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
closeNest();
|
|
1100
|
+
if (item.content.length > 0) item.content = [nestInlineWrappers(group.stack, item.content)];
|
|
1101
|
+
nested.push(item);
|
|
1102
|
+
}
|
|
1103
|
+
closeNest();
|
|
1104
|
+
}
|
|
1105
|
+
return nested;
|
|
1106
|
+
};
|
|
1020
1107
|
function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, textBoxAnchorMarkers, skipLeadingRenderedPageBreak = false, inheritedFormattingOverride) {
|
|
1021
1108
|
const content = [];
|
|
1022
1109
|
const paragraphStyleContext = paragraph.type.name === "paragraph" ? paragraphRunStyleContext(paragraph) : void 0;
|
|
@@ -1033,6 +1120,11 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1033
1120
|
})).toSorted((left, right) => left.attrs.offset - right.attrs.offset || left.order - right.order);
|
|
1034
1121
|
let nextEmptyHyperlink = 0;
|
|
1035
1122
|
let leadingRenderedPageBreakPending = skipLeadingRenderedPageBreak;
|
|
1123
|
+
const wrapperGroups = [{
|
|
1124
|
+
start: 0,
|
|
1125
|
+
stack: []
|
|
1126
|
+
}];
|
|
1127
|
+
let wrapperGroupKey = "";
|
|
1036
1128
|
let currentRun = null;
|
|
1037
1129
|
let currentMarksKey = null;
|
|
1038
1130
|
let currentHyperlink = null;
|
|
@@ -1086,14 +1178,14 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1086
1178
|
if (toClose.length === 0 && toOpen.length === 0) return;
|
|
1087
1179
|
flushCurrentInline();
|
|
1088
1180
|
currentTrackedChange = void 0;
|
|
1089
|
-
for (const commentId of toClose
|
|
1181
|
+
for (const commentId of byCommentId(toClose)) {
|
|
1090
1182
|
content.push({
|
|
1091
1183
|
type: "commentRangeEnd",
|
|
1092
1184
|
id: commentId
|
|
1093
1185
|
});
|
|
1094
1186
|
openedComments.delete(commentId);
|
|
1095
1187
|
}
|
|
1096
|
-
for (const commentId of toOpen
|
|
1188
|
+
for (const commentId of byCommentId(toOpen)) {
|
|
1097
1189
|
content.push({
|
|
1098
1190
|
type: "commentRangeStart",
|
|
1099
1191
|
id: commentId
|
|
@@ -1111,13 +1203,45 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1111
1203
|
content.push(createEmptyHyperlink(item.attrs));
|
|
1112
1204
|
}
|
|
1113
1205
|
};
|
|
1206
|
+
/**
|
|
1207
|
+
* Cut the emitted sequence where the wrapper the nodes sit inside changes.
|
|
1208
|
+
*
|
|
1209
|
+
* Nothing that spans nodes may span the cut: a run, a hyperlink and a
|
|
1210
|
+
* revision each sit inside one wrapper or outside it, never half in. The
|
|
1211
|
+
* comment ranges `syncCommentRanges` writes are cut with the rest, which
|
|
1212
|
+
* puts a range that opens or closes inside a wrapper inside it, as Word
|
|
1213
|
+
* writes it; a range marker says the same thing at either level, because the
|
|
1214
|
+
* wrapper is transparent and the position is unchanged.
|
|
1215
|
+
*/
|
|
1216
|
+
const enterWrapperGroup = (node) => {
|
|
1217
|
+
const stack = inlineWrapperStackOf(node);
|
|
1218
|
+
const key = inlineWrapperStackKey(stack);
|
|
1219
|
+
if (key === wrapperGroupKey) return;
|
|
1220
|
+
flushCurrentInline();
|
|
1221
|
+
currentTrackedChange = void 0;
|
|
1222
|
+
wrapperGroupKey = key;
|
|
1223
|
+
wrapperGroups.push({
|
|
1224
|
+
start: content.length,
|
|
1225
|
+
stack
|
|
1226
|
+
});
|
|
1227
|
+
};
|
|
1114
1228
|
const processInlineNode = (node, offset) => {
|
|
1115
1229
|
if (node.type.name === "renderedPageBreak" && leadingRenderedPageBreakPending) {
|
|
1116
1230
|
leadingRenderedPageBreakPending = false;
|
|
1117
1231
|
return;
|
|
1118
1232
|
}
|
|
1119
1233
|
leadingRenderedPageBreakPending = false;
|
|
1234
|
+
enterWrapperGroup(node);
|
|
1120
1235
|
syncCommentRanges(node, offset);
|
|
1236
|
+
if (node.type.name === "commentReference") {
|
|
1237
|
+
flushCurrentInline();
|
|
1238
|
+
currentTrackedChange = void 0;
|
|
1239
|
+
content.push({
|
|
1240
|
+
type: "commentReference",
|
|
1241
|
+
id: expectCommentReferenceAttrs(node).commentId
|
|
1242
|
+
});
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1121
1245
|
const linkMark = node.marks.find((m) => m.type.name === "hyperlink");
|
|
1122
1246
|
const noteRefMark = node.marks.find((m) => m.type.name === "footnoteRef");
|
|
1123
1247
|
const insertionMark = node.marks.find((m) => m.type.name === "insertion");
|
|
@@ -1210,6 +1334,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1210
1334
|
});
|
|
1211
1335
|
return;
|
|
1212
1336
|
}
|
|
1337
|
+
if (isInlineLevelPreservedXml(node)) {
|
|
1338
|
+
currentTrackedChange.hyperlink.children.push(createPreservedInline(node));
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1213
1341
|
const run = createTrackedChangeRun({
|
|
1214
1342
|
...formattingContext,
|
|
1215
1343
|
marks: otherMarks,
|
|
@@ -1256,6 +1384,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1256
1384
|
currentTrackedChange.wrapper.content.push(createMathFromNode(node));
|
|
1257
1385
|
return;
|
|
1258
1386
|
}
|
|
1387
|
+
if (isInlineLevelPreservedXml(node)) {
|
|
1388
|
+
currentTrackedChange.wrapper.content.push(createPreservedInline(node));
|
|
1389
|
+
return;
|
|
1390
|
+
}
|
|
1259
1391
|
const run = createTrackedChangeRun({
|
|
1260
1392
|
...formattingContext,
|
|
1261
1393
|
marks: otherMarks,
|
|
@@ -1325,6 +1457,9 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1325
1457
|
} else if (node.type.name === "symbol") {
|
|
1326
1458
|
flushCurrentInline();
|
|
1327
1459
|
content.push(createSymbolRun(node, node.marks, formattingContext));
|
|
1460
|
+
} else if (node.type.name === "preservedXml") {
|
|
1461
|
+
flushCurrentInline();
|
|
1462
|
+
content.push(isInlineLevelPreservedXml(node) ? createPreservedInline(node) : createPreservedXmlRun(node, node.marks, formattingContext));
|
|
1328
1463
|
} else if (node.type.name === "hardBreak") {
|
|
1329
1464
|
flushCurrentInline();
|
|
1330
1465
|
content.push(createBreakRun(expectHardBreakAttrs(node), node.marks, formattingContext));
|
|
@@ -1379,11 +1514,11 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1379
1514
|
});
|
|
1380
1515
|
flushEmptyHyperlinksThroughOffset(Number.POSITIVE_INFINITY);
|
|
1381
1516
|
flushCurrentInline();
|
|
1382
|
-
for (const commentId of openedComments) content.push({
|
|
1517
|
+
for (const commentId of byCommentId(openedComments)) content.push({
|
|
1383
1518
|
type: "commentRangeEnd",
|
|
1384
1519
|
id: commentId
|
|
1385
1520
|
});
|
|
1386
|
-
return content;
|
|
1521
|
+
return nestInlineWrapperGroups(content, wrapperGroups);
|
|
1387
1522
|
}
|
|
1388
1523
|
function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting, marks, node, paragraphMarkFormatting, paragraphMarkPrecedesStyle, styleResolver }) {
|
|
1389
1524
|
const formattingContext = {
|
|
@@ -1408,6 +1543,7 @@ function createTrackedChangeRun({ baseParagraphFormatting, inheritedFormatting,
|
|
|
1408
1543
|
};
|
|
1409
1544
|
restoreRunPropertyChanges(run, marks);
|
|
1410
1545
|
} else if (node.type.name === "symbol") run = createSymbolRun(node, marks, formattingContext);
|
|
1546
|
+
else if (node.type.name === "preservedXml") run = createPreservedXmlRun(node, marks, formattingContext);
|
|
1411
1547
|
else if (node.type.name === "hardBreak") run = createBreakRun(expectHardBreakAttrs(node), marks, formattingContext);
|
|
1412
1548
|
else if (node.type.name === "pageBreakRun") {
|
|
1413
1549
|
const { clear } = expectPageBreakRunAttrs(node);
|
|
@@ -1582,6 +1718,16 @@ function addNodeToHyperlink({ baseParagraphFormatting, hyperlink, inheritedForma
|
|
|
1582
1718
|
}));
|
|
1583
1719
|
return;
|
|
1584
1720
|
}
|
|
1721
|
+
if (node.type.name === "preservedXml") {
|
|
1722
|
+
hyperlink.children.push(isInlineLevelPreservedXml(node) ? createPreservedInline(node) : createPreservedXmlRun(node, nonLinkMarks, {
|
|
1723
|
+
baseParagraphFormatting,
|
|
1724
|
+
inheritedFormatting,
|
|
1725
|
+
paragraphMarkFormatting,
|
|
1726
|
+
paragraphMarkPrecedesStyle,
|
|
1727
|
+
styleResolver
|
|
1728
|
+
}));
|
|
1729
|
+
return;
|
|
1730
|
+
}
|
|
1585
1731
|
if (node.type.name === "hardBreak") {
|
|
1586
1732
|
hyperlink.children.push(createBreakRun(expectHardBreakAttrs(node), nonLinkMarks, {
|
|
1587
1733
|
baseParagraphFormatting,
|
|
@@ -1679,6 +1825,44 @@ function createSymbolRun(node, marks, formattingContext) {
|
|
|
1679
1825
|
restoreRunPropertyChanges(run, marks);
|
|
1680
1826
|
return run;
|
|
1681
1827
|
}
|
|
1828
|
+
/**
|
|
1829
|
+
* Whether the atom's markup is a paragraph child rather than a run child.
|
|
1830
|
+
*
|
|
1831
|
+
* The two are the same node in the editor and different elements in the file:
|
|
1832
|
+
* `w:ruby` has to go back inside a `w:r` and `w:permStart` may not, because
|
|
1833
|
+
* the schema admits no such child of a run and Word reports the package as
|
|
1834
|
+
* unreadable content.
|
|
1835
|
+
*/
|
|
1836
|
+
const isInlineLevelPreservedXml = (node) => node.type.name === "preservedXml" && expectPreservedXmlAttrs(node).level === PRESERVED_XML_LEVELS.inline;
|
|
1837
|
+
/** The paragraph-level capture an inline-level atom writes back. */
|
|
1838
|
+
const createPreservedInline = (node) => {
|
|
1839
|
+
const { xml, text } = expectPreservedXmlAttrs(node);
|
|
1840
|
+
return {
|
|
1841
|
+
type: "preservedInline",
|
|
1842
|
+
xml,
|
|
1843
|
+
text
|
|
1844
|
+
};
|
|
1845
|
+
};
|
|
1846
|
+
/**
|
|
1847
|
+
* Rebuild the run around a preserved child. The markup is opaque and comes
|
|
1848
|
+
* back byte for byte; only the run properties around it are rebuilt from the
|
|
1849
|
+
* atom's marks, exactly as for a symbol.
|
|
1850
|
+
*/
|
|
1851
|
+
function createPreservedXmlRun(node, marks, formattingContext) {
|
|
1852
|
+
const { xml, text } = expectPreservedXmlAttrs(node);
|
|
1853
|
+
const run = {
|
|
1854
|
+
type: "run",
|
|
1855
|
+
content: [{
|
|
1856
|
+
type: "preservedXml",
|
|
1857
|
+
xml,
|
|
1858
|
+
text
|
|
1859
|
+
}]
|
|
1860
|
+
};
|
|
1861
|
+
const formatting = getAtomRunFormattingFromMarks(marks, formattingContext);
|
|
1862
|
+
if (formatting) run.formatting = formatting;
|
|
1863
|
+
restoreRunPropertyChanges(run, marks);
|
|
1864
|
+
return run;
|
|
1865
|
+
}
|
|
1682
1866
|
function restoreRunPropertyChanges(run, marks) {
|
|
1683
1867
|
const changeMark = marks.find((mark) => mark.type.name === "runPropertyChange");
|
|
1684
1868
|
if (!changeMark) return;
|
|
@@ -1821,7 +2005,7 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1821
2005
|
paragraphMarkFormatting,
|
|
1822
2006
|
paragraphMarkPrecedesStyle: paragraphMarkPrecedesStyle ?? false,
|
|
1823
2007
|
styleResolver: styleResolver ?? null
|
|
1824
|
-
}).filter((content) => content.type === "run" || content.type === "hyperlink");
|
|
2008
|
+
}).filter((content) => content.type === "run" || content.type === "hyperlink" || content.type === "preservedInline");
|
|
1825
2009
|
const displayText = attrs.displayText ?? "";
|
|
1826
2010
|
const displayRun = {
|
|
1827
2011
|
type: "run",
|
|
@@ -1842,8 +2026,8 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1842
2026
|
fieldCode: [],
|
|
1843
2027
|
fieldResult: fieldContent.length > 0 ? fieldContent.filter((content) => content.type === "run") : fallbackFieldContent
|
|
1844
2028
|
};
|
|
1845
|
-
if (attrs.fldLock) complex.fldLock =
|
|
1846
|
-
if (attrs.dirty) complex.dirty =
|
|
2029
|
+
if (attrs.fldLock !== void 0) complex.fldLock = attrs.fldLock;
|
|
2030
|
+
if (attrs.dirty !== void 0) complex.dirty = attrs.dirty;
|
|
1847
2031
|
return complex;
|
|
1848
2032
|
}
|
|
1849
2033
|
const simple = {
|
|
@@ -1852,8 +2036,8 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1852
2036
|
fieldType: attrs.fieldType,
|
|
1853
2037
|
content: fieldContent.length > 0 ? fieldContent : fallbackFieldContent
|
|
1854
2038
|
};
|
|
1855
|
-
if (attrs.fldLock) simple.fldLock =
|
|
1856
|
-
if (attrs.dirty) simple.dirty =
|
|
2039
|
+
if (attrs.fldLock !== void 0) simple.fldLock = attrs.fldLock;
|
|
2040
|
+
if (attrs.dirty !== void 0) simple.dirty = attrs.dirty;
|
|
1857
2041
|
return simple;
|
|
1858
2042
|
}
|
|
1859
2043
|
const synchronizeFieldDisplayText = (content, displayText, fallbackRun) => {
|
|
@@ -1864,6 +2048,7 @@ const synchronizeFieldDisplayText = (content, displayText, fallbackRun) => {
|
|
|
1864
2048
|
visit(child);
|
|
1865
2049
|
continue;
|
|
1866
2050
|
}
|
|
2051
|
+
if (child.type !== "hyperlink") continue;
|
|
1867
2052
|
for (const hyperlinkChild of child.children) if (hyperlinkChild.type === "run") visit(hyperlinkChild);
|
|
1868
2053
|
}
|
|
1869
2054
|
};
|
|
@@ -1909,7 +2094,7 @@ function createInlineSdtFromNode(node, textBoxAnchorMarkers, formattingContext)
|
|
|
1909
2094
|
return {
|
|
1910
2095
|
type: "inlineSdt",
|
|
1911
2096
|
properties: sdtPropertiesFromAttrs(expectSdtAttrs(node)),
|
|
1912
|
-
content: extractParagraphContent(node, void 0, void 0, textBoxAnchorMarkers, false, formattingContext).filter(
|
|
2097
|
+
content: extractParagraphContent(node, void 0, void 0, textBoxAnchorMarkers, false, formattingContext).filter(isInlineSdtContent)
|
|
1913
2098
|
};
|
|
1914
2099
|
}
|
|
1915
2100
|
/**
|
|
@@ -1942,9 +2127,13 @@ function createImageRun(node) {
|
|
|
1942
2127
|
if (attrs.docPrName != null) image.docPrName = attrs.docPrName;
|
|
1943
2128
|
if (attrs.alt != null) image.alt = attrs.alt;
|
|
1944
2129
|
if (attrs.title != null) image.title = attrs.title;
|
|
1945
|
-
const imageTransform =
|
|
2130
|
+
const imageTransform = readAuthoredTransform(attrs);
|
|
1946
2131
|
if (imageTransform) image.transform = imageTransform;
|
|
1947
2132
|
if (attrs.opacity != null) image.opacity = attrs.opacity;
|
|
2133
|
+
if (attrs.brightness != null || attrs.contrast != null) image.effects = {
|
|
2134
|
+
...attrs.brightness == null ? {} : { brightness: attrs.brightness },
|
|
2135
|
+
...attrs.contrast == null ? {} : { contrast: attrs.contrast }
|
|
2136
|
+
};
|
|
1948
2137
|
const imagePosition = imagePositionFromAttrs(attrs.position);
|
|
1949
2138
|
if (imagePosition) image.position = imagePosition;
|
|
1950
2139
|
if (attrs.layoutInCell !== void 0) image.layoutInCell = attrs.layoutInCell;
|
|
@@ -2049,7 +2238,7 @@ function createShapeRun(node) {
|
|
|
2049
2238
|
if (attrs.title !== void 0) shape.title = attrs.title;
|
|
2050
2239
|
const geometryAdjustments = parseShapeGeometryAdjustments(attrs.geometryAdjustments);
|
|
2051
2240
|
if (geometryAdjustments !== void 0) shape.geometryAdjustments = geometryAdjustments;
|
|
2052
|
-
const shapeTransform =
|
|
2241
|
+
const shapeTransform = readAuthoredTransform(attrs);
|
|
2053
2242
|
if (shapeTransform) shape.transform = shapeTransform;
|
|
2054
2243
|
const wrap = { type: attrs.wrapType || "inline" };
|
|
2055
2244
|
assignWrapDistances(wrap, attrs);
|
|
@@ -2860,6 +3049,7 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges, styleReso
|
|
|
2860
3049
|
const rowFormatting = tableRowAttrsToFormatting(attrs);
|
|
2861
3050
|
if (rowFormatting) row.formatting = rowFormatting;
|
|
2862
3051
|
if (Array.isArray(attrs.trPrChange) && attrs.trPrChange.length > 0) row.propertyChanges = [...attrs.trPrChange];
|
|
3052
|
+
if (attrs._preservedAttributes && attrs._preservedAttributes.length > 0) row.preservedAttributes = attrs._preservedAttributes;
|
|
2863
3053
|
if (attrs.trIns) row.structuralChange = {
|
|
2864
3054
|
type: "tableRowInsertion",
|
|
2865
3055
|
info: {
|
|
@@ -2952,6 +3142,13 @@ function convertPMTableCell(node, documentCounts, styleResolver = null) {
|
|
|
2952
3142
|
textBoxAnchorMarkers,
|
|
2953
3143
|
styleResolver
|
|
2954
3144
|
});
|
|
3145
|
+
else if (contentNode.type.name === "preservedBlock") {
|
|
3146
|
+
content.push({
|
|
3147
|
+
type: "preservedBlock",
|
|
3148
|
+
xml: expectPreservedBlockAttrs(contentNode).xml
|
|
3149
|
+
});
|
|
3150
|
+
previousStandaloneTextBox = null;
|
|
3151
|
+
}
|
|
2955
3152
|
});
|
|
2956
3153
|
removeUnresolvedTextBoxAnchors(content, textBoxAnchorMarkers);
|
|
2957
3154
|
const cell = {
|
|
@@ -3086,7 +3283,7 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
3086
3283
|
if (attrs.textBoxName !== void 0) shape.name = attrs.textBoxName;
|
|
3087
3284
|
if (attrs.alt !== void 0) shape.alt = attrs.alt;
|
|
3088
3285
|
if (attrs.title !== void 0) shape.title = attrs.title;
|
|
3089
|
-
const transform =
|
|
3286
|
+
const transform = readAuthoredTransform(attrs);
|
|
3090
3287
|
if (transform) shape.transform = transform;
|
|
3091
3288
|
if (attrs.fillColor) shape.fill = {
|
|
3092
3289
|
type: "solid",
|
|
@@ -3156,8 +3353,10 @@ function updateDocumentContent(originalDocument, pmDoc) {
|
|
|
3156
3353
|
* Used for converting edited header/footer PM content back to the document
|
|
3157
3354
|
* model.
|
|
3158
3355
|
*/
|
|
3159
|
-
function proseDocToBlocks(pmDoc, baseContent, styles
|
|
3160
|
-
const blocks = extractBlocks(pmDoc, "resolve", styles ? createStyleEngine(styles) : null
|
|
3356
|
+
function proseDocToBlocks(pmDoc, baseContent, styles) {
|
|
3357
|
+
const blocks = extractBlocks(pmDoc, "resolve", styles ? createStyleEngine(styles) : null);
|
|
3358
|
+
joinCommentRangesAcrossParagraphs(blocks);
|
|
3359
|
+
completeCommentReferences(blocks);
|
|
3161
3360
|
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
3162
3361
|
if (baseContent) restoreParagraphPropertySources(blocks, baseContent, linkedSources.targets, linkedSources.sources);
|
|
3163
3362
|
return blocks;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fromProseDoc, proseDocToBlocks, updateDocumentContent } from "./fromProseDoc.js";
|
|
2
2
|
import { ToProseDocOptions, createEmptyDoc, headerFooterToProseDoc, toProseDoc } from "./toProseDoc.js";
|
|
3
3
|
import { ProseMirrorDocumentValidationIssue, ValidateProseMirrorDocumentResult, assertValidProseMirrorDocument, formatProseMirrorDocumentIssues, validateProseMirrorDocument } from "../validation.js";
|
|
4
|
-
export { type
|
|
4
|
+
export { type ProseMirrorDocumentValidationIssue, type ToProseDocOptions, type ValidateProseMirrorDocumentResult, assertValidProseMirrorDocument, createEmptyDoc, formatProseMirrorDocumentIssues, fromProseDoc, headerFooterToProseDoc, proseDocToBlocks, toProseDoc, updateDocumentContent, validateProseMirrorDocument };
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import { document_d_exports } from "../../types/document.js";
|
|
2
2
|
import { StyleEngine } from "../../style-engine/styleEngine.js";
|
|
3
3
|
import "../../style-engine/index.js";
|
|
4
|
+
import { ParseContext } from "../../docx/parseContext.js";
|
|
4
5
|
import { Node } from "prosemirror-model";
|
|
5
6
|
//#region src/prosemirror/conversion/toProseDoc.d.ts
|
|
6
|
-
type UnsupportedDocxToProseMirrorOwner = "complex-field-instruction" | "field-result" | "page-break-bearing-run" | "paragraph-borders" | "paragraph-frame" | "paragraph-outline" | "paragraph-text-box-anchor" | "table-cell" | "text-box";
|
|
7
|
-
declare const UnsupportedDocxToProseMirrorConversionError_base: import("better-result").TaggedErrorClass<"UnsupportedDocxToProseMirrorConversionError">;
|
|
8
|
-
/** DOCX content that cannot be preserved by the editable ProseMirror model. */
|
|
9
|
-
declare class UnsupportedDocxToProseMirrorConversionError extends UnsupportedDocxToProseMirrorConversionError_base<{
|
|
10
|
-
message: string;
|
|
11
|
-
owner: UnsupportedDocxToProseMirrorOwner;
|
|
12
|
-
contentType: document_d_exports.RunContent["type"];
|
|
13
|
-
}> {}
|
|
14
7
|
/**
|
|
15
8
|
* Options for document conversion
|
|
16
9
|
*/
|
|
@@ -19,6 +12,11 @@ type ToProseDocOptions = {
|
|
|
19
12
|
styles?: document_d_exports.StyleDefinitions;
|
|
20
13
|
/** Theme used when converting themed table/cell values in nested content. */
|
|
21
14
|
theme?: document_d_exports.Theme | null;
|
|
15
|
+
/**
|
|
16
|
+
* Where a projection approximation is reported, on the channel the parsers
|
|
17
|
+
* already use. Absent means nobody is listening, not that nothing happened.
|
|
18
|
+
*/
|
|
19
|
+
warn?: ParseContext["warn"];
|
|
22
20
|
};
|
|
23
21
|
/**
|
|
24
22
|
* Convert a Document to a ProseMirror document
|
|
@@ -53,4 +51,4 @@ declare function footnoteToProseDoc(content: document_d_exports.BlockContent[],
|
|
|
53
51
|
*/
|
|
54
52
|
declare function createEmptyDoc(): Node;
|
|
55
53
|
//#endregion
|
|
56
|
-
export { ToProseDocOptions,
|
|
54
|
+
export { ToProseDocOptions, createEmptyDoc, footnoteToProseDoc, headerFooterToProseDoc, resolveParagraphDefaultTextFormatting, standaloneTableCellToProseMirror, toProseDoc };
|