@stll/folio-core 0.36.0 → 0.37.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/README.md +59 -1
- package/dist/ai-edits/apply.js +545 -296
- package/dist/ai-edits/block-identity.d.ts +4 -1
- package/dist/ai-edits/block-identity.js +4 -1
- package/dist/ai-edits/blockRange.js +14 -14
- package/dist/ai-edits/clean-text.d.ts +40 -1
- package/dist/ai-edits/clean-text.js +52 -2
- package/dist/ai-edits/headless.d.ts +3 -1
- package/dist/ai-edits/headless.js +133 -71
- package/dist/ai-edits/index.d.ts +3 -3
- package/dist/ai-edits/index.js +2 -2
- package/dist/ai-edits/read.js +38 -20
- package/dist/ai-edits/snapshot.d.ts +14 -6
- package/dist/ai-edits/snapshot.js +99 -19
- package/dist/ai-edits/table-cell-mutations.js +1 -1
- package/dist/ai-edits/table-row-column-mutations.js +7 -0
- package/dist/ai-edits/table-template.d.ts +11 -1
- package/dist/ai-edits/table-template.js +49 -17
- package/dist/ai-edits/types.d.ts +45 -57
- package/dist/ai-suggestions/conflict.js +1 -4
- package/dist/ai-suggestions/text-positions.d.ts +8 -0
- package/dist/ai-suggestions/text-positions.js +27 -5
- package/dist/compare/__fixtures__/body-sequence.js +3 -4
- package/dist/compare/column-alignment.d.ts +13 -13
- package/dist/compare/column-alignment.js +78 -39
- package/dist/compare/compare.d.ts +4 -3
- package/dist/compare/compare.js +41 -5
- package/dist/compare/content-alignment.d.ts +95 -0
- package/dist/compare/content-alignment.js +1450 -0
- package/dist/compare/content-types.d.ts +100 -0
- package/dist/compare/content-types.js +0 -0
- package/dist/compare/content.d.ts +209 -0
- package/dist/compare/content.js +885 -0
- package/dist/compare/formatting.d.ts +5 -5
- package/dist/compare/formatting.js +6 -4
- package/dist/compare/plan.d.ts +6 -1
- package/dist/compare/plan.js +169 -567
- package/dist/compare/scenario.d.ts +2 -2
- package/dist/compare/types.d.ts +3 -3
- package/dist/compare/verification.d.ts +2 -2
- package/dist/compare/verification.js +25 -8
- package/dist/compat/eigenpal.d.ts +5 -3
- package/dist/compat/eigenpal.js +3 -2
- package/dist/controller/headerFooterEditorManager.js +14 -6
- package/dist/controller/hiddenEditorManager.d.ts +7 -2
- package/dist/controller/hiddenEditorManager.js +15 -6
- package/dist/controller/layoutPipeline.js +5 -3
- package/dist/controller/noteEditorManager.js +12 -7
- package/dist/display-list/build/headerFooterPrimitives.js +1 -0
- package/dist/display-list/build/storyPrimitives.d.ts +5 -2
- package/dist/display-list/build/storyPrimitives.js +60 -3
- package/dist/display-list/build/tablePrimitives.js +30 -0
- package/dist/display-list/primitives.d.ts +1 -1
- package/dist/document-operations.d.ts +6 -4
- package/dist/document-operations.js +77 -12
- package/dist/docx/blockContentParser.js +6 -27
- package/dist/docx/ensureParaIds.js +9 -4
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +4 -1
- package/dist/docx/paragraphParser.js +7 -6
- package/dist/docx/paragraphTraversal.js +30 -34
- package/dist/docx/rezip.d.ts +0 -8
- package/dist/docx/rezip.js +41 -16
- package/dist/docx/runParser.js +4 -2
- package/dist/docx/serializer/paragraphSerializer.js +2 -0
- package/dist/docx/serializer/runSerializer.js +5 -3
- package/dist/docx/serializer/trackedChangeAttributes.d.ts +3 -1
- package/dist/docx/serializer/trackedChangeAttributes.js +11 -1
- package/dist/docx/server/build.d.ts +1 -1
- package/dist/headless-layout.js +5 -4
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -2
- package/dist/internal/headlessRevisionResolution.d.ts +23 -0
- package/dist/internal/headlessRevisionResolution.js +155 -0
- package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
- package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
- package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
- package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
- package/dist/internal/pageBreakRunPartition.d.ts +26 -0
- package/dist/internal/pageBreakRunPartition.js +35 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
- package/dist/internal/sectionEndpointResolution.d.ts +32 -0
- package/dist/internal/sectionEndpointResolution.js +38 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
- package/dist/layout-bridge/convert/headerFooterLayout.js +48 -5
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +379 -75
- package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
- package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
- package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
- package/dist/layout-bridge/dom/textStreamDom.js +75 -0
- package/dist/layout-bridge/headerFooterLayout.js +16 -30
- package/dist/layout-engine/index.js +12 -3
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
- package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
- package/dist/layout-engine/types.d.ts +7 -0
- package/dist/layout-painter/imageLayout.d.ts +1 -1
- package/dist/layout-painter/renderTable.js +20 -0
- package/dist/model.d.ts +1 -1
- package/dist/paged-layout/rangeProjection.js +6 -9
- package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
- package/dist/paged-layout/transactionDirtyRange.js +23 -1
- package/dist/prosemirror/attrs/index.d.ts +7 -3
- package/dist/prosemirror/attrs/index.js +113 -7
- package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
- package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
- package/dist/prosemirror/commands/comments.d.ts +10 -1
- package/dist/prosemirror/commands/comments.js +190 -59
- package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
- package/dist/prosemirror/commands/formatPainter.js +319 -63
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
- package/dist/prosemirror/commands/pageBreak.js +18 -36
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +7 -5
- package/dist/prosemirror/commands/propertyChangeScope.js +27 -18
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +7 -2
- package/dist/prosemirror/conversion/fromProseDoc.js +809 -209
- package/dist/prosemirror/conversion/runShadingMark.js +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
- package/dist/prosemirror/conversion/toProseDoc.js +416 -283
- package/dist/prosemirror/extensions/StarterKit.js +4 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -8
- package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
- package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
- package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
- package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
- package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
- package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
- package/dist/prosemirror/findReplaceSelection.js +8 -3
- package/dist/prosemirror/index.d.ts +3 -3
- package/dist/prosemirror/listMarker.d.ts +26 -1
- package/dist/prosemirror/listMarker.js +108 -14
- package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
- package/dist/prosemirror/pageBreakRunProjection.js +47 -0
- package/dist/prosemirror/paraText.js +6 -0
- package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
- package/dist/prosemirror/paragraphSpacing.js +125 -0
- package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
- package/dist/prosemirror/plugins/documentNumbering.js +18 -0
- package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
- package/dist/prosemirror/plugins/pmTextScan.js +14 -4
- package/dist/prosemirror/plugins/suggestionMode.js +8 -10
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
- package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
- package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
- package/dist/prosemirror/runFormattingProvenance.js +48 -0
- package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
- package/dist/prosemirror/runFormattingReconciliation.js +54 -0
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
- package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
- package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
- package/dist/prosemirror/runStyleFormatting.js +105 -0
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +82 -9
- package/dist/prosemirror/schema/marks.js +73 -1
- package/dist/prosemirror/schema/nodes.d.ts +18 -5
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +44 -23
- package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
- package/dist/prosemirror/styles/styleResolver.js +3 -3
- package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
- package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
- package/dist/prosemirror/tableGridMutation.d.ts +20 -0
- package/dist/prosemirror/tableGridMutation.js +30 -0
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
- package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
- package/dist/prosemirror/validation.js +23 -4
- package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
- package/dist/render-dom/RenderedDomContext.js +17 -34
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/style-engine/styleEngine.d.ts +1 -1
- package/dist/utils/clipboard.js +1 -1
- package/dist/utils/findReplace.js +38 -21
- package/dist/version-comparison.d.ts +38 -44
- package/dist/version-comparison.js +270 -401
- package/package.json +3 -2
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import { appendHeadlessInlineResolution } from "../../internal/headlessRevisionResolution.js";
|
|
2
|
+
import { stateAllowsHeadlessRevisionResolution } from "../../internal/headlessRevisionResolutionGuard.js";
|
|
1
3
|
import { expectParagraphAttrs, expectRunPropertyChangeMarkAttrs } from "../attrs/index.js";
|
|
2
4
|
import { addedBreakCarrierBefore, finalParagraphsOf, paragraphEndsItsContainer } from "../containerFinalParagraph.js";
|
|
3
|
-
import {
|
|
4
|
-
import { markStructuralChange } from "../extensions/features/ParagraphChangeTrackerExtension.js";
|
|
5
|
+
import { resolveParagraphDefaultTextFormatting } from "../conversion/toProseDoc.js";
|
|
6
|
+
import { markChangedParagraphRanges, markStructuralChange, markTrackedSectionEndpointRemoval } from "../extensions/features/ParagraphChangeTrackerExtension.js";
|
|
5
7
|
import { getDocumentStyleResolver } from "../plugins/documentStyles.js";
|
|
8
|
+
import { setParagraphAttrsWithRebasedRunFormatting } from "../rebaseParagraphRunFormatting.js";
|
|
6
9
|
import { getFolioNodeRevisionCarriers } from "../revisionCarriers.js";
|
|
7
10
|
import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
11
|
+
import { reconstructRejectedRunFormattingMarks } from "../runPropertyChangeResolution.js";
|
|
12
|
+
import { paragraphRunStyleContextAt } from "../runStyleFormatting.js";
|
|
8
13
|
import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
|
|
14
|
+
import { reconcileTableGridAfterColumnRemoval } from "../tableGridMutation.js";
|
|
9
15
|
import { holdsNoContent } from "../zeroWidthAnchors.js";
|
|
10
|
-
import { paragraphPropertiesSnapshot, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch } from "./propertyChangeScope.js";
|
|
16
|
+
import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch } from "./propertyChangeScope.js";
|
|
11
17
|
import { hasMatchingCollapsedTableCellMerge, resolveCollapsedTableCellMerge, resolveVisibleTableCellMerge } from "./tableCellMergeResolution.js";
|
|
12
18
|
import { TableMap, removeRow } from "prosemirror-tables";
|
|
13
19
|
import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
|
|
@@ -44,6 +50,7 @@ function removeCommentMark(commentId) {
|
|
|
44
50
|
return true;
|
|
45
51
|
};
|
|
46
52
|
}
|
|
53
|
+
const BULK_INLINE_RESOLUTION_THRESHOLD = 256;
|
|
47
54
|
/**
|
|
48
55
|
* Resolve a tracked change: accept or reject.
|
|
49
56
|
* - Accept: keep insertions (remove mark), delete deletions (remove text)
|
|
@@ -56,7 +63,7 @@ function removeCommentMark(commentId) {
|
|
|
56
63
|
* the operation matches every revision mark or property-change entry in the
|
|
57
64
|
* range (the bulk accept-all/reject-all path).
|
|
58
65
|
*/
|
|
59
|
-
function resolveChange(from, to, mode, revisionIds) {
|
|
66
|
+
function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
|
|
60
67
|
return (state, dispatch) => {
|
|
61
68
|
const insertionType = state.schema.marks["insertion"];
|
|
62
69
|
const deletionType = state.schema.marks["deletion"];
|
|
@@ -65,6 +72,7 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
65
72
|
const removeType = mode === "accept" ? deletionType : insertionType;
|
|
66
73
|
const revisionSet = revisionIds === void 0 ? null : new Set(revisionIds);
|
|
67
74
|
const removeKeptMarksInBulk = revisionSet === null && keepType !== void 0;
|
|
75
|
+
const canBulkInlineResolution = execution === "headless-bulk-inline" && revisionSet === null && from === 0 && to === state.doc.content.size && stateAllowsHeadlessRevisionResolution(state);
|
|
68
76
|
const matchesRevision = (mark) => revisionSet === null || typeof mark.attrs["revisionId"] === "number" && revisionSet.has(mark.attrs["revisionId"]);
|
|
69
77
|
if (dispatch) {
|
|
70
78
|
const tr = state.tr;
|
|
@@ -72,6 +80,10 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
72
80
|
const pPrMarkOps = [];
|
|
73
81
|
const tableRowStructuralOps = [];
|
|
74
82
|
const tableCellStructuralOps = [];
|
|
83
|
+
const deferredRunPropertyChanges = [];
|
|
84
|
+
let bulkInlineCarrierCount = 0;
|
|
85
|
+
let removedSectionEndpointCount = 0;
|
|
86
|
+
const removedSectionReferences = [];
|
|
75
87
|
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
76
88
|
if (node.type.name === "paragraph") {
|
|
77
89
|
const op = collectPPrMarkOp(node, pos, from, to, mode, revisionSet);
|
|
@@ -92,9 +104,14 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
92
104
|
_propertyChanges: remaining.length > 0 ? remaining : null
|
|
93
105
|
};
|
|
94
106
|
if (rejection?.type === "restore-previous") {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
107
|
+
const inheritedAlignment = expectParagraphAttrs(node).alignmentFromStyle;
|
|
108
|
+
let previousFormattingFromStyle;
|
|
109
|
+
if (styleResolver) previousFormattingFromStyle = styleResolver.resolveParagraphStyle(rejection.previousFormatting?.styleId).paragraphFormatting;
|
|
110
|
+
else if (inheritedAlignment !== void 0) previousFormattingFromStyle = { alignment: inheritedAlignment };
|
|
111
|
+
Object.assign(nextAttrs, paragraphRejectAttrPatch(rejection.previousFormatting, previousFormattingFromStyle));
|
|
112
|
+
const restoredFormatting = paragraphRejectOriginalFormatting(rejection.previousFormatting, node.attrs["_originalFormatting"]);
|
|
113
|
+
nextAttrs["_originalFormatting"] = restoredFormatting;
|
|
114
|
+
if (styleResolver) nextAttrs["defaultTextFormatting"] = resolveParagraphDefaultTextFormatting(rejection.previousFormatting?.styleId, restoredFormatting ?? void 0, styleResolver) ?? null;
|
|
98
115
|
}
|
|
99
116
|
}
|
|
100
117
|
}
|
|
@@ -113,7 +130,13 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
113
130
|
nextAttrs["sectionBreakType"] = sectionBreakTypeFromSectionStart(restored.sectionStart);
|
|
114
131
|
}
|
|
115
132
|
}
|
|
116
|
-
if (nextAttrs)
|
|
133
|
+
if (nextAttrs) if (nextAttrs["styleId"] !== node.attrs["styleId"] && styleResolver) setParagraphAttrsWithRebasedRunFormatting({
|
|
134
|
+
nextAttrs,
|
|
135
|
+
paragraphPosition: pos,
|
|
136
|
+
styleResolver,
|
|
137
|
+
tr
|
|
138
|
+
});
|
|
139
|
+
else tr.setNodeMarkup(pos, void 0, nextAttrs);
|
|
117
140
|
return true;
|
|
118
141
|
}
|
|
119
142
|
if (node.type.name === "tableRow" && rangeCoversNode(from, to, pos, node)) {
|
|
@@ -125,7 +148,10 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
125
148
|
if (tableChangeAttrName !== void 0) {
|
|
126
149
|
if (rangeCoversNode(from, to, pos, node)) {
|
|
127
150
|
const nextAttrs = resolveTablePropertyChangeAttrs(node, tableChangeAttrName, mode, revisionSet);
|
|
128
|
-
if (nextAttrs)
|
|
151
|
+
if (nextAttrs) {
|
|
152
|
+
tr.setNodeMarkup(pos, void 0, nextAttrs);
|
|
153
|
+
markStructuralChange(tr);
|
|
154
|
+
}
|
|
129
155
|
}
|
|
130
156
|
return true;
|
|
131
157
|
}
|
|
@@ -134,6 +160,27 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
134
160
|
const rangeFrom = Math.max(from, pos);
|
|
135
161
|
const rangeTo = Math.min(to, nodeEnd);
|
|
136
162
|
const runPropertyChangeMark = node.marks.find((mark) => mark.type.name === "runPropertyChange");
|
|
163
|
+
const resolvesRunPropertyChange = runPropertyChangeMark !== void 0 && expectRunPropertyChangeMarkAttrs(runPropertyChangeMark).changes.length > 0;
|
|
164
|
+
const removesNode = removeType !== void 0 && node.marks.some((mark) => mark.type === removeType && matchesRevision(mark));
|
|
165
|
+
const removesKeptMark = keepType !== void 0 && node.marks.some((mark) => mark.type === keepType && matchesRevision(mark));
|
|
166
|
+
if (canBulkInlineResolution) {
|
|
167
|
+
if (resolvesRunPropertyChange) deferredRunPropertyChanges.push({
|
|
168
|
+
tr,
|
|
169
|
+
node,
|
|
170
|
+
from: rangeFrom,
|
|
171
|
+
to: rangeTo,
|
|
172
|
+
mark: runPropertyChangeMark,
|
|
173
|
+
mode,
|
|
174
|
+
revisionSet,
|
|
175
|
+
styleResolver
|
|
176
|
+
});
|
|
177
|
+
if (removesNode) deleteRanges.push({
|
|
178
|
+
from: rangeFrom,
|
|
179
|
+
to: rangeTo
|
|
180
|
+
});
|
|
181
|
+
if (resolvesRunPropertyChange || removesNode || removesKeptMark) bulkInlineCarrierCount++;
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
137
184
|
if (runPropertyChangeMark) resolveRunPropertyChange({
|
|
138
185
|
tr,
|
|
139
186
|
node,
|
|
@@ -141,9 +188,10 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
141
188
|
to: rangeTo,
|
|
142
189
|
mark: runPropertyChangeMark,
|
|
143
190
|
mode,
|
|
144
|
-
revisionSet
|
|
191
|
+
revisionSet,
|
|
192
|
+
styleResolver
|
|
145
193
|
});
|
|
146
|
-
if (
|
|
194
|
+
if (removesNode) deleteRanges.push({
|
|
147
195
|
from: rangeFrom,
|
|
148
196
|
to: rangeTo
|
|
149
197
|
});
|
|
@@ -152,24 +200,35 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
152
200
|
}
|
|
153
201
|
return true;
|
|
154
202
|
});
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
203
|
+
let bulkInlineChangeTracking = null;
|
|
204
|
+
if (canBulkInlineResolution && bulkInlineCarrierCount >= BULK_INLINE_RESOLUTION_THRESHOLD) bulkInlineChangeTracking = appendHeadlessInlineResolution({
|
|
205
|
+
tr,
|
|
206
|
+
mode,
|
|
207
|
+
keepType,
|
|
208
|
+
removeType,
|
|
209
|
+
styleResolver
|
|
210
|
+
});
|
|
211
|
+
else {
|
|
212
|
+
for (const deferred of deferredRunPropertyChanges) resolveRunPropertyChange(deferred);
|
|
213
|
+
if (removeKeptMarksInBulk) tr.removeMark(from, to, keepType);
|
|
214
|
+
let rangesToDelete = deleteRanges;
|
|
215
|
+
if (revisionSet === null) {
|
|
216
|
+
const coalescedDeleteRanges = [];
|
|
217
|
+
for (const range of deleteRanges) {
|
|
218
|
+
const previous = coalescedDeleteRanges.at(-1);
|
|
219
|
+
if (previous && range.from <= previous.to) {
|
|
220
|
+
previous.to = Math.max(previous.to, range.to);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
coalescedDeleteRanges.push({
|
|
224
|
+
from: range.from,
|
|
225
|
+
to: range.to
|
|
226
|
+
});
|
|
164
227
|
}
|
|
165
|
-
coalescedDeleteRanges
|
|
166
|
-
from: range.from,
|
|
167
|
-
to: range.to
|
|
168
|
-
});
|
|
228
|
+
rangesToDelete = coalescedDeleteRanges;
|
|
169
229
|
}
|
|
170
|
-
rangesToDelete
|
|
230
|
+
for (const range of rangesToDelete.toReversed()) tr.delete(range.from, range.to);
|
|
171
231
|
}
|
|
172
|
-
for (const range of rangesToDelete.toReversed()) tr.delete(range.from, range.to);
|
|
173
232
|
pPrMarkOps.sort((a, b) => b.paragraphPos - a.paragraphPos);
|
|
174
233
|
for (const op of pPrMarkOps) {
|
|
175
234
|
const mappedPos = tr.mapping.map(op.paragraphPos);
|
|
@@ -181,35 +240,34 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
181
240
|
}
|
|
182
241
|
const joinPos = mappedPos + paragraph.nodeSize;
|
|
183
242
|
const nextNode = joinPos < tr.doc.content.size ? tr.doc.nodeAt(joinPos) : null;
|
|
184
|
-
if (!(nextNode?.type.name === paragraph.type.name
|
|
243
|
+
if (!(nextNode?.type.name === paragraph.type.name)) {
|
|
185
244
|
const resolved = tr.doc.resolve(mappedPos);
|
|
186
|
-
const previous = resolved.nodeBefore;
|
|
187
|
-
const sectionCanMoveBack = !carriesSection(paragraph) || previous?.type.name === paragraph.type.name && !carriesSection(previous);
|
|
188
245
|
const endsItsContainer = paragraphEndsItsContainer(resolved, paragraph.type.name);
|
|
189
246
|
const canGo = op.markWasAdded || !endsItsContainer;
|
|
190
|
-
if (
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
});
|
|
247
|
+
if (holdsNoContent(paragraph) && canGo && resolved.parent.childCount > 1) {
|
|
248
|
+
if (ownsSectionEndpoint(paragraph)) {
|
|
249
|
+
removedSectionEndpointCount++;
|
|
250
|
+
removedSectionReferences.push(...sectionReferencesOf(paragraph));
|
|
251
|
+
}
|
|
196
252
|
tr.delete(mappedPos, mappedPos + paragraph.nodeSize);
|
|
197
253
|
continue;
|
|
198
254
|
}
|
|
199
255
|
tr.setNodeAttribute(mappedPos, "pPrMark", null);
|
|
200
256
|
continue;
|
|
201
257
|
}
|
|
202
|
-
const formattingOwner = holdsNoContent(paragraph) ? nextNode : paragraph;
|
|
203
|
-
const sectionOwner = carriesSection(paragraph) ? paragraph : nextNode;
|
|
204
258
|
const joinedAttrs = {
|
|
205
|
-
...
|
|
259
|
+
...(holdsNoContent(paragraph) ? nextNode : paragraph).attrs,
|
|
206
260
|
pPrMark: nextNode.attrs["pPrMark"],
|
|
207
|
-
sectionBreakType:
|
|
208
|
-
_sectionProperties:
|
|
261
|
+
sectionBreakType: nextNode.attrs["sectionBreakType"],
|
|
262
|
+
_sectionProperties: nextNode.attrs["_sectionProperties"]
|
|
209
263
|
};
|
|
210
264
|
try {
|
|
211
265
|
tr.join(joinPos);
|
|
212
266
|
tr.setNodeMarkup(mappedPos, void 0, joinedAttrs);
|
|
267
|
+
if (ownsSectionEndpoint(paragraph)) {
|
|
268
|
+
removedSectionEndpointCount++;
|
|
269
|
+
removedSectionReferences.push(...sectionReferencesOf(paragraph));
|
|
270
|
+
}
|
|
213
271
|
} catch {}
|
|
214
272
|
}
|
|
215
273
|
tableRowStructuralOps.sort((left, right) => right.rowPos - left.rowPos);
|
|
@@ -259,12 +317,18 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
259
317
|
}
|
|
260
318
|
if (failedTableCellMergeResolution) return false;
|
|
261
319
|
if (resolvedTableCellStructure) markStructuralChange(tr);
|
|
320
|
+
if (bulkInlineChangeTracking) markChangedParagraphRanges(tr, bulkInlineChangeTracking);
|
|
321
|
+
if (removedSectionEndpointCount > 0) markTrackedSectionEndpointRemoval(tr, {
|
|
322
|
+
sourceDoc: state.doc,
|
|
323
|
+
removedEndpointCount: removedSectionEndpointCount,
|
|
324
|
+
removedReferences: removedSectionReferences
|
|
325
|
+
});
|
|
262
326
|
if (tr.steps.length > 0) dispatch(tr);
|
|
263
327
|
}
|
|
264
328
|
return true;
|
|
265
329
|
};
|
|
266
330
|
}
|
|
267
|
-
const resolveRunPropertyChange = ({ tr, node, from, to, mark, mode, revisionSet }) => {
|
|
331
|
+
const resolveRunPropertyChange = ({ tr, node, from, to, mark, mode, revisionSet, styleResolver }) => {
|
|
268
332
|
const { changes } = expectRunPropertyChangeMarkAttrs(mark);
|
|
269
333
|
const matches = changes.filter((change) => revisionSet === null || revisionSet.has(change.info.id));
|
|
270
334
|
if (matches.length === 0) return;
|
|
@@ -273,15 +337,18 @@ const resolveRunPropertyChange = ({ tr, node, from, to, mark, mode, revisionSet
|
|
|
273
337
|
if (remaining.length > 0) tr.addMark(from, to, mark.type.create({ changes: remaining }));
|
|
274
338
|
if (mode === "accept") return;
|
|
275
339
|
const previousFormatting = matches.at(0)?.previousFormatting;
|
|
340
|
+
const styleContext = paragraphRunStyleContextAt({
|
|
341
|
+
doc: tr.doc,
|
|
342
|
+
pos: from,
|
|
343
|
+
styleResolver
|
|
344
|
+
});
|
|
276
345
|
for (const currentMark of node.marks) if (RUN_FORMATTING_MARK_NAMES.has(currentMark.type.name)) tr.removeMark(from, to, currentMark.type);
|
|
277
|
-
for (const previousMark of
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}));
|
|
284
|
-
}
|
|
346
|
+
for (const previousMark of reconstructRejectedRunFormattingMarks({
|
|
347
|
+
node,
|
|
348
|
+
paragraphContext: styleContext,
|
|
349
|
+
previousFormatting,
|
|
350
|
+
styleResolver
|
|
351
|
+
})) tr.addMark(from, to, previousMark);
|
|
285
352
|
};
|
|
286
353
|
function collectTableRowStructuralOp(node, rowPos, mode, revisionSet) {
|
|
287
354
|
for (const attrName of ["trIns", "trDel"]) {
|
|
@@ -376,11 +443,33 @@ function deleteTableCellAt(tr, cellPos) {
|
|
|
376
443
|
const resolved = tr.doc.resolve(cellPos);
|
|
377
444
|
const row = resolved.parent;
|
|
378
445
|
if (row.type.spec["tableRole"] !== "row") return;
|
|
446
|
+
const tableDepth = resolved.depth - 1;
|
|
447
|
+
const table = resolved.node(tableDepth);
|
|
448
|
+
if (table.type.spec["tableRole"] !== "table") return;
|
|
449
|
+
const tablePosition = resolved.before(tableDepth);
|
|
450
|
+
const cellOffset = cellPos - resolved.start(tableDepth);
|
|
451
|
+
const removedColumn = TableMap.get(table).findCell(cellOffset).left;
|
|
379
452
|
if (row.childCount > 1) {
|
|
380
453
|
tr.delete(cellPos, cellPos + cell.nodeSize);
|
|
454
|
+
reconcileTableGridAfterColumnRemoval({
|
|
455
|
+
tr,
|
|
456
|
+
tablePosition,
|
|
457
|
+
previousTable: table,
|
|
458
|
+
removedColumn
|
|
459
|
+
});
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (table.childCount === 1) {
|
|
463
|
+
deleteTableRowAt(tr, resolved.start() - 1);
|
|
381
464
|
return;
|
|
382
465
|
}
|
|
383
466
|
deleteTableRowAt(tr, resolved.start() - 1);
|
|
467
|
+
reconcileTableGridAfterColumnRemoval({
|
|
468
|
+
tr,
|
|
469
|
+
tablePosition,
|
|
470
|
+
previousTable: table,
|
|
471
|
+
removedColumn
|
|
472
|
+
});
|
|
384
473
|
}
|
|
385
474
|
function deleteTableRowAt(tr, rowPos) {
|
|
386
475
|
const resolved = tr.doc.resolve(rowPos);
|
|
@@ -487,16 +576,24 @@ function isPPrMarkAttr(value) {
|
|
|
487
576
|
* the two ends belong together, not because they resolve differently.
|
|
488
577
|
*/
|
|
489
578
|
const paragraphMarkWasAdded = (kind) => kind === "ins" || kind === "moveTo";
|
|
579
|
+
const ownsSectionEndpoint = (paragraph) => {
|
|
580
|
+
const attrs = expectParagraphAttrs(paragraph);
|
|
581
|
+
return attrs._sectionProperties !== void 0 || attrs.sectionBreakType !== void 0;
|
|
582
|
+
};
|
|
583
|
+
const sectionReferencesOf = (paragraph) => {
|
|
584
|
+
const sectionProperties = expectParagraphAttrs(paragraph)._sectionProperties;
|
|
585
|
+
if (!sectionProperties) return [];
|
|
586
|
+
return [...(sectionProperties.headerReferences ?? []).map(({ type, rId }) => ({
|
|
587
|
+
part: "header",
|
|
588
|
+
type,
|
|
589
|
+
relationshipId: rId
|
|
590
|
+
})), ...(sectionProperties.footerReferences ?? []).map(({ type, rId }) => ({
|
|
591
|
+
part: "footer",
|
|
592
|
+
type,
|
|
593
|
+
relationshipId: rId
|
|
594
|
+
}))];
|
|
595
|
+
};
|
|
490
596
|
const isAddedPPrMarkAttr = (value) => isPPrMarkAttr(value) && (value.kind === "ins" || value.kind === "moveTo");
|
|
491
|
-
/**
|
|
492
|
-
* Whether the paragraph's mark carries a section's properties.
|
|
493
|
-
*
|
|
494
|
-
* A section break lives on a paragraph mark, so the paragraph is where the
|
|
495
|
-
* section ends. Removing it removes the section: a document that had two ends
|
|
496
|
-
* up with one, and every setting the dropped section carried — page size,
|
|
497
|
-
* margins, its header and footer references — goes with it.
|
|
498
|
-
*/
|
|
499
|
-
const carriesSection = (paragraph) => paragraph.attrs["sectionBreakType"] != null || paragraph.attrs["_sectionProperties"] != null;
|
|
500
597
|
function readRevisionInfo(info) {
|
|
501
598
|
const revision = {};
|
|
502
599
|
if (typeof info?.author === "string") revision.author = info.author;
|
|
@@ -574,6 +671,20 @@ function rejectAllChanges() {
|
|
|
574
671
|
return (state, dispatch) => rejectChange(0, state.doc.content.size)(state, dispatch);
|
|
575
672
|
}
|
|
576
673
|
/**
|
|
674
|
+
* Resolve a complete state synchronously for a headless reader or writer.
|
|
675
|
+
*
|
|
676
|
+
* @internal The replacement transaction is consumed here and never exposed:
|
|
677
|
+
* it is deliberately not an editor command and must not be transported or
|
|
678
|
+
* mapped through concurrent edits.
|
|
679
|
+
*/
|
|
680
|
+
function resolveAllChangesInHeadlessState(state, mode) {
|
|
681
|
+
let resolvedState = state;
|
|
682
|
+
resolveChange(0, state.doc.content.size, mode, void 0, "headless-bulk-inline")(state, (transaction) => {
|
|
683
|
+
resolvedState = state.apply(transaction);
|
|
684
|
+
});
|
|
685
|
+
return resolvedState;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
577
688
|
* Find the document range covered by all revision carriers with any of the
|
|
578
689
|
* given ids. Returns null when none are present (already accepted/rejected, or
|
|
579
690
|
* never existed). A replace operation typically passes two ids; standalone
|
|
@@ -965,12 +1076,31 @@ const reauthorParagraphPropertySuggestions = ({ node, matchesSuggestion, author,
|
|
|
965
1076
|
});
|
|
966
1077
|
return changed ? next : null;
|
|
967
1078
|
};
|
|
1079
|
+
const canReauthorParagraphPropertySuggestions = (doc, matchesSuggestion) => {
|
|
1080
|
+
let valid = true;
|
|
1081
|
+
doc.descendants((node) => {
|
|
1082
|
+
if (!valid || node.type.name !== "paragraph") return;
|
|
1083
|
+
const propertyChanges = expectParagraphAttrs(node)._propertyChanges;
|
|
1084
|
+
if (!Array.isArray(propertyChanges)) return;
|
|
1085
|
+
let serializableCount = 0;
|
|
1086
|
+
for (const change of propertyChanges) {
|
|
1087
|
+
const suggested = readSuggestedParagraphPropertyChange(change);
|
|
1088
|
+
if (!suggested || matchesSuggestion(suggested.suggestionId)) serializableCount++;
|
|
1089
|
+
}
|
|
1090
|
+
if (serializableCount > 1) {
|
|
1091
|
+
valid = false;
|
|
1092
|
+
return false;
|
|
1093
|
+
}
|
|
1094
|
+
});
|
|
1095
|
+
return valid;
|
|
1096
|
+
};
|
|
968
1097
|
const appendRotatedParagraphPropertyChange = ({ tr, currentPosition, previous, mark, fallbackAuthor }) => {
|
|
969
1098
|
const current = tr.doc.nodeAt(currentPosition);
|
|
970
1099
|
if (!current || current.type.name !== "paragraph") return false;
|
|
971
1100
|
const author = typeof mark.info.author === "string" ? mark.info.author : fallbackAuthor;
|
|
972
1101
|
if (author === void 0) return false;
|
|
973
1102
|
const existing = expectParagraphAttrs(current)._propertyChanges;
|
|
1103
|
+
if (hasSerializableParagraphPropertyChange(existing)) return false;
|
|
974
1104
|
tr.setNodeMarkup(currentPosition, void 0, {
|
|
975
1105
|
...current.attrs,
|
|
976
1106
|
_propertyChanges: [...Array.isArray(existing) ? existing : [], {
|
|
@@ -1194,6 +1324,7 @@ const removeSuggestedInsertNodes = ({ tr, positions, resolvedRevisionIds }) => {
|
|
|
1194
1324
|
*/
|
|
1195
1325
|
const acceptSuggestions = (matchesSuggestion, options) => {
|
|
1196
1326
|
return (state, dispatch) => {
|
|
1327
|
+
if (!canReauthorParagraphPropertySuggestions(state.doc, matchesSuggestion)) return false;
|
|
1197
1328
|
const insertionType = state.schema.marks["insertion"];
|
|
1198
1329
|
const deletionType = state.schema.marks["deletion"];
|
|
1199
1330
|
const runPropertyChangeType = state.schema.marks["runPropertyChange"];
|
|
@@ -1547,4 +1678,4 @@ function findPreviousChange(state, startPos) {
|
|
|
1547
1678
|
return result.value;
|
|
1548
1679
|
}
|
|
1549
1680
|
//#endregion
|
|
1550
|
-
export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark };
|
|
1681
|
+
export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { document_d_exports } from "../../types/document.js";
|
|
1
2
|
import { Command, EditorState } from "prosemirror-state";
|
|
2
3
|
import { Mark } from "prosemirror-model";
|
|
3
4
|
//#region src/prosemirror/commands/formatPainter.d.ts
|
|
@@ -9,22 +10,56 @@ import { Mark } from "prosemirror-model";
|
|
|
9
10
|
* text direction or hide content, which is surprising for a formatting brush.
|
|
10
11
|
*/
|
|
11
12
|
declare const PAINTABLE_MARK_NAMES: ReadonlySet<string>;
|
|
13
|
+
type PaintableFormatting = {
|
|
14
|
+
allCaps?: document_d_exports.TextFormatting["allCaps"];
|
|
15
|
+
bold?: document_d_exports.TextFormatting["bold"];
|
|
16
|
+
boldCs?: document_d_exports.TextFormatting["boldCs"];
|
|
17
|
+
color?: document_d_exports.TextFormatting["color"];
|
|
18
|
+
cs?: document_d_exports.TextFormatting["cs"];
|
|
19
|
+
doubleStrike?: document_d_exports.TextFormatting["doubleStrike"];
|
|
20
|
+
effect?: document_d_exports.TextFormatting["effect"];
|
|
21
|
+
emboss?: document_d_exports.TextFormatting["emboss"];
|
|
22
|
+
emphasisMark?: document_d_exports.TextFormatting["emphasisMark"];
|
|
23
|
+
fontFamily?: document_d_exports.TextFormatting["fontFamily"];
|
|
24
|
+
fontSize?: document_d_exports.TextFormatting["fontSize"];
|
|
25
|
+
fontSizeCs?: document_d_exports.TextFormatting["fontSizeCs"];
|
|
26
|
+
highlight?: document_d_exports.TextFormatting["highlight"];
|
|
27
|
+
imprint?: document_d_exports.TextFormatting["imprint"];
|
|
28
|
+
italic?: document_d_exports.TextFormatting["italic"];
|
|
29
|
+
italicCs?: document_d_exports.TextFormatting["italicCs"];
|
|
30
|
+
kerning?: document_d_exports.TextFormatting["kerning"];
|
|
31
|
+
outline?: document_d_exports.TextFormatting["outline"];
|
|
32
|
+
position?: document_d_exports.TextFormatting["position"];
|
|
33
|
+
scale?: document_d_exports.TextFormatting["scale"];
|
|
34
|
+
shading?: document_d_exports.TextFormatting["shading"];
|
|
35
|
+
shadow?: document_d_exports.TextFormatting["shadow"];
|
|
36
|
+
smallCaps?: document_d_exports.TextFormatting["smallCaps"];
|
|
37
|
+
spacing?: document_d_exports.TextFormatting["spacing"];
|
|
38
|
+
strike?: document_d_exports.TextFormatting["strike"];
|
|
39
|
+
underline?: document_d_exports.TextFormatting["underline"];
|
|
40
|
+
vertAlign?: document_d_exports.TextFormatting["vertAlign"];
|
|
41
|
+
};
|
|
42
|
+
type CapturedTextFormatting = Readonly<{
|
|
43
|
+
effectiveFormatting: Readonly<PaintableFormatting>;
|
|
44
|
+
marks: readonly Mark[];
|
|
45
|
+
type: "capturedTextFormatting";
|
|
46
|
+
}>;
|
|
12
47
|
/**
|
|
13
|
-
* Capture the paintable character
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
48
|
+
* Capture the paintable character formatting active over the current selection.
|
|
49
|
+
* An empty selection reads the stored/insertion marks; a range reads its leading
|
|
50
|
+
* run. The discriminated result deliberately represents an effectively plain run:
|
|
51
|
+
* `null` belongs to the host's “nothing captured” state, not this command.
|
|
17
52
|
*/
|
|
18
|
-
declare function captureFormatMarks(state: EditorState):
|
|
53
|
+
declare function captureFormatMarks(state: EditorState): CapturedTextFormatting;
|
|
19
54
|
/**
|
|
20
55
|
* Apply captured marks onto the current selection's range: clear every paintable
|
|
21
56
|
* mark type first (replace, not merge — so painting Georgia-12-bold onto
|
|
22
57
|
* Arial-10 leaves only Georgia-12-bold), then lay down the captured marks.
|
|
23
58
|
*
|
|
24
|
-
* Best-effort: a collapsed selection
|
|
25
|
-
*
|
|
26
|
-
*
|
|
59
|
+
* Best-effort: a collapsed selection, no capture, or a target-relative delta
|
|
60
|
+
* that cannot be represented without guessing document defaults is a no-op.
|
|
61
|
+
* Returns false so a keymap binding stays unclaimed; never partially mutates.
|
|
27
62
|
*/
|
|
28
|
-
declare function applyFormatMarks(
|
|
63
|
+
declare function applyFormatMarks(captured: CapturedTextFormatting | null): Command;
|
|
29
64
|
//#endregion
|
|
30
|
-
export { PAINTABLE_MARK_NAMES, applyFormatMarks, captureFormatMarks };
|
|
65
|
+
export { CapturedTextFormatting, PAINTABLE_MARK_NAMES, applyFormatMarks, captureFormatMarks };
|