@stll/folio-core 0.47.5 → 0.47.7
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/word-diff.d.ts +25 -6
- package/dist/ai-edits/word-diff.js +210 -38
- 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/relsParser.js +9 -1
- package/dist/docx/selectiveSave.js +11 -2
- package/dist/prosemirror/attrs/index.d.ts +3 -2
- package/dist/prosemirror/attrs/index.js +18 -1
- package/dist/prosemirror/commands/comments.js +61 -3
- package/dist/prosemirror/conversion/fromProseDoc.js +107 -37
- package/dist/prosemirror/conversion/toProseDoc.js +33 -13
- package/dist/prosemirror/extensions/markRegistry.d.ts +5 -8
- package/dist/prosemirror/extensions/markRegistry.js +5 -8
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +2 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +32 -7
- 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 +17 -2
- package/dist/prosemirror/utils/extractTrackedChanges.js +21 -6
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AUTHOR_COLORS, getAuthorColorIdx } from "../../../utils/authorColors.js";
|
|
2
|
-
import { expectTrackedChangeMarkAttrs } from "../../attrs/index.js";
|
|
2
|
+
import { expectTrackedChangeMarkAttrs, isTrackedRevisionAncestorArray } from "../../attrs/index.js";
|
|
3
3
|
import { createMarkExtension } from "../create.js";
|
|
4
4
|
//#region src/prosemirror/extensions/marks/TrackedChangeExtensions.ts
|
|
5
5
|
/**
|
|
@@ -31,6 +31,15 @@ const SUGGESTION_TINT = "var(--suggestion-bg, color-mix(in oklch, #6d3bd6 12%, t
|
|
|
31
31
|
const SUGGESTION_TINT_LAYER = `linear-gradient(${SUGGESTION_TINT}, ${SUGGESTION_TINT})`;
|
|
32
32
|
const suggestedInsertionStyle = () => `color: ${SUGGESTION_COLOR}; text-decoration: underline; text-decoration-style: dotted; text-decoration-color: ${SUGGESTION_COLOR}; background-image: ${SUGGESTION_TINT_LAYER};`;
|
|
33
33
|
const suggestedDeletionStyle = () => `color: ${SUGGESTION_COLOR}; text-decoration: line-through; text-decoration-style: dotted; text-decoration-color: ${SUGGESTION_COLOR}; background-image: ${SUGGESTION_TINT_LAYER};`;
|
|
34
|
+
const revisionAncestorsFromDom = (serialized) => {
|
|
35
|
+
if (serialized === void 0) return null;
|
|
36
|
+
try {
|
|
37
|
+
const value = JSON.parse(serialized);
|
|
38
|
+
return isTrackedRevisionAncestorArray(value) ? value : false;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
34
43
|
/**
|
|
35
44
|
* Insertion mark — text added in tracked changes
|
|
36
45
|
* Renders with per-author colored underline.
|
|
@@ -47,21 +56,27 @@ const InsertionExtension = createMarkExtension({
|
|
|
47
56
|
moveKind: { default: null },
|
|
48
57
|
initials: { default: null },
|
|
49
58
|
provenance: { default: "user" },
|
|
50
|
-
suggestionId: { default: null }
|
|
59
|
+
suggestionId: { default: null },
|
|
60
|
+
_docxOuterWrapperCount: { default: null },
|
|
61
|
+
_docxRevisionAncestors: { default: null }
|
|
51
62
|
},
|
|
52
63
|
inclusive: false,
|
|
53
64
|
parseDOM: [{
|
|
54
65
|
tag: "span.docx-insertion",
|
|
55
66
|
getAttrs(dom) {
|
|
67
|
+
const ancestors = revisionAncestorsFromDom(dom.dataset["revisionAncestors"]);
|
|
68
|
+
if (ancestors === false) return false;
|
|
56
69
|
return {
|
|
57
70
|
revisionId: Number.parseInt(dom.dataset["revisionId"] ?? "0", 10),
|
|
58
71
|
author: dom.dataset["author"] ?? "",
|
|
59
|
-
date: dom.dataset["date"] ?? null
|
|
72
|
+
date: dom.dataset["date"] ?? null,
|
|
73
|
+
_docxOuterWrapperCount: dom.dataset["outerWrapperCount"] ? Number(dom.dataset["outerWrapperCount"]) : null,
|
|
74
|
+
_docxRevisionAncestors: ancestors
|
|
60
75
|
};
|
|
61
76
|
}
|
|
62
77
|
}],
|
|
63
78
|
toDOM(mark) {
|
|
64
|
-
const { revisionId, author, date, provenance, suggestionId } = expectTrackedChangeMarkAttrs(mark);
|
|
79
|
+
const { revisionId, author, date, provenance, suggestionId, _docxOuterWrapperCount, _docxRevisionAncestors } = expectTrackedChangeMarkAttrs(mark);
|
|
65
80
|
const idx = getAuthorColorIdx(author);
|
|
66
81
|
const color = AUTHOR_COLORS[idx] ?? "#000000";
|
|
67
82
|
const titleParts = [author, date ? new Date(date).toLocaleDateString() : ""].filter(Boolean);
|
|
@@ -76,6 +91,8 @@ const InsertionExtension = createMarkExtension({
|
|
|
76
91
|
...suggested ? { "data-provenance": "suggested" } : {},
|
|
77
92
|
...suggested && suggestionId ? { "data-suggestion-id": suggestionId } : {},
|
|
78
93
|
...date ? { "data-date": date } : {},
|
|
94
|
+
..._docxOuterWrapperCount != null ? { "data-outer-wrapper-count": String(_docxOuterWrapperCount) } : {},
|
|
95
|
+
..._docxRevisionAncestors ? { "data-revision-ancestors": JSON.stringify(_docxRevisionAncestors) } : {},
|
|
79
96
|
...titleParts.length > 0 ? { title: `${suggested ? "Suggested" : "Inserted"}: ${titleParts.join(", ")}` } : {},
|
|
80
97
|
style: suggested ? suggestedInsertionStyle() : insertionStyle(color)
|
|
81
98
|
},
|
|
@@ -101,21 +118,27 @@ const DeletionExtension = createMarkExtension({
|
|
|
101
118
|
initials: { default: null },
|
|
102
119
|
provenance: { default: "user" },
|
|
103
120
|
suggestionId: { default: null },
|
|
104
|
-
_historicalFormatting: { default: null }
|
|
121
|
+
_historicalFormatting: { default: null },
|
|
122
|
+
_docxOuterWrapperCount: { default: null },
|
|
123
|
+
_docxRevisionAncestors: { default: null }
|
|
105
124
|
},
|
|
106
125
|
inclusive: false,
|
|
107
126
|
parseDOM: [{
|
|
108
127
|
tag: "span.docx-deletion",
|
|
109
128
|
getAttrs(dom) {
|
|
129
|
+
const ancestors = revisionAncestorsFromDom(dom.dataset["revisionAncestors"]);
|
|
130
|
+
if (ancestors === false) return false;
|
|
110
131
|
return {
|
|
111
132
|
revisionId: Number.parseInt(dom.dataset["revisionId"] ?? "0", 10),
|
|
112
133
|
author: dom.dataset["author"] ?? "",
|
|
113
|
-
date: dom.dataset["date"] ?? null
|
|
134
|
+
date: dom.dataset["date"] ?? null,
|
|
135
|
+
_docxOuterWrapperCount: dom.dataset["outerWrapperCount"] ? Number(dom.dataset["outerWrapperCount"]) : null,
|
|
136
|
+
_docxRevisionAncestors: ancestors
|
|
114
137
|
};
|
|
115
138
|
}
|
|
116
139
|
}],
|
|
117
140
|
toDOM(mark) {
|
|
118
|
-
const { revisionId, author, date, provenance, suggestionId } = expectTrackedChangeMarkAttrs(mark);
|
|
141
|
+
const { revisionId, author, date, provenance, suggestionId, _docxOuterWrapperCount, _docxRevisionAncestors } = expectTrackedChangeMarkAttrs(mark);
|
|
119
142
|
const idx = getAuthorColorIdx(author);
|
|
120
143
|
const color = AUTHOR_COLORS[idx] ?? "#000000";
|
|
121
144
|
const titleParts = [author, date ? new Date(date).toLocaleDateString() : ""].filter(Boolean);
|
|
@@ -130,6 +153,8 @@ const DeletionExtension = createMarkExtension({
|
|
|
130
153
|
...suggested ? { "data-provenance": "suggested" } : {},
|
|
131
154
|
...suggested && suggestionId ? { "data-suggestion-id": suggestionId } : {},
|
|
132
155
|
...date ? { "data-date": date } : {},
|
|
156
|
+
..._docxOuterWrapperCount != null ? { "data-outer-wrapper-count": String(_docxOuterWrapperCount) } : {},
|
|
157
|
+
..._docxRevisionAncestors ? { "data-revision-ancestors": JSON.stringify(_docxRevisionAncestors) } : {},
|
|
133
158
|
...titleParts.length > 0 ? { title: `${suggested ? "Suggested deletion" : "Deleted"}: ${titleParts.join(", ")}` } : {},
|
|
134
159
|
style: suggested ? suggestedDeletionStyle() : deletionStyle(color)
|
|
135
160
|
},
|
|
@@ -13,16 +13,16 @@ declare const RUN_IDENTITY_MARK_NAME = "runIdentity";
|
|
|
13
13
|
type RunIdentityPayload = {
|
|
14
14
|
preservedAttributes?: readonly document_d_exports.PreservedAttribute[] | undefined;
|
|
15
15
|
preserved?: document_d_exports.PreservedMarkup | undefined;
|
|
16
|
+
emptyFormatting?: boolean | undefined;
|
|
16
17
|
};
|
|
17
18
|
/** A run identity's attrs in canonical form. */
|
|
18
|
-
declare const runIdentityAttrs: (id: number, { preservedAttributes, preserved }?: RunIdentityPayload) => RunIdentityMarkAttrs;
|
|
19
|
+
declare const runIdentityAttrs: (id: number, { preservedAttributes, preserved, emptyFormatting }?: RunIdentityPayload) => RunIdentityMarkAttrs;
|
|
19
20
|
/**
|
|
20
21
|
* Whether a run holds markup the mark exists to carry.
|
|
21
22
|
*
|
|
22
|
-
* The
|
|
23
|
-
*
|
|
24
|
-
* of corpus files hold none.
|
|
23
|
+
* The payload condition. The conversion also mints an identity for runs whose
|
|
24
|
+
* page break or mixed inline atoms split one authored run into several leaves.
|
|
25
25
|
*/
|
|
26
|
-
declare const hasRunIdentityPayload: ({ preservedAttributes, preserved }: RunIdentityPayload) => boolean;
|
|
26
|
+
declare const hasRunIdentityPayload: ({ preservedAttributes, preserved, emptyFormatting }: RunIdentityPayload) => boolean;
|
|
27
27
|
//#endregion
|
|
28
28
|
export { RUN_IDENTITY_ATTRIBUTE, RUN_IDENTITY_MARK_NAME, RunIdentityPayload, hasRunIdentityPayload, runIdentityAttrs };
|
|
@@ -18,19 +18,19 @@ const preservedMarkup = ({ children }) => ({ children: (children ?? []).map(({ i
|
|
|
18
18
|
xml
|
|
19
19
|
})) });
|
|
20
20
|
/** A run identity's attrs in canonical form. */
|
|
21
|
-
const runIdentityAttrs = (id, { preservedAttributes, preserved } = {}) => {
|
|
21
|
+
const runIdentityAttrs = (id, { preservedAttributes, preserved, emptyFormatting } = {}) => {
|
|
22
22
|
const attrs = { id };
|
|
23
23
|
if (preservedAttributes && preservedAttributes.length > 0) attrs.preservedAttributes = preservedAttributes.map(preservedAttribute);
|
|
24
24
|
if (preserved && (preserved.children?.length ?? 0) > 0) attrs.preserved = preservedMarkup(preserved);
|
|
25
|
+
if (emptyFormatting) attrs.emptyFormatting = true;
|
|
25
26
|
return attrs;
|
|
26
27
|
};
|
|
27
28
|
/**
|
|
28
29
|
* Whether a run holds markup the mark exists to carry.
|
|
29
30
|
*
|
|
30
|
-
* The
|
|
31
|
-
*
|
|
32
|
-
* of corpus files hold none.
|
|
31
|
+
* The payload condition. The conversion also mints an identity for runs whose
|
|
32
|
+
* page break or mixed inline atoms split one authored run into several leaves.
|
|
33
33
|
*/
|
|
34
|
-
const hasRunIdentityPayload = ({ preservedAttributes, preserved }) => (preservedAttributes?.length ?? 0) > 0 || (preserved?.children?.length ?? 0) > 0;
|
|
34
|
+
const hasRunIdentityPayload = ({ preservedAttributes, preserved, emptyFormatting }) => (preservedAttributes?.length ?? 0) > 0 || (preserved?.children?.length ?? 0) > 0 || emptyFormatting === true;
|
|
35
35
|
//#endregion
|
|
36
36
|
export { RUN_IDENTITY_ATTRIBUTE, RUN_IDENTITY_MARK_NAME, hasRunIdentityPayload, runIdentityAttrs };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, InlineWrapperAttrs, InlineWrapperKind, InlineWrapperLayer, LanguageAttrs, RunFormattingOverrideAttrs, RunIdentityMarkAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "./marks.js";
|
|
1
|
+
import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, InlineWrapperAttrs, InlineWrapperKind, InlineWrapperLayer, LanguageAttrs, RunFormattingOverrideAttrs, RunIdentityMarkAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, TrackedRevisionAncestor, UnderlineAttrs } from "./marks.js";
|
|
2
2
|
import { BlockSdtAttrs, BookmarkBoundaryAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, ParagraphPropertyChangeAttrs, PreservedBlockAttrs, PreservedXmlAttrs, PreservedXmlLevel, SdtAttrs, ShapeAttrs, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "./nodes.js";
|
|
3
3
|
import { ExtensionManager } from "../extensions/ExtensionManager.js";
|
|
4
4
|
//#region src/prosemirror/schema/index.d.ts
|
|
@@ -11,4 +11,4 @@ type DocxSchema = typeof schema;
|
|
|
11
11
|
type DocxNode = ReturnType<typeof schema.node>;
|
|
12
12
|
type DocxMark = ReturnType<typeof schema.mark>;
|
|
13
13
|
//#endregion
|
|
14
|
-
export { type BlockSdtAttrs, type BookmarkBoundaryAttrs, type CharacterSpacingAttrs, type CharacterStyleAttrs, type CommentAttrs, DocxMark, DocxNode, DocxSchema, type EmphasisMarkAttrs, type FieldAttrs, type FontFamilyAttrs, type FontSizeAttrs, type FootnoteRefAttrs, type HardBreakAttrs, type HighlightAttrs, type HyperlinkAttrs, type ImageAttrs, type ImagePositionAttrs, type InlineWrapperAttrs, type InlineWrapperKind, type InlineWrapperLayer, type LanguageAttrs, type MathAttrs, type PageBreakRunAttrs, type ParagraphAttrs, type ParagraphPropertyChangeAttrs, type PreservedBlockAttrs, type PreservedXmlAttrs, type PreservedXmlLevel, type RunFormattingOverrideAttrs, type RunIdentityMarkAttrs, type RunPropertyChangeMarkAttrs, type RunShadingAttrs, type SdtAttrs, type ShapeAttrs, type StrikeAttrs, type SymbolAttrs, type TabAttrs, type TableAttrs, type TableCellAttrs, type TableRowAttrs, type TextBoxAttrs, type TextColorAttrs, type TextEffectAttrs, type TrackedChangeMarkAttrs, type UnderlineAttrs, schema, singletonManager };
|
|
14
|
+
export { type BlockSdtAttrs, type BookmarkBoundaryAttrs, type CharacterSpacingAttrs, type CharacterStyleAttrs, type CommentAttrs, DocxMark, DocxNode, DocxSchema, type EmphasisMarkAttrs, type FieldAttrs, type FontFamilyAttrs, type FontSizeAttrs, type FootnoteRefAttrs, type HardBreakAttrs, type HighlightAttrs, type HyperlinkAttrs, type ImageAttrs, type ImagePositionAttrs, type InlineWrapperAttrs, type InlineWrapperKind, type InlineWrapperLayer, type LanguageAttrs, type MathAttrs, type PageBreakRunAttrs, type ParagraphAttrs, type ParagraphPropertyChangeAttrs, type PreservedBlockAttrs, type PreservedXmlAttrs, type PreservedXmlLevel, type RunFormattingOverrideAttrs, type RunIdentityMarkAttrs, type RunPropertyChangeMarkAttrs, type RunShadingAttrs, type SdtAttrs, type ShapeAttrs, type StrikeAttrs, type SymbolAttrs, type TabAttrs, type TableAttrs, type TableCellAttrs, type TableRowAttrs, type TextBoxAttrs, type TextColorAttrs, type TextEffectAttrs, type TrackedChangeMarkAttrs, type TrackedRevisionAncestor, type UnderlineAttrs, schema, singletonManager };
|
|
@@ -99,6 +99,15 @@ type CommentAttrs = {
|
|
|
99
99
|
*/
|
|
100
100
|
declare const TRACKED_CHANGE_PROVENANCE_VALUES: readonly ["user", "suggested"];
|
|
101
101
|
type TrackedChangeProvenance = (typeof TRACKED_CHANGE_PROVENANCE_VALUES)[number];
|
|
102
|
+
type TrackedRevisionAncestor = {
|
|
103
|
+
type: "insertion" | "deletion" | "moveFrom" | "moveTo";
|
|
104
|
+
revisionId: number;
|
|
105
|
+
author: string;
|
|
106
|
+
date?: string;
|
|
107
|
+
utcDate?: string;
|
|
108
|
+
initials?: string;
|
|
109
|
+
outerWrapperCount: number;
|
|
110
|
+
};
|
|
102
111
|
type TrackedChangeMarkAttrs = {
|
|
103
112
|
revisionId: number;
|
|
104
113
|
author: string;
|
|
@@ -108,6 +117,10 @@ type TrackedChangeMarkAttrs = {
|
|
|
108
117
|
/** Optional author initials (w:initials) carried through the round-trip. */
|
|
109
118
|
initials?: string;
|
|
110
119
|
moveKind?: "moveTo" | "moveFrom";
|
|
120
|
+
/** Number of inline-wrapper layers authored outside this revision. */
|
|
121
|
+
_docxOuterWrapperCount?: number;
|
|
122
|
+
/** Outer revisions, in authored order, that ProseMirror cannot hold as nested marks. */
|
|
123
|
+
_docxRevisionAncestors?: readonly TrackedRevisionAncestor[];
|
|
111
124
|
/** Defaults to `"user"`; `"suggested"` for AI-proposed, non-serialized edits. */
|
|
112
125
|
provenance: TrackedChangeProvenance;
|
|
113
126
|
/**
|
|
@@ -136,7 +149,7 @@ type RunPropertyChangeMarkAttrs = {
|
|
|
136
149
|
* in the schema would force a resolution.
|
|
137
150
|
*
|
|
138
151
|
* Minted only when the run has something to carry — a page break, an
|
|
139
|
-
* attribute remainder, or
|
|
152
|
+
* attribute remainder, or authored run properties — so a document that
|
|
140
153
|
* carries none pays nothing.
|
|
141
154
|
*/
|
|
142
155
|
type RunIdentityMarkAttrs = {
|
|
@@ -146,6 +159,8 @@ type RunIdentityMarkAttrs = {
|
|
|
146
159
|
preservedAttributes?: readonly document_d_exports.PreservedAttribute[];
|
|
147
160
|
/** The `w:rPr` children no reader took a value from, with their ordinals. */
|
|
148
161
|
preserved?: document_d_exports.PreservedMarkup;
|
|
162
|
+
/** Preserve an authored empty `w:rPr`, distinct from no run properties. */
|
|
163
|
+
emptyFormatting?: true;
|
|
149
164
|
};
|
|
150
165
|
/**
|
|
151
166
|
* One transparent wrapper a leaf sits inside, minus the content ProseMirror
|
|
@@ -289,4 +304,4 @@ type HyperlinkAttrs = {
|
|
|
289
304
|
_docxHyperlinkIndex?: number;
|
|
290
305
|
};
|
|
291
306
|
//#endregion
|
|
292
|
-
export { AuthoredRunFormattingValues, COMPLEX_SCRIPT_RUN_PROPERTY_KEYS, CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, ComplexScriptRunPropertyKey, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, InlineWrapperAttrs, InlineWrapperKind, InlineWrapperLayer, LanguageAttrs, RUN_FORMATTING_BOOLEAN_PROPERTIES, RUN_FORMATTING_PROPERTY_SPECS, RUN_FORMATTING_VALUE_PROPERTIES, RunFormattingBooleanProperty, RunFormattingOverrideAttrs, RunFormattingValueProperty, RunIdentityMarkAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TRACKED_CHANGE_PROVENANCE_VALUES, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, TrackedChangeProvenance, UnderlineAttrs };
|
|
307
|
+
export { AuthoredRunFormattingValues, COMPLEX_SCRIPT_RUN_PROPERTY_KEYS, CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, ComplexScriptRunPropertyKey, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, InlineWrapperAttrs, InlineWrapperKind, InlineWrapperLayer, LanguageAttrs, RUN_FORMATTING_BOOLEAN_PROPERTIES, RUN_FORMATTING_PROPERTY_SPECS, RUN_FORMATTING_VALUE_PROPERTIES, RunFormattingBooleanProperty, RunFormattingOverrideAttrs, RunFormattingValueProperty, RunIdentityMarkAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TRACKED_CHANGE_PROVENANCE_VALUES, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, TrackedChangeProvenance, TrackedRevisionAncestor, UnderlineAttrs };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { expectRunPropertyChangeMarkAttrs } from "../attrs/index.js";
|
|
1
|
+
import { expectRunPropertyChangeMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
|
|
2
2
|
import { nodePropertyRevisionSites, propertyRevisionMetadata, propertyRevisionRecords } from "../revisionCarriers.js";
|
|
3
3
|
import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
|
|
4
4
|
//#region src/prosemirror/utils/extractTrackedChanges.ts
|
|
@@ -46,6 +46,7 @@ function extractTrackedChanges(state) {
|
|
|
46
46
|
const runPropertyChangeType = schema.marks["runPropertyChange"];
|
|
47
47
|
if (!insertionType && !deletionType && !runPropertyChangeType) return EMPTY_RESULT;
|
|
48
48
|
const raw = [];
|
|
49
|
+
const nestedRevisionIds = /* @__PURE__ */ new Set();
|
|
49
50
|
const commentToRevision = /* @__PURE__ */ new Map();
|
|
50
51
|
const commentMetadata = /* @__PURE__ */ new Map();
|
|
51
52
|
const rowRevisionScopes = [];
|
|
@@ -223,14 +224,28 @@ function extractTrackedChanges(state) {
|
|
|
223
224
|
if (mark.type === insertionType || mark.type === deletionType) {
|
|
224
225
|
tcMark = mark;
|
|
225
226
|
if (foldIntoRowRevision(rowRevisionScopes.at(-1), mark)) continue;
|
|
227
|
+
const attrs = expectTrackedChangeMarkAttrs(mark);
|
|
228
|
+
if (attrs._docxRevisionAncestors?.length) nestedRevisionIds.add(attrs.revisionId);
|
|
229
|
+
for (const ancestor of attrs._docxRevisionAncestors ?? []) {
|
|
230
|
+
nestedRevisionIds.add(ancestor.revisionId);
|
|
231
|
+
raw.push({
|
|
232
|
+
type: ancestor.type === "insertion" || ancestor.type === "moveTo" ? "insertion" : "deletion",
|
|
233
|
+
text: inlineText,
|
|
234
|
+
author: ancestor.author,
|
|
235
|
+
date: ancestor.date,
|
|
236
|
+
from: pos,
|
|
237
|
+
to: pos + node.nodeSize,
|
|
238
|
+
revisionId: ancestor.revisionId
|
|
239
|
+
});
|
|
240
|
+
}
|
|
226
241
|
raw.push({
|
|
227
242
|
type: mark.type === insertionType ? "insertion" : "deletion",
|
|
228
243
|
text: inlineText,
|
|
229
|
-
author:
|
|
230
|
-
date:
|
|
244
|
+
author: attrs.author,
|
|
245
|
+
date: attrs.date,
|
|
231
246
|
from: pos,
|
|
232
247
|
to: pos + node.nodeSize,
|
|
233
|
-
revisionId:
|
|
248
|
+
revisionId: attrs.revisionId
|
|
234
249
|
});
|
|
235
250
|
}
|
|
236
251
|
}
|
|
@@ -380,7 +395,7 @@ function extractTrackedChanges(state) {
|
|
|
380
395
|
merged.push({ ...entry });
|
|
381
396
|
continue;
|
|
382
397
|
}
|
|
383
|
-
const key = `${entry.type}|${entry.author}|${entry.date ?? ""}`;
|
|
398
|
+
const key = `${entry.type}|${entry.author}|${entry.date ?? ""}|${nestedRevisionIds.has(entry.revisionId) ? entry.revisionId : ""}`;
|
|
384
399
|
const group = inlineGroups.get(key);
|
|
385
400
|
if (group) {
|
|
386
401
|
const sep = group.to === entry.from ? "" : " ";
|
|
@@ -403,7 +418,7 @@ function extractTrackedChanges(state) {
|
|
|
403
418
|
for (let i = 0; i < merged.length; i++) {
|
|
404
419
|
const curr = merged[i];
|
|
405
420
|
const next = merged[i + 1];
|
|
406
|
-
if (curr.type === "deletion" && next && next.type === "insertion" && curr.author === next.author && curr.to === next.from) {
|
|
421
|
+
if (curr.type === "deletion" && next && next.type === "insertion" && !nestedRevisionIds.has(curr.revisionId) && !nestedRevisionIds.has(next.revisionId) && curr.author === next.author && curr.to === next.from) {
|
|
407
422
|
final.push({
|
|
408
423
|
type: "replacement",
|
|
409
424
|
text: next.text,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.47.
|
|
3
|
+
"version": "0.47.7",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|