@stll/folio-core 0.47.4 → 0.47.6
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/compare/inline-atoms.js +218 -31
- package/dist/compare/section-boundary-properties.js +1 -0
- package/dist/content-controls/mutateContentControls.js +1 -3
- package/dist/controller/headerFooterEditorManager.d.ts +2 -1
- package/dist/controller/headerFooterEditorManager.js +2 -1
- package/dist/controller/noteEditorManager.d.ts +2 -1
- package/dist/controller/noteEditorManager.js +2 -1
- package/dist/docx/commentRangeIntegrity.js +7 -0
- package/dist/docx/documentParser.js +55 -3
- package/dist/docx/inlineWrapperContent.d.ts +18 -16
- package/dist/docx/inlineWrapperContent.js +18 -16
- package/dist/docx/normalizeBaseDirection.js +4 -0
- package/dist/docx/rezip.js +1 -0
- package/dist/docx/selectiveSave.js +11 -2
- package/dist/docx/serializer/documentSerializer.js +16 -1
- package/dist/docx/serializer/paragraphSerializer.js +8 -0
- package/dist/docx/serializer/tableSerializer.js +5 -2
- package/dist/docx/server/createBilingualDocument.js +23 -14
- package/dist/docx/tableParser.js +101 -75
- package/dist/markdown/renderRuns.js +4 -0
- package/dist/markdown/renderTable.js +46 -12
- package/dist/prosemirror/attrs/index.d.ts +3 -2
- package/dist/prosemirror/attrs/index.js +85 -4
- package/dist/prosemirror/commands/comments.js +61 -3
- package/dist/prosemirror/commentReferenceAttrs.js +2 -2
- package/dist/prosemirror/commentReferenceIntegrity.d.ts +7 -3
- package/dist/prosemirror/commentReferenceIntegrity.js +9 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +177 -51
- package/dist/prosemirror/conversion/toProseDoc.js +108 -55
- package/dist/prosemirror/extensions/markRegistry.d.ts +5 -8
- package/dist/prosemirror/extensions/markRegistry.js +5 -8
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +13 -6
- package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +24 -6
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +2 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +32 -7
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +9 -5
- package/dist/prosemirror/extensions/nodes/TableExtension.js +2 -2
- package/dist/prosemirror/runIdentity.d.ts +5 -5
- package/dist/prosemirror/runIdentity.js +5 -5
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +28 -2
- package/dist/prosemirror/schema/nodes.d.ts +6 -4
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
- package/dist/prosemirror/utils/extractTrackedChanges.js +21 -6
- package/dist/prosemirror/validation.js +48 -7
- package/dist/types/content.d.ts +2 -2
- package/dist/types/index.d.ts +3 -1
- package/dist/utils/mergeDocumentContent.js +1 -7
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, InlineWrapperAttrs, InlineWrapperLayer, LanguageAttrs, RunFormattingOverrideAttrs, RunIdentityMarkAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "../schema/marks.js";
|
|
1
|
+
import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, InlineWrapperAttrs, InlineWrapperLayer, LanguageAttrs, RunFormattingOverrideAttrs, RunIdentityMarkAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, TrackedRevisionAncestor, UnderlineAttrs } from "../schema/marks.js";
|
|
2
2
|
import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, PreservedBlockAttrs, PreservedXmlAttrs, SdtAttrs, ShapeAttrs, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "../schema/nodes.js";
|
|
3
3
|
import "../schema/index.js";
|
|
4
4
|
import { Mark, Node } from "prosemirror-model";
|
|
@@ -76,6 +76,7 @@ declare const readFootnoteRefMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResu
|
|
|
76
76
|
declare const expectFootnoteRefMarkAttrs: (mark: Mark) => FootnoteRefAttrs;
|
|
77
77
|
declare const readCommentMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<CommentAttrs>;
|
|
78
78
|
declare const expectCommentMarkAttrs: (mark: Mark) => CommentAttrs;
|
|
79
|
+
declare const isTrackedRevisionAncestorArray: (value: unknown) => value is readonly TrackedRevisionAncestor[];
|
|
79
80
|
declare const readTrackedChangeMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<TrackedChangeMarkAttrs>;
|
|
80
81
|
declare const expectTrackedChangeMarkAttrs: (mark: Mark) => TrackedChangeMarkAttrs;
|
|
81
82
|
declare const readRunPropertyChangeMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<RunPropertyChangeMarkAttrs>;
|
|
@@ -118,4 +119,4 @@ declare const mergeTableRowAttrs: (node: Node, patch: NodeAttrPatch<TableRowAttr
|
|
|
118
119
|
*/
|
|
119
120
|
declare const mergeTableCellAttrs: (node: Node, patch: NodeAttrPatch<TableCellAttrs>) => TableCellAttrs;
|
|
120
121
|
//#endregion
|
|
121
|
-
export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, 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, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readInlineWrapperStack, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunIdentityMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
|
|
122
|
+
export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, 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, isTrackedRevisionAncestorArray, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readInlineWrapperStack, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunIdentityMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
|
|
@@ -82,6 +82,12 @@ const NOTE_TYPES = ["footnote", "endnote"];
|
|
|
82
82
|
const NOTE_REF_VERT_ALIGNS = ["baseline", "superscript"];
|
|
83
83
|
const TEXT_BOX_DOCX_PLACEMENTS = ["standalone", "inlineWithPrevious"];
|
|
84
84
|
const TRACKED_CHANGE_MOVE_KINDS = ["moveTo", "moveFrom"];
|
|
85
|
+
const TRACKED_REVISION_ANCESTOR_TYPES = [
|
|
86
|
+
"insertion",
|
|
87
|
+
"deletion",
|
|
88
|
+
"moveFrom",
|
|
89
|
+
"moveTo"
|
|
90
|
+
];
|
|
85
91
|
const TEXT_BOX_TRACKED_CHANGE_TYPES = [
|
|
86
92
|
"insertion",
|
|
87
93
|
"deletion",
|
|
@@ -792,6 +798,7 @@ const readCommentMarkAttrs = (mark) => {
|
|
|
792
798
|
return attrsResult(attrs, issues);
|
|
793
799
|
};
|
|
794
800
|
const expectCommentMarkAttrs = (mark) => expectCachedMarkAttrs(mark, commentAttrsCache, readCommentMarkAttrs, "comment attrs");
|
|
801
|
+
const isTrackedRevisionAncestorArray = (value) => Array.isArray(value) && value.length > 0 && value.every((ancestor) => isRecord(ancestor) && TRACKED_REVISION_ANCESTOR_TYPES.some((type) => type === ancestor["type"]) && typeof ancestor["revisionId"] === "number" && Number.isSafeInteger(ancestor["revisionId"]) && ancestor["revisionId"] >= 0 && typeof ancestor["author"] === "string" && (ancestor["date"] === void 0 || typeof ancestor["date"] === "string") && (ancestor["utcDate"] === void 0 || typeof ancestor["utcDate"] === "string") && (ancestor["initials"] === void 0 || typeof ancestor["initials"] === "string") && typeof ancestor["outerWrapperCount"] === "number" && Number.isSafeInteger(ancestor["outerWrapperCount"]) && ancestor["outerWrapperCount"] >= 0);
|
|
795
802
|
const readTrackedChangeMarkAttrs = (mark) => {
|
|
796
803
|
const attrs = attrsRecord(mark.attrs);
|
|
797
804
|
const issues = [];
|
|
@@ -801,6 +808,16 @@ const readTrackedChangeMarkAttrs = (mark) => {
|
|
|
801
808
|
optionalString(attrs, "date", `${mark.type.name}.attrs.date`, issues);
|
|
802
809
|
optionalString(attrs, "utcDate", `${mark.type.name}.attrs.utcDate`, issues);
|
|
803
810
|
optionalString(attrs, "initials", `${mark.type.name}.attrs.initials`, issues);
|
|
811
|
+
const outerWrapperCount = attrs["_docxOuterWrapperCount"];
|
|
812
|
+
if (outerWrapperCount !== void 0 && outerWrapperCount !== null && (typeof outerWrapperCount !== "number" || !Number.isSafeInteger(outerWrapperCount) || outerWrapperCount < 0)) issues.push({
|
|
813
|
+
path: `${mark.type.name}.attrs._docxOuterWrapperCount`,
|
|
814
|
+
message: "Expected a non-negative safe integer."
|
|
815
|
+
});
|
|
816
|
+
const ancestors = attrs["_docxRevisionAncestors"];
|
|
817
|
+
if (ancestors !== void 0 && ancestors !== null && !isTrackedRevisionAncestorArray(ancestors)) issues.push({
|
|
818
|
+
path: `${mark.type.name}.attrs._docxRevisionAncestors`,
|
|
819
|
+
message: "Expected a non-empty array of valid revision ancestors."
|
|
820
|
+
});
|
|
804
821
|
optionalOneOf(attrs, "moveKind", `${mark.type.name}.attrs.moveKind`, issues, TRACKED_CHANGE_MOVE_KINDS);
|
|
805
822
|
optionalOneOf(attrs, "provenance", `${mark.type.name}.attrs.provenance`, issues, TRACKED_CHANGE_PROVENANCE_VALUES);
|
|
806
823
|
optionalString(attrs, "suggestionId", `${mark.type.name}.attrs.suggestionId`, issues);
|
|
@@ -868,6 +885,11 @@ const taggedLayerValidator = (label) => (layer, path, issues) => {
|
|
|
868
885
|
path: `${path}.${key}`,
|
|
869
886
|
message: "Expected a string."
|
|
870
887
|
});
|
|
888
|
+
const propertiesXml = layer["propertiesXml"];
|
|
889
|
+
if (typeof propertiesXml === "string" && !isSafePreservedChildXml(propertiesXml)) issues.push({
|
|
890
|
+
path: `${path}.propertiesXml`,
|
|
891
|
+
message: "Expected one bounded, well-formed XML element."
|
|
892
|
+
});
|
|
871
893
|
for (const key of Object.keys(layer)) if (!TAGGED_LAYER_KEYS.has(key)) issues.push({
|
|
872
894
|
path: `${path}.${key}`,
|
|
873
895
|
message: `Unexpected ${label} wrapper property.`
|
|
@@ -894,6 +916,19 @@ const INLINE_WRAPPER_LAYER_VALIDATORS = {
|
|
|
894
916
|
const inlineWrapperLayerValidator = (kind) => {
|
|
895
917
|
return typeof kind === "string" ? INLINE_WRAPPER_LAYER_VALIDATORS[kind] : void 0;
|
|
896
918
|
};
|
|
919
|
+
const inlineWrapperProperties = function* (layers) {
|
|
920
|
+
for (let index = 0; index < layers.length; index += 1) {
|
|
921
|
+
const layer = layers[index];
|
|
922
|
+
yield { xml: isRecord(layer) && typeof layer["propertiesXml"] === "string" ? layer["propertiesXml"] : "" };
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
const emptyHyperlinkWrapperProperties = function* (stacks) {
|
|
926
|
+
for (let stackIndex = 0; stackIndex < stacks.length; stackIndex += 1) {
|
|
927
|
+
const stack = stacks[stackIndex];
|
|
928
|
+
yield {};
|
|
929
|
+
if (Array.isArray(stack)) yield* inlineWrapperProperties(stack);
|
|
930
|
+
}
|
|
931
|
+
};
|
|
897
932
|
const validateInlineWrapperStack = (value, path, issues) => {
|
|
898
933
|
if (!Array.isArray(value)) {
|
|
899
934
|
issues.push({
|
|
@@ -909,6 +944,13 @@ const validateInlineWrapperStack = (value, path, issues) => {
|
|
|
909
944
|
});
|
|
910
945
|
return;
|
|
911
946
|
}
|
|
947
|
+
if (!isWithinPreservedMarkupBudget(inlineWrapperProperties(value))) {
|
|
948
|
+
issues.push({
|
|
949
|
+
path,
|
|
950
|
+
message: "Inline wrapper stack exceeds its resource budget."
|
|
951
|
+
});
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
912
954
|
for (const [index, layer] of value.entries()) {
|
|
913
955
|
const layerPath = `${path}[${index}]`;
|
|
914
956
|
if (!isRecord(layer)) {
|
|
@@ -950,6 +992,22 @@ const readInlineWrapperMarkAttrs = (mark) => {
|
|
|
950
992
|
const issues = [];
|
|
951
993
|
expectMarkType(mark, "inlineWrapper", issues);
|
|
952
994
|
validateInlineWrapperStack(attrs["stack"], "inlineWrapper.attrs.stack", issues);
|
|
995
|
+
const hyperlinkIndex = attrs["_docxHyperlinkIndex"];
|
|
996
|
+
const stackStart = attrs["_docxInsideHyperlinkStackStart"];
|
|
997
|
+
const hasHyperlinkIndex = hyperlinkIndex !== void 0 && hyperlinkIndex !== null;
|
|
998
|
+
const hasStackStart = stackStart !== void 0 && stackStart !== null;
|
|
999
|
+
if (hasHyperlinkIndex !== hasStackStart) issues.push({
|
|
1000
|
+
path: "inlineWrapper.attrs",
|
|
1001
|
+
message: "Hyperlink wrapper provenance requires both an index and stack start."
|
|
1002
|
+
});
|
|
1003
|
+
else if (hasHyperlinkIndex && hasStackStart) {
|
|
1004
|
+
validateNonNegativeInteger(hyperlinkIndex, "inlineWrapper.attrs._docxHyperlinkIndex", issues);
|
|
1005
|
+
validateNonNegativeInteger(stackStart, "inlineWrapper.attrs._docxInsideHyperlinkStackStart", issues);
|
|
1006
|
+
if (typeof stackStart === "number" && Array.isArray(attrs["stack"]) && stackStart >= attrs["stack"].length) issues.push({
|
|
1007
|
+
path: "inlineWrapper.attrs._docxInsideHyperlinkStackStart",
|
|
1008
|
+
message: "Expected a stack position inside the wrapper stack."
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
953
1011
|
return attrsResult(attrs, issues);
|
|
954
1012
|
};
|
|
955
1013
|
const expectInlineWrapperMarkAttrs = (mark) => expectCachedMarkAttrs(mark, inlineWrapperAttrsCache, readInlineWrapperMarkAttrs, "inline wrapper attrs");
|
|
@@ -1745,7 +1803,7 @@ const optionalPositionedBookmarks = (attrs, path, issues) => {
|
|
|
1745
1803
|
});
|
|
1746
1804
|
continue;
|
|
1747
1805
|
}
|
|
1748
|
-
|
|
1806
|
+
validateNonNegativeSafeInteger(entry["index"], `${entryPath}.index`, issues);
|
|
1749
1807
|
const marker = entry["marker"];
|
|
1750
1808
|
if (!isRecord(marker)) {
|
|
1751
1809
|
issues.push({
|
|
@@ -1762,7 +1820,7 @@ const optionalPositionedBookmarks = (attrs, path, issues) => {
|
|
|
1762
1820
|
});
|
|
1763
1821
|
continue;
|
|
1764
1822
|
}
|
|
1765
|
-
|
|
1823
|
+
validateNonNegativeSafeInteger(marker["id"], `${entryPath}.marker.id`, issues);
|
|
1766
1824
|
if (type === "bookmarkStart") requiredString(marker, "name", `${entryPath}.marker.name`, issues);
|
|
1767
1825
|
optionalContentControls(entry, `${entryPath}.contentControls`, issues);
|
|
1768
1826
|
}
|
|
@@ -2574,11 +2632,17 @@ const validateNonNegativeInteger = (value, path, issues) => {
|
|
|
2574
2632
|
});
|
|
2575
2633
|
return;
|
|
2576
2634
|
}
|
|
2577
|
-
if (!Number.
|
|
2635
|
+
if (!Number.isSafeInteger(value) || value < 0) issues.push({
|
|
2578
2636
|
path,
|
|
2579
2637
|
message: "Expected a non-negative integer."
|
|
2580
2638
|
});
|
|
2581
2639
|
};
|
|
2640
|
+
const validateNonNegativeSafeInteger = (value, path, issues) => {
|
|
2641
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) issues.push({
|
|
2642
|
+
path,
|
|
2643
|
+
message: "Expected a non-negative safe integer."
|
|
2644
|
+
});
|
|
2645
|
+
};
|
|
2582
2646
|
const optionalBookmarkArray = (value, issues) => {
|
|
2583
2647
|
if (value === void 0 || value === null) return;
|
|
2584
2648
|
if (!Array.isArray(value)) {
|
|
@@ -2633,7 +2697,24 @@ const optionalEmptyHyperlinkArray = (value, issues) => {
|
|
|
2633
2697
|
optionalString(item, "target", `${itemPath}.target`, issues);
|
|
2634
2698
|
optionalBoolean(item, "history", `${itemPath}.history`, issues);
|
|
2635
2699
|
optionalString(item, "docLocation", `${itemPath}.docLocation`, issues);
|
|
2700
|
+
const wrapperStacks = item["_docxEmptyWrapperStacks"];
|
|
2701
|
+
if (wrapperStacks === void 0 || wrapperStacks === null) continue;
|
|
2702
|
+
if (!Array.isArray(wrapperStacks)) {
|
|
2703
|
+
issues.push({
|
|
2704
|
+
path: `${itemPath}._docxEmptyWrapperStacks`,
|
|
2705
|
+
message: "Expected an array of inline wrapper stacks."
|
|
2706
|
+
});
|
|
2707
|
+
continue;
|
|
2708
|
+
}
|
|
2709
|
+
if (!isWithinPreservedMarkupBudget(emptyHyperlinkWrapperProperties(wrapperStacks))) {
|
|
2710
|
+
issues.push({
|
|
2711
|
+
path: `${itemPath}._docxEmptyWrapperStacks`,
|
|
2712
|
+
message: "Empty inline wrapper stacks exceed their aggregate resource budget."
|
|
2713
|
+
});
|
|
2714
|
+
continue;
|
|
2715
|
+
}
|
|
2716
|
+
for (const [stackIndex, stack] of wrapperStacks.entries()) validateInlineWrapperStack(stack, `${itemPath}._docxEmptyWrapperStacks[${stackIndex}]`, issues);
|
|
2636
2717
|
}
|
|
2637
2718
|
};
|
|
2638
2719
|
//#endregion
|
|
2639
|
-
export { 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, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readInlineWrapperStack, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunIdentityMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
|
|
2720
|
+
export { 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, isTrackedRevisionAncestorArray, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readInlineWrapperStack, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunIdentityMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
|
|
@@ -2,7 +2,7 @@ import { sameStatedParagraphNumbering as sameStatedParagraphNumbering$1 } from "
|
|
|
2
2
|
import { joinProseParagraphsWithRightPropertySource } from "../../docx/paragraphPropertySource.js";
|
|
3
3
|
import { appendHeadlessInlineResolution } from "../../internal/headlessRevisionResolution.js";
|
|
4
4
|
import { stateAllowsHeadlessRevisionResolution } from "../../internal/headlessRevisionResolutionGuard.js";
|
|
5
|
-
import { expectParagraphAttrs, expectRunPropertyChangeMarkAttrs } from "../attrs/index.js";
|
|
5
|
+
import { expectParagraphAttrs, expectRunPropertyChangeMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
|
|
6
6
|
import { addedBreakCarrierBefore, finalParagraphsOf, paragraphEndsItsContainer } from "../containerFinalParagraph.js";
|
|
7
7
|
import { resolveParagraphDefaultTextFormatting } from "../conversion/toProseDoc.js";
|
|
8
8
|
import { markChangedParagraphRanges, markStructuralChange, markTrackedSectionEndpointRemoval } from "../extensions/features/ParagraphChangeTrackerExtension.js";
|
|
@@ -19,6 +19,7 @@ import { reconcileTableGridAfterColumnRemoval } from "../tableGridMutation.js";
|
|
|
19
19
|
import { holdsNoContent } from "../zeroWidthAnchors.js";
|
|
20
20
|
import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties, tableCellRejectAttrPatch, tablePropertyExceptionsRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch } from "./propertyChangeScope.js";
|
|
21
21
|
import { hasMatchingCollapsedTableCellMerge, resolveCollapsedTableCellMerge, resolveVisibleTableCellMerge } from "./tableCellMergeResolution.js";
|
|
22
|
+
import { panic } from "better-result";
|
|
22
23
|
import { PARAGRAPH_MARK_CHANGE_KINDS, REVIEW_CARRIERS } from "@stll/docx-core/model";
|
|
23
24
|
import { TableMap, removeRow } from "prosemirror-tables";
|
|
24
25
|
import { Mapping } from "prosemirror-transform";
|
|
@@ -55,6 +56,33 @@ function removeCommentMark(commentId) {
|
|
|
55
56
|
return true;
|
|
56
57
|
};
|
|
57
58
|
}
|
|
59
|
+
const revisionLayerOf = (mark) => {
|
|
60
|
+
const attrs = expectTrackedChangeMarkAttrs(mark);
|
|
61
|
+
let type;
|
|
62
|
+
if (mark.type.name === "insertion") type = attrs.moveKind === "moveTo" ? "moveTo" : "insertion";
|
|
63
|
+
else type = attrs.moveKind === "moveFrom" ? "moveFrom" : "deletion";
|
|
64
|
+
return {
|
|
65
|
+
type,
|
|
66
|
+
revisionId: attrs.revisionId,
|
|
67
|
+
author: attrs.author,
|
|
68
|
+
...attrs.date ? { date: attrs.date } : {},
|
|
69
|
+
...attrs.utcDate ? { utcDate: attrs.utcDate } : {},
|
|
70
|
+
...attrs.initials ? { initials: attrs.initials } : {},
|
|
71
|
+
outerWrapperCount: attrs._docxOuterWrapperCount ?? 0
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const revisionLayerRemovesContent = (layer, mode) => mode === "accept" ? layer.type === "deletion" || layer.type === "moveFrom" : layer.type === "insertion" || layer.type === "moveTo";
|
|
75
|
+
const containsNestedRevision = (doc) => {
|
|
76
|
+
let found = false;
|
|
77
|
+
doc.descendants((node) => {
|
|
78
|
+
if (found) return false;
|
|
79
|
+
for (const mark of node.marks) if ((mark.type.name === "insertion" || mark.type.name === "deletion") && (expectTrackedChangeMarkAttrs(mark)._docxRevisionAncestors?.length ?? 0) > 0) {
|
|
80
|
+
found = true;
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return found;
|
|
85
|
+
};
|
|
58
86
|
/**
|
|
59
87
|
* Resolve a tracked change: accept or reject.
|
|
60
88
|
* - Accept: keep insertions (remove mark), delete deletions (remove text)
|
|
@@ -76,7 +104,7 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
|
|
|
76
104
|
const removeType = mode === "accept" ? deletionType : insertionType;
|
|
77
105
|
const revisionSet = revisionIds === void 0 ? null : new Set(revisionIds);
|
|
78
106
|
const removeKeptMarksInBulk = revisionSet === null && keepType !== void 0;
|
|
79
|
-
const canBulkInlineResolution = execution === "headless-bulk-inline" && revisionSet === null && from === 0 && to === state.doc.content.size && stateAllowsHeadlessRevisionResolution(state);
|
|
107
|
+
const canBulkInlineResolution = execution === "headless-bulk-inline" && revisionSet === null && from === 0 && to === state.doc.content.size && stateAllowsHeadlessRevisionResolution(state) && !containsNestedRevision(state.doc);
|
|
80
108
|
const matchesRevision = (mark) => revisionSet === null || typeof mark.attrs["revisionId"] === "number" && revisionSet.has(mark.attrs["revisionId"]);
|
|
81
109
|
if (dispatch) {
|
|
82
110
|
const tr = state.tr;
|
|
@@ -189,6 +217,36 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
|
|
|
189
217
|
revisionSet,
|
|
190
218
|
styleResolver
|
|
191
219
|
});
|
|
220
|
+
const nestedMark = node.marks.find((mark) => (mark.type === insertionType || mark.type === deletionType) && (expectTrackedChangeMarkAttrs(mark)._docxRevisionAncestors?.length ?? 0) > 0);
|
|
221
|
+
if (nestedMark) {
|
|
222
|
+
const path = [...expectTrackedChangeMarkAttrs(nestedMark)._docxRevisionAncestors ?? [], revisionLayerOf(nestedMark)];
|
|
223
|
+
const selected = (layer) => revisionSet === null || revisionSet.has(layer.revisionId);
|
|
224
|
+
if (path.some(selected)) if (path.some((layer) => selected(layer) && revisionLayerRemovesContent(layer, mode))) deleteRanges.push({
|
|
225
|
+
from: rangeFrom,
|
|
226
|
+
to: rangeTo
|
|
227
|
+
});
|
|
228
|
+
else {
|
|
229
|
+
tr.removeMark(rangeFrom, rangeTo, nestedMark);
|
|
230
|
+
const remaining = path.filter((layer) => !selected(layer));
|
|
231
|
+
const active = remaining.at(-1);
|
|
232
|
+
if (active) {
|
|
233
|
+
const type = active.type === "insertion" || active.type === "moveTo" ? insertionType : deletionType;
|
|
234
|
+
if (!type) panic("A nested tracked revision has no editor mark type");
|
|
235
|
+
tr.addMark(rangeFrom, rangeTo, type.create({
|
|
236
|
+
revisionId: active.revisionId,
|
|
237
|
+
author: active.author,
|
|
238
|
+
date: active.date ?? null,
|
|
239
|
+
utcDate: active.utcDate ?? null,
|
|
240
|
+
initials: active.initials ?? null,
|
|
241
|
+
moveKind: active.type === "moveTo" || active.type === "moveFrom" ? active.type : null,
|
|
242
|
+
_historicalFormatting: active.type === "deletion" || active.type === "moveFrom" ? true : null,
|
|
243
|
+
_docxOuterWrapperCount: active.outerWrapperCount,
|
|
244
|
+
_docxRevisionAncestors: remaining.length > 1 ? remaining.slice(0, -1) : null
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
192
250
|
if (removesNode) deleteRanges.push({
|
|
193
251
|
from: rangeFrom,
|
|
194
252
|
to: rangeTo
|
|
@@ -794,7 +852,7 @@ function findAIEditRevisionRange(state, revisionIds) {
|
|
|
794
852
|
includeRange(pos, pos + node.nodeSize);
|
|
795
853
|
break;
|
|
796
854
|
}
|
|
797
|
-
if ((mark.type === insertionType || mark.type === deletionType) &&
|
|
855
|
+
if ((mark.type === insertionType || mark.type === deletionType) && (idSet.has(expectTrackedChangeMarkAttrs(mark).revisionId) || (expectTrackedChangeMarkAttrs(mark)._docxRevisionAncestors ?? []).some((ancestor) => idSet.has(ancestor.revisionId)))) {
|
|
798
856
|
includeRange(pos, pos + node.nodeSize);
|
|
799
857
|
break;
|
|
800
858
|
}
|
|
@@ -8,9 +8,9 @@ const readCommentReferenceAttrs = (node) => {
|
|
|
8
8
|
message: `Expected commentReference, got ${node.type.name}.`
|
|
9
9
|
});
|
|
10
10
|
const commentId = node.attrs["commentId"];
|
|
11
|
-
if (typeof commentId !== "number" || !Number.
|
|
11
|
+
if (typeof commentId !== "number" || !Number.isSafeInteger(commentId)) issues.push({
|
|
12
12
|
path: "commentReference.attrs.commentId",
|
|
13
|
-
message: "Expected a
|
|
13
|
+
message: "Expected a safe integer."
|
|
14
14
|
});
|
|
15
15
|
if (issues.length > 0 || typeof commentId !== "number") return {
|
|
16
16
|
ok: false,
|
|
@@ -10,13 +10,17 @@
|
|
|
10
10
|
* a comment mark creates none — so the repair is computed here and applied by
|
|
11
11
|
* the extension's `appendTransaction`, rather than left to each call site.
|
|
12
12
|
*/
|
|
13
|
-
type
|
|
14
|
-
commentId: number;
|
|
13
|
+
type PositionedReference = {
|
|
15
14
|
position: number;
|
|
16
15
|
/** Node size, so a caller can delete the node without re-reading it. */
|
|
17
16
|
size: number;
|
|
18
|
-
malformed: boolean;
|
|
19
17
|
};
|
|
18
|
+
type CommentReferenceOccurrence = (PositionedReference & {
|
|
19
|
+
status: "valid";
|
|
20
|
+
commentId: number;
|
|
21
|
+
}) | (PositionedReference & {
|
|
22
|
+
status: "malformed";
|
|
23
|
+
});
|
|
20
24
|
/** Where a comment's mark last covers content, and how far that content runs. */
|
|
21
25
|
type CommentMarkExtent = {
|
|
22
26
|
commentId: number;
|
|
@@ -10,7 +10,15 @@ const planCommentReferenceRepairs = ({ references, markExtents }) => {
|
|
|
10
10
|
const deletions = [];
|
|
11
11
|
const keptIds = /* @__PURE__ */ new Set();
|
|
12
12
|
for (const reference of references) {
|
|
13
|
-
if (reference.
|
|
13
|
+
if (reference.status === "malformed") {
|
|
14
|
+
deletions.push({
|
|
15
|
+
type: "delete",
|
|
16
|
+
position: reference.position,
|
|
17
|
+
size: reference.size
|
|
18
|
+
});
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (!markedIds.has(reference.commentId)) {
|
|
14
22
|
deletions.push({
|
|
15
23
|
type: "delete",
|
|
16
24
|
position: reference.position,
|