@magic-marker/prosemirror-suggest-changes 0.3.3-wrap-unwrap.30 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/playwrightHelpers.d.ts +2 -2
- package/dist/__tests__/playwrightPage.d.ts +2 -50
- package/dist/commands.js +43 -222
- package/dist/ensureSelectionPlugin.js +3 -3
- package/dist/features/joinOnDelete/index.d.ts +19 -4
- package/dist/features/joinOnDelete/index.js +53 -166
- package/dist/generateId.js +4 -31
- package/dist/index.d.ts +2 -5
- package/dist/index.js +2 -4
- package/dist/replaceStep.d.ts +1 -1
- package/dist/schema.d.ts +1 -2
- package/dist/schema.js +1 -37
- package/dist/testing/testBuilders.d.ts +2 -1
- package/dist/utils.d.ts +0 -1
- package/dist/utils.js +2 -6
- package/dist/withSuggestChanges.d.ts +14 -11
- package/dist/withSuggestChanges.js +94 -64
- package/package.json +1 -1
- package/src/features/joinOnDelete/README.md +8 -0
- package/dist/features/joinOnDelete/__tests__/joinOnDeleteInLists.playwright.test.d.ts +0 -1
- package/dist/features/joinOnDelete/__tests__/joinOnDeleteInListsTipTapStyle.playwright.test.d.ts +0 -1
- package/dist/features/joinOnDelete/__tests__/listWithJoinsAndStructureMarks.playwright.test.d.ts +0 -1
- package/dist/features/joinOnDelete/normalizeJoinNodesMetadata.d.ts +0 -6
- package/dist/features/joinOnDelete/normalizeJoinNodesMetadata.js +0 -24
- package/dist/features/joinOnDelete/types.d.ts +0 -36
- package/dist/features/joinOnDelete/types.js +0 -23
- package/dist/features/transactionShaping/detectSpecialTransactionShape.d.ts +0 -3
- package/dist/features/transactionShaping/detectSpecialTransactionShape.js +0 -4
- package/dist/features/transactionShaping/index.d.ts +0 -3
- package/dist/features/transactionShaping/index.js +0 -11
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.d.ts +0 -3
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.js +0 -48
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.test.d.ts +0 -1
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.test.js +0 -188
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/handleTipTapParagraphIntoListJoin.d.ts +0 -3
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/handleTipTapParagraphIntoListJoin.js +0 -64
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/index.d.ts +0 -2
- package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/index.js +0 -2
- package/dist/features/transactionShaping/types.d.ts +0 -20
- package/dist/features/transactionShaping/types.js +0 -1
- package/dist/features/wrapUnwrap/__tests__/blockquoteStructure.playwright.test.d.ts +0 -1
- package/dist/features/wrapUnwrap/__tests__/buildMaterializedPaths.test.d.ts +0 -1
- package/dist/features/wrapUnwrap/__tests__/listStructure.playwright.test.d.ts +0 -1
- package/dist/features/wrapUnwrap/__tests__/listStructureTextEdits.playwright.test.d.ts +0 -1
- package/dist/features/wrapUnwrap/__tests__/splitDetection.test.d.ts +0 -1
- package/dist/features/wrapUnwrap/addIdAttr.d.ts +0 -2
- package/dist/features/wrapUnwrap/addIdAttr.js +0 -60
- package/dist/features/wrapUnwrap/apply/applyStructureSuggestions.d.ts +0 -10
- package/dist/features/wrapUnwrap/apply/applyStructureSuggestions.js +0 -41
- package/dist/features/wrapUnwrap/apply/index.d.ts +0 -5
- package/dist/features/wrapUnwrap/apply/index.js +0 -21
- package/dist/features/wrapUnwrap/areEquivalentStructureMarks.d.ts +0 -2
- package/dist/features/wrapUnwrap/areEquivalentStructureMarks.js +0 -17
- package/dist/features/wrapUnwrap/buildMaterializedPaths.d.ts +0 -3
- package/dist/features/wrapUnwrap/buildMaterializedPaths.js +0 -82
- package/dist/features/wrapUnwrap/constants.d.ts +0 -3
- package/dist/features/wrapUnwrap/constants.js +0 -3
- package/dist/features/wrapUnwrap/generateUniqueNodeId.d.ts +0 -1
- package/dist/features/wrapUnwrap/generateUniqueNodeId.js +0 -6
- package/dist/features/wrapUnwrap/getNodeId.d.ts +0 -2
- package/dist/features/wrapUnwrap/getNodeId.js +0 -5
- package/dist/features/wrapUnwrap/revert/deleteNodeUpwards.d.ts +0 -3
- package/dist/features/wrapUnwrap/revert/deleteNodeUpwards.js +0 -37
- package/dist/features/wrapUnwrap/revert/index.d.ts +0 -5
- package/dist/features/wrapUnwrap/revert/index.js +0 -19
- package/dist/features/wrapUnwrap/revert/revertAddOp.d.ts +0 -4
- package/dist/features/wrapUnwrap/revert/revertAddOp.js +0 -4
- package/dist/features/wrapUnwrap/revert/revertMoveOp.d.ts +0 -16
- package/dist/features/wrapUnwrap/revert/revertMoveOp.js +0 -122
- package/dist/features/wrapUnwrap/revert/revertStructureSuggestions.d.ts +0 -10
- package/dist/features/wrapUnwrap/revert/revertStructureSuggestions.js +0 -236
- package/dist/features/wrapUnwrap/sameParentChain.d.ts +0 -2
- package/dist/features/wrapUnwrap/sameParentChain.js +0 -4
- package/dist/features/wrapUnwrap/structureChangesPlugin.d.ts +0 -17
- package/dist/features/wrapUnwrap/structureChangesPlugin.js +0 -299
- package/dist/features/wrapUnwrap/types.d.ts +0 -54
- package/dist/features/wrapUnwrap/types.js +0 -23
- package/dist/features/wrapUnwrap/uniqueNodeIdsPlugin.d.ts +0 -17
- package/dist/features/wrapUnwrap/uniqueNodeIdsPlugin.js +0 -106
- package/dist/listInputRules.d.ts +0 -2
- package/dist/listInputRules.js +0 -14
- package/dist/rebaseStep.d.ts +0 -9
- package/dist/rebaseStep.js +0 -11
- package/dist/testing/e2eTestSchema.d.ts +0 -2
- package/dist/transformToSuggestionTransaction.d.ts +0 -22
- package/dist/transformToSuggestionTransaction.js +0 -101
- package/dist/wrappingInputRule.d.ts +0 -4
- package/dist/wrappingInputRule.js +0 -28
|
@@ -2,104 +2,41 @@ import { Mark } from "prosemirror-model";
|
|
|
2
2
|
import { canJoin, Transform } from "prosemirror-transform";
|
|
3
3
|
import { ZWSP } from "../../constants.js";
|
|
4
4
|
import { getSuggestionMarks } from "../../utils.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
marks: node.marks.map((mark)=>mark.toJSON())
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
function marksFromJSON(schema, markData) {
|
|
17
|
-
return markData.map((markData)=>Mark.fromJSON(schema, markData));
|
|
18
|
-
}
|
|
19
|
-
// when we revert a block join deletion mark, we restore nodes on both sides of the mark using leftNodes rightNodes metadata
|
|
20
|
-
// but existing left and right nodes may have structure marks that we need to preserve
|
|
21
|
-
function mergeSerializedMarksWithCurrentStructureMarks(tr, pos, serializedMarks) {
|
|
22
|
-
const currentNode = tr.doc.nodeAt(pos);
|
|
23
|
-
if (!currentNode) return serializedMarks;
|
|
24
|
-
const { structure } = getSuggestionMarks(tr.doc.type.schema);
|
|
25
|
-
const mergedMarks = [
|
|
26
|
-
...serializedMarks
|
|
27
|
-
];
|
|
28
|
-
for (const currentMark of currentNode.marks){
|
|
29
|
-
if (currentMark.type !== structure) continue;
|
|
30
|
-
const alreadyIncluded = mergedMarks.some((mark)=>mark.type === structure && areEquivalentStructureMarks(mark, currentMark));
|
|
31
|
-
if (!alreadyIncluded) {
|
|
32
|
-
mergedMarks.push(currentMark);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return mergedMarks;
|
|
36
|
-
}
|
|
37
|
-
function restoreNodeMarkup(tr, pos, node) {
|
|
38
|
-
const nodeType = tr.doc.type.schema.nodes[node.type];
|
|
39
|
-
if (!nodeType) return false;
|
|
40
|
-
const marks = mergeSerializedMarksWithCurrentStructureMarks(tr, pos, marksFromJSON(tr.doc.type.schema, node.marks));
|
|
41
|
-
tr.setNodeMarkup(pos, nodeType, node.attrs, marks);
|
|
5
|
+
export function isJoinMarkAttrs(attrs) {
|
|
6
|
+
if (attrs["type"] !== "join") return false;
|
|
7
|
+
if (attrs["data"] == null) return false;
|
|
8
|
+
const data = attrs["data"];
|
|
9
|
+
if (data.leftNode == null || data.rightNode == null) return false;
|
|
10
|
+
if (typeof data.leftNode.type !== "string" || typeof data.rightNode.type !== "string") return false;
|
|
11
|
+
if (typeof data.leftNode.attrs !== "object" || typeof data.rightNode.attrs !== "object") return false;
|
|
12
|
+
if (!Array.isArray(data.leftNode.marks) || !Array.isArray(data.rightNode.marks)) return false;
|
|
42
13
|
return true;
|
|
43
14
|
}
|
|
44
|
-
// collect structure suggestion IDs that will be re-introduced into the document after the join is reverted
|
|
45
|
-
function getRestoredStructureSuggestionIds(joinNodes, schema) {
|
|
46
|
-
const { structure } = getSuggestionMarks(schema);
|
|
47
|
-
const restoredStructureSuggestionIds = new Set();
|
|
48
|
-
for (const node of [
|
|
49
|
-
...joinNodes.leftNodes,
|
|
50
|
-
...joinNodes.rightNodes
|
|
51
|
-
]){
|
|
52
|
-
const marks = marksFromJSON(schema, node.marks);
|
|
53
|
-
for (const mark of marks){
|
|
54
|
-
if (mark.type !== structure) continue;
|
|
55
|
-
if (!guardStructureMarkAttrs(mark.attrs)) continue;
|
|
56
|
-
restoredStructureSuggestionIds.add(mark.attrs.id);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return restoredStructureSuggestionIds;
|
|
60
|
-
}
|
|
61
15
|
export function maybeRevertJoinMark(tr, from, to, node, markType) {
|
|
62
16
|
const mark = node.marks.find((mark)=>mark.type === markType);
|
|
63
|
-
if (!mark ||
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
...joinNodes.rightNodes
|
|
69
|
-
]){
|
|
70
|
-
const nodeType = tr.doc.type.schema.nodes[node.type];
|
|
71
|
-
if (!nodeType) return false;
|
|
72
|
-
try {
|
|
73
|
-
marksFromJSON(tr.doc.type.schema, node.marks);
|
|
74
|
-
} catch {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
const restoredStructureSuggestionIds = getRestoredStructureSuggestionIds(joinNodes, tr.doc.type.schema);
|
|
79
|
-
// Reverting a join marker removes its ZWSP anchor, splits at that position,
|
|
80
|
-
// and restores markup because ProseMirror split creates nodes with defaults.
|
|
81
|
-
const joinDepth = joinNodes.leftNodes.length;
|
|
17
|
+
if (!mark || mark.attrs["type"] !== "join" || node.text !== ZWSP) return false;
|
|
18
|
+
// this is a mark of type join
|
|
19
|
+
// split the current node at this mark position
|
|
20
|
+
// delete this mark together with its zwsp content
|
|
21
|
+
// assign left and right node (after the split) properties from the mark's data
|
|
82
22
|
tr.delete(from, to);
|
|
83
|
-
tr.split(from
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
restoredStructureSuggestionIds
|
|
102
|
-
};
|
|
23
|
+
tr.split(from);
|
|
24
|
+
// insertionFrom is now at the end of the left node (but before the closing token)
|
|
25
|
+
// after() will give us the position after the closing token (but before the next opening token) - exactly the split pos
|
|
26
|
+
const $insertionFrom = tr.doc.resolve(from);
|
|
27
|
+
const $splitPos = tr.doc.resolve($insertionFrom.after());
|
|
28
|
+
const { attrs } = mark;
|
|
29
|
+
if (!isJoinMarkAttrs(attrs) || !$splitPos.nodeBefore || !$splitPos.nodeAfter) return false;
|
|
30
|
+
// restore left and right node type, attrs and marks, as they were before the join
|
|
31
|
+
const { leftNode, rightNode } = attrs.data;
|
|
32
|
+
const leftNodeType = tr.doc.type.schema.nodes[leftNode.type];
|
|
33
|
+
const rightNodeType = tr.doc.type.schema.nodes[rightNode.type];
|
|
34
|
+
const leftNodeMarks = leftNode.marks.map((markData)=>Mark.fromJSON(tr.doc.type.schema, markData));
|
|
35
|
+
const rightNodeMarks = rightNode.marks.map((markData)=>Mark.fromJSON(tr.doc.type.schema, markData));
|
|
36
|
+
if (!leftNodeType || !rightNodeType) return false;
|
|
37
|
+
tr.setNodeMarkup($splitPos.pos - $splitPos.nodeBefore.nodeSize, leftNodeType, leftNode.attrs, leftNodeMarks);
|
|
38
|
+
tr.setNodeMarkup($splitPos.pos, rightNodeType, rightNode.attrs, rightNodeMarks);
|
|
39
|
+
return true;
|
|
103
40
|
}
|
|
104
41
|
/**
|
|
105
42
|
* Remove ZWSP text nodes marked as deletions (except for type=join) from the given range
|
|
@@ -135,95 +72,45 @@ export function maybeRevertJoinMark(tr, from, to, node, markType) {
|
|
|
135
72
|
doc.nodesBetween(blockRange.start, blockRange.end, (node, pos)=>{
|
|
136
73
|
if (node.isInline) return false;
|
|
137
74
|
const endOfNode = pos + node.nodeSize;
|
|
75
|
+
// make sure the node ends within the range
|
|
138
76
|
if (endOfNode >= blockRange.$to.pos) return true;
|
|
139
|
-
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
77
|
+
const $endOfNode = doc.resolve(endOfNode);
|
|
78
|
+
// make sure we are between two nodes
|
|
79
|
+
if (!$endOfNode.nodeBefore || !$endOfNode.nodeAfter) return false;
|
|
80
|
+
// we cannot insert zwsp text nodes into non-textblock nodes
|
|
81
|
+
if (!$endOfNode.nodeBefore.isTextblock || !$endOfNode.nodeAfter.isTextblock) return true;
|
|
82
|
+
const mappedEndOfNode = transform.mapping.map(endOfNode);
|
|
83
|
+
const $mappedEndOfNode = transform.doc.resolve(mappedEndOfNode);
|
|
84
|
+
if (!canJoin(transform.doc, mappedEndOfNode) || !$mappedEndOfNode.nodeBefore || !$mappedEndOfNode.nodeAfter) {
|
|
145
85
|
return true;
|
|
146
86
|
}
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
87
|
+
const leftNode = {
|
|
88
|
+
type: $endOfNode.nodeBefore.type.name,
|
|
89
|
+
attrs: $endOfNode.nodeBefore.attrs,
|
|
90
|
+
marks: $endOfNode.nodeBefore.marks.map((mark)=>mark.toJSON())
|
|
91
|
+
};
|
|
92
|
+
const rightNode = {
|
|
93
|
+
type: $endOfNode.nodeAfter.type.name,
|
|
94
|
+
attrs: $endOfNode.nodeAfter.attrs,
|
|
95
|
+
marks: $endOfNode.nodeAfter.marks.map((mark)=>mark.toJSON())
|
|
96
|
+
};
|
|
97
|
+
transform.join(mappedEndOfNode);
|
|
155
98
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
156
99
|
const joinStep = transform.steps[transform.steps.length - 1];
|
|
157
|
-
const joinPos = joinStep.getMap().map(
|
|
100
|
+
const joinPos = joinStep.getMap().map(mappedEndOfNode);
|
|
158
101
|
transform.insert(joinPos, transform.doc.type.schema.text(ZWSP));
|
|
159
102
|
transform.addMark(joinPos, joinPos + 1, deletion.create({
|
|
160
103
|
id: markId,
|
|
161
104
|
type: "join",
|
|
162
105
|
data: {
|
|
163
|
-
|
|
164
|
-
|
|
106
|
+
leftNode,
|
|
107
|
+
rightNode
|
|
165
108
|
}
|
|
166
109
|
}));
|
|
167
110
|
return false;
|
|
168
111
|
});
|
|
169
112
|
return transform;
|
|
170
113
|
}
|
|
171
|
-
function getJoinCandidateAtBoundary(doc, boundaryPos, from, to, maxJoinDepth) {
|
|
172
|
-
const $boundary = doc.resolve(boundaryPos);
|
|
173
|
-
const leftNode = $boundary.nodeBefore;
|
|
174
|
-
const rightNode = $boundary.nodeAfter;
|
|
175
|
-
// Multi-depth list joins can begin between structural nodes, not just textblocks.
|
|
176
|
-
if (!leftNode || !rightNode) return null;
|
|
177
|
-
if (leftNode.isInline || rightNode.isInline) return null;
|
|
178
|
-
if (!canJoin(doc, boundaryPos)) return null;
|
|
179
|
-
const pairs = [
|
|
180
|
-
{
|
|
181
|
-
leftNode,
|
|
182
|
-
rightNode
|
|
183
|
-
}
|
|
184
|
-
];
|
|
185
|
-
for(let expandBy = 1; pairs.length < maxJoinDepth; expandBy += 1){
|
|
186
|
-
const left = boundaryPos - expandBy;
|
|
187
|
-
const right = boundaryPos + expandBy;
|
|
188
|
-
if (left < from || right > to) break;
|
|
189
|
-
const $left = doc.resolve(left);
|
|
190
|
-
const $right = doc.resolve(right);
|
|
191
|
-
// Once text is adjacent, there is no deeper block pair to capture.
|
|
192
|
-
if ($left.nodeBefore?.isText || $right.nodeAfter?.isText) break;
|
|
193
|
-
if ($left.nodeAfter === null && $left.nodeBefore && !$left.nodeBefore.isInline && $right.nodeBefore === null && $right.nodeAfter && !$right.nodeAfter.isInline) {
|
|
194
|
-
pairs.push({
|
|
195
|
-
leftNode: $left.nodeBefore,
|
|
196
|
-
rightNode: $right.nodeAfter
|
|
197
|
-
});
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
// canJoin only checks the boundary; the temporary transform verifies depth.
|
|
203
|
-
if (!canApplyJoinCandidate(doc, boundaryPos, pairs.length)) return null;
|
|
204
|
-
return {
|
|
205
|
-
joinPos: boundaryPos,
|
|
206
|
-
leftNodes: pairs.map((pair)=>pair.leftNode).reverse(),
|
|
207
|
-
rightNodes: pairs.map((pair)=>pair.rightNode).reverse()
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
function canApplyJoinCandidate(doc, joinPos, depth) {
|
|
211
|
-
if (!canJoin(doc, joinPos)) return false;
|
|
212
|
-
try {
|
|
213
|
-
new Transform(doc).join(joinPos, depth);
|
|
214
|
-
return true;
|
|
215
|
-
} catch {
|
|
216
|
-
return false;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
function hasStructureAddMark(node) {
|
|
220
|
-
const { structure } = getSuggestionMarks(node.type.schema);
|
|
221
|
-
return node.marks.some((mark)=>{
|
|
222
|
-
if (mark.type !== structure) return false;
|
|
223
|
-
if (!guardStructureMarkAttrs(mark.attrs)) return false;
|
|
224
|
-
return mark.attrs.data.op.op === "add";
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
114
|
/**
|
|
228
115
|
* Find ZWSP nodes marked as insertions and deletions with the same mark id
|
|
229
116
|
* Delete them from the given range
|
package/dist/generateId.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { getSuggestionMarks } from "./utils.js";
|
|
2
|
-
import { isJoinMark } from "./features/joinOnDelete/types.js";
|
|
3
|
-
import { normalizeJoinNodesMetadata } from "./features/joinOnDelete/normalizeJoinNodesMetadata.js";
|
|
4
2
|
export const suggestionIdValidate = "number|string";
|
|
5
3
|
export function parseSuggestionId(id) {
|
|
6
4
|
const parsed = parseInt(id, 10);
|
|
@@ -10,39 +8,14 @@ export function parseSuggestionId(id) {
|
|
|
10
8
|
return parsed;
|
|
11
9
|
}
|
|
12
10
|
export function generateNextNumberId(schema, doc) {
|
|
13
|
-
const { deletion, insertion, modification
|
|
11
|
+
const { deletion, insertion, modification } = getSuggestionMarks(schema);
|
|
14
12
|
// Find the highest change id in the document so far,
|
|
15
13
|
// and use that as the starting point for new changes
|
|
16
14
|
let suggestionId = 0;
|
|
17
15
|
doc?.descendants((node)=>{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// collect suggestion ids of marks that are serialized into join marks metadata
|
|
22
|
-
const joinMarks = marks.filter((mark)=>isJoinMark(mark));
|
|
23
|
-
const joinMetadataMarkIds = [];
|
|
24
|
-
joinMarks.forEach((mark)=>{
|
|
25
|
-
const joinMetadata = normalizeJoinNodesMetadata(mark.attrs);
|
|
26
|
-
if (!joinMetadata) return;
|
|
27
|
-
joinMetadata.leftNodes.forEach((node)=>{
|
|
28
|
-
node.marks.forEach((mark)=>{
|
|
29
|
-
if (!mark.attrs["id"]) return;
|
|
30
|
-
joinMetadataMarkIds.push(mark.attrs["id"]);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
joinMetadata.rightNodes.forEach((node)=>{
|
|
34
|
-
node.marks.forEach((mark)=>{
|
|
35
|
-
if (!mark.attrs["id"]) return;
|
|
36
|
-
joinMetadataMarkIds.push(mark.attrs["id"]);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
const allMarkIds = [
|
|
41
|
-
...markIds,
|
|
42
|
-
...joinMetadataMarkIds
|
|
43
|
-
];
|
|
44
|
-
if (allMarkIds.length > 0) {
|
|
45
|
-
suggestionId = Math.max(suggestionId, ...allMarkIds);
|
|
16
|
+
const mark = node.marks.find((mark)=>mark.type === insertion || mark.type === deletion || mark.type === modification);
|
|
17
|
+
if (mark) {
|
|
18
|
+
suggestionId = Math.max(suggestionId, mark.attrs["id"]);
|
|
46
19
|
return false;
|
|
47
20
|
}
|
|
48
21
|
return true;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
export { addSuggestionMarks, insertion, deletion, modification, hiddenDeletion,
|
|
1
|
+
export { addSuggestionMarks, insertion, deletion, modification, hiddenDeletion, } from "./schema.js";
|
|
2
2
|
export { selectSuggestion, revertSuggestion, revertSuggestions, applySuggestion, applySuggestions, enableSuggestChanges, disableSuggestChanges, toggleSuggestChanges, } from "./commands.js";
|
|
3
3
|
export { suggestChanges, suggestChangesKey, isSuggestChangesEnabled, } from "./plugin.js";
|
|
4
|
-
export { withSuggestChanges, transformToSuggestionTransaction,
|
|
4
|
+
export { withSuggestChanges, transformToSuggestionTransaction, } from "./withSuggestChanges.js";
|
|
5
5
|
export { ensureSelection as experimental_ensureSelection, ensureSelectionKey as experimental_ensureSelectionKey, isEnsureSelectionEnabled as experimental_isEnsureSelectionEnabled, } from "./ensureSelectionPlugin.js";
|
|
6
|
-
export { guardStructureMarkAttrs } from "./features/wrapUnwrap/types.js";
|
|
7
|
-
export type { Op as StructureOp, StructureMarkAttrs, StructuralContextPath, } from "./features/wrapUnwrap/types.js";
|
|
8
|
-
export { wrappingInputRule as experimental_wrappingInputRule } from "./wrappingInputRule.js";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
export { addSuggestionMarks, insertion, deletion, modification, hiddenDeletion
|
|
1
|
+
export { addSuggestionMarks, insertion, deletion, modification, hiddenDeletion } from "./schema.js";
|
|
2
2
|
export { selectSuggestion, revertSuggestion, revertSuggestions, applySuggestion, applySuggestions, enableSuggestChanges, disableSuggestChanges, toggleSuggestChanges } from "./commands.js";
|
|
3
3
|
export { suggestChanges, suggestChangesKey, isSuggestChangesEnabled } from "./plugin.js";
|
|
4
|
-
export { withSuggestChanges, transformToSuggestionTransaction
|
|
4
|
+
export { withSuggestChanges, transformToSuggestionTransaction } from "./withSuggestChanges.js";
|
|
5
5
|
export { ensureSelection as experimental_ensureSelection, ensureSelectionKey as experimental_ensureSelectionKey, isEnsureSelectionEnabled as experimental_isEnsureSelectionEnabled } from "./ensureSelectionPlugin.js";
|
|
6
|
-
export { guardStructureMarkAttrs } from "./features/wrapUnwrap/types.js";
|
|
7
|
-
export { wrappingInputRule as experimental_wrappingInputRule } from "./wrappingInputRule.js";
|
package/dist/replaceStep.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Node } from "prosemirror-model";
|
|
2
2
|
import { type EditorState, type Transaction } from "prosemirror-state";
|
|
3
|
-
import { type
|
|
3
|
+
import { type Step, type ReplaceStep } from "prosemirror-transform";
|
|
4
4
|
import { type SuggestionId } from "./generateId.js";
|
|
5
5
|
/**
|
|
6
6
|
* Transform a replace step into its equivalent tracked steps.
|
package/dist/schema.d.ts
CHANGED
|
@@ -3,11 +3,10 @@ export declare const deletion: MarkSpec;
|
|
|
3
3
|
export declare const hiddenDeletion: MarkSpec;
|
|
4
4
|
export declare const insertion: MarkSpec;
|
|
5
5
|
export declare const modification: MarkSpec;
|
|
6
|
-
export declare const structure: MarkSpec;
|
|
7
6
|
/**
|
|
8
7
|
* Add the deletion, insertion, and modification marks to
|
|
9
8
|
* the provided MarkSpec map.
|
|
10
9
|
*/
|
|
11
10
|
export declare function addSuggestionMarks<Marks extends string>(marks: Record<Marks, MarkSpec>, opts?: {
|
|
12
11
|
experimental_deletions?: "hidden" | "visible";
|
|
13
|
-
}): Record<Marks | "deletion" | "insertion" | "modification"
|
|
12
|
+
}): Record<Marks | "deletion" | "insertion" | "modification", MarkSpec>;
|
package/dist/schema.js
CHANGED
|
@@ -166,41 +166,6 @@ export const modification = {
|
|
|
166
166
|
}
|
|
167
167
|
]
|
|
168
168
|
};
|
|
169
|
-
export const structure = {
|
|
170
|
-
inclusive: false,
|
|
171
|
-
excludes: "deletion insertion modification",
|
|
172
|
-
attrs: {
|
|
173
|
-
id: {
|
|
174
|
-
validate: suggestionIdValidate
|
|
175
|
-
},
|
|
176
|
-
data: {
|
|
177
|
-
default: null
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
toDOM (mark) {
|
|
181
|
-
return [
|
|
182
|
-
"div",
|
|
183
|
-
{
|
|
184
|
-
"data-type": "structure",
|
|
185
|
-
"data-id": JSON.stringify(mark.attrs["id"]),
|
|
186
|
-
"data-data": JSON.stringify(mark.attrs["data"])
|
|
187
|
-
},
|
|
188
|
-
0
|
|
189
|
-
];
|
|
190
|
-
},
|
|
191
|
-
parseDOM: [
|
|
192
|
-
{
|
|
193
|
-
tag: "div[data-type='structure']",
|
|
194
|
-
getAttrs (node) {
|
|
195
|
-
if (!node.dataset["id"]) return false;
|
|
196
|
-
return {
|
|
197
|
-
id: JSON.parse(node.dataset["id"]),
|
|
198
|
-
data: JSON.parse(node.dataset["data"] ?? "null")
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
]
|
|
203
|
-
};
|
|
204
169
|
/**
|
|
205
170
|
* Add the deletion, insertion, and modification marks to
|
|
206
171
|
* the provided MarkSpec map.
|
|
@@ -209,7 +174,6 @@ export const structure = {
|
|
|
209
174
|
...marks,
|
|
210
175
|
deletion: opts?.experimental_deletions === "hidden" ? hiddenDeletion : deletion,
|
|
211
176
|
insertion,
|
|
212
|
-
modification
|
|
213
|
-
structure
|
|
177
|
+
modification
|
|
214
178
|
};
|
|
215
179
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Schema, type Node } from "prosemirror-model";
|
|
2
2
|
import { type MarkBuilder, type NodeBuilder } from "prosemirror-test-builder";
|
|
3
|
-
|
|
3
|
+
declare const schema: Schema<"blockquote" | "text" | "doc" | "paragraph" | "image" | "orderedList" | "bulletList" | "listItem" | "horizontal_rule" | "heading" | "code_block" | "hard_break", "insertion" | "deletion" | "modification" | "code" | "em" | "link" | "strong" | "difficulty">;
|
|
4
4
|
export declare const testBuilders: { [NodeTypeName in keyof (typeof schema)["nodes"]]: NodeBuilder; } & { [MarkTypeName in keyof (typeof schema)["marks"]]: MarkBuilder; } & {
|
|
5
5
|
schema: typeof schema;
|
|
6
6
|
};
|
|
@@ -8,3 +8,4 @@ export type TaggedNode = Node & {
|
|
|
8
8
|
flat: Node;
|
|
9
9
|
tag: Record<string, number>;
|
|
10
10
|
};
|
|
11
|
+
export {};
|
package/dist/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Get the suggestion mark types from a schema, with proper error handling.
|
|
3
3
|
* Throws an error if any of the required marks are not found.
|
|
4
4
|
*/ export function getSuggestionMarks(schema) {
|
|
5
|
-
const { insertion, deletion, modification
|
|
5
|
+
const { insertion, deletion, modification } = schema.marks;
|
|
6
6
|
if (!insertion) {
|
|
7
7
|
throw new Error("Failed to find insertion mark in schema. Did you forget to add it?");
|
|
8
8
|
}
|
|
@@ -12,13 +12,9 @@
|
|
|
12
12
|
if (!modification) {
|
|
13
13
|
throw new Error("Failed to find modification mark in schema. Did you forget to add it?");
|
|
14
14
|
}
|
|
15
|
-
if (!structure) {
|
|
16
|
-
throw new Error("Failed to find structure mark in schema. Did you forget to add it?");
|
|
17
|
-
}
|
|
18
15
|
return {
|
|
19
16
|
insertion,
|
|
20
17
|
deletion,
|
|
21
|
-
modification
|
|
22
|
-
structure
|
|
18
|
+
modification
|
|
23
19
|
};
|
|
24
20
|
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type Transaction } from "prosemirror-state";
|
|
3
|
-
import { type Transform } from "prosemirror-transform";
|
|
1
|
+
import { type Schema, type Node } from "prosemirror-model";
|
|
2
|
+
import { type EditorState, type Transaction } from "prosemirror-state";
|
|
4
3
|
import { type EditorView } from "prosemirror-view";
|
|
5
4
|
import { type SuggestionId } from "./generateId.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Given a standard transaction from ProseMirror, produce
|
|
7
|
+
* a new transaction that tracks the changes from the original,
|
|
8
|
+
* rather than applying them.
|
|
9
|
+
*
|
|
10
|
+
* For each type of step, we implement custom behavior to prevent
|
|
11
|
+
* deletions from being removed from the document, instead adding
|
|
12
|
+
* deletion marks, and ensuring that all insertions have insertion
|
|
13
|
+
* marks.
|
|
14
|
+
*/
|
|
15
|
+
export declare function transformToSuggestionTransaction(originalTransaction: Transaction, state: EditorState, generateId?: (schema: Schema, doc?: Node) => SuggestionId): Transaction;
|
|
9
16
|
/**
|
|
10
17
|
* A `dispatchTransaction` decorator. Wrap your existing `dispatchTransaction`
|
|
11
18
|
* function with `withSuggestChanges`, or pass no arguments to use the default
|
|
@@ -17,8 +24,4 @@ export { suggestStructureChanges } from "./features/wrapUnwrap/structureChangesP
|
|
|
17
24
|
* applying them, e.g. by marking a range with the deletion mark rather
|
|
18
25
|
* than removing it from the document.
|
|
19
26
|
*/
|
|
20
|
-
export declare function withSuggestChanges(dispatchTransaction?: EditorView["dispatch"], generateId?: (schema: Schema, doc?: Node) => SuggestionId
|
|
21
|
-
experimental_trackStructureChanges?: boolean;
|
|
22
|
-
experimental_trackStructures?: StructuralContextPath[];
|
|
23
|
-
experimental_ensureUniqueNodeIds?: (transactions: Transaction[], oldDoc: Node, newDoc: Node) => Transform;
|
|
24
|
-
}): EditorView["dispatch"];
|
|
27
|
+
export declare function withSuggestChanges(dispatchTransaction?: EditorView["dispatch"], generateId?: (schema: Schema, doc?: Node) => SuggestionId): EditorView["dispatch"];
|