@magic-marker/prosemirror-suggest-changes 0.3.3-wrap-unwrap.29 → 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.
Files changed (88) hide show
  1. package/dist/__tests__/playwrightHelpers.d.ts +2 -2
  2. package/dist/__tests__/playwrightPage.d.ts +2 -50
  3. package/dist/commands.js +43 -178
  4. package/dist/ensureSelectionPlugin.js +3 -3
  5. package/dist/features/joinOnDelete/index.d.ts +19 -4
  6. package/dist/features/joinOnDelete/index.js +53 -166
  7. package/dist/generateId.js +4 -31
  8. package/dist/index.d.ts +2 -5
  9. package/dist/index.js +2 -4
  10. package/dist/replaceStep.d.ts +1 -1
  11. package/dist/schema.d.ts +1 -2
  12. package/dist/schema.js +1 -37
  13. package/dist/testing/testBuilders.d.ts +2 -1
  14. package/dist/utils.d.ts +0 -1
  15. package/dist/utils.js +2 -6
  16. package/dist/withSuggestChanges.d.ts +14 -11
  17. package/dist/withSuggestChanges.js +94 -64
  18. package/package.json +1 -1
  19. package/src/features/joinOnDelete/README.md +8 -0
  20. package/dist/features/joinOnDelete/__tests__/joinOnDeleteInLists.playwright.test.d.ts +0 -1
  21. package/dist/features/joinOnDelete/__tests__/joinOnDeleteInListsTipTapStyle.playwright.test.d.ts +0 -1
  22. package/dist/features/joinOnDelete/__tests__/listWithJoinsAndStructureMarks.playwright.test.d.ts +0 -1
  23. package/dist/features/joinOnDelete/normalizeJoinNodesMetadata.d.ts +0 -6
  24. package/dist/features/joinOnDelete/normalizeJoinNodesMetadata.js +0 -24
  25. package/dist/features/joinOnDelete/types.d.ts +0 -34
  26. package/dist/features/joinOnDelete/types.js +0 -20
  27. package/dist/features/transactionShaping/detectSpecialTransactionShape.d.ts +0 -3
  28. package/dist/features/transactionShaping/detectSpecialTransactionShape.js +0 -4
  29. package/dist/features/transactionShaping/index.d.ts +0 -3
  30. package/dist/features/transactionShaping/index.js +0 -11
  31. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.d.ts +0 -3
  32. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.js +0 -48
  33. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.test.d.ts +0 -1
  34. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.test.js +0 -188
  35. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/handleTipTapParagraphIntoListJoin.d.ts +0 -3
  36. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/handleTipTapParagraphIntoListJoin.js +0 -64
  37. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/index.d.ts +0 -2
  38. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/index.js +0 -2
  39. package/dist/features/transactionShaping/types.d.ts +0 -20
  40. package/dist/features/transactionShaping/types.js +0 -1
  41. package/dist/features/wrapUnwrap/__tests__/blockquoteStructure.playwright.test.d.ts +0 -1
  42. package/dist/features/wrapUnwrap/__tests__/buildMaterializedPaths.test.d.ts +0 -1
  43. package/dist/features/wrapUnwrap/__tests__/listStructure.playwright.test.d.ts +0 -1
  44. package/dist/features/wrapUnwrap/__tests__/listStructureTextEdits.playwright.test.d.ts +0 -1
  45. package/dist/features/wrapUnwrap/__tests__/splitDetection.test.d.ts +0 -1
  46. package/dist/features/wrapUnwrap/addIdAttr.d.ts +0 -2
  47. package/dist/features/wrapUnwrap/addIdAttr.js +0 -60
  48. package/dist/features/wrapUnwrap/apply/applyStructureSuggestions.d.ts +0 -10
  49. package/dist/features/wrapUnwrap/apply/applyStructureSuggestions.js +0 -41
  50. package/dist/features/wrapUnwrap/apply/index.d.ts +0 -5
  51. package/dist/features/wrapUnwrap/apply/index.js +0 -21
  52. package/dist/features/wrapUnwrap/areEquivalentStructureMarks.d.ts +0 -2
  53. package/dist/features/wrapUnwrap/areEquivalentStructureMarks.js +0 -17
  54. package/dist/features/wrapUnwrap/buildMaterializedPaths.d.ts +0 -3
  55. package/dist/features/wrapUnwrap/buildMaterializedPaths.js +0 -82
  56. package/dist/features/wrapUnwrap/constants.d.ts +0 -3
  57. package/dist/features/wrapUnwrap/constants.js +0 -3
  58. package/dist/features/wrapUnwrap/generateUniqueNodeId.d.ts +0 -1
  59. package/dist/features/wrapUnwrap/generateUniqueNodeId.js +0 -6
  60. package/dist/features/wrapUnwrap/getNodeId.d.ts +0 -2
  61. package/dist/features/wrapUnwrap/getNodeId.js +0 -5
  62. package/dist/features/wrapUnwrap/revert/deleteNodeUpwards.d.ts +0 -3
  63. package/dist/features/wrapUnwrap/revert/deleteNodeUpwards.js +0 -37
  64. package/dist/features/wrapUnwrap/revert/index.d.ts +0 -5
  65. package/dist/features/wrapUnwrap/revert/index.js +0 -19
  66. package/dist/features/wrapUnwrap/revert/revertAddOp.d.ts +0 -4
  67. package/dist/features/wrapUnwrap/revert/revertAddOp.js +0 -4
  68. package/dist/features/wrapUnwrap/revert/revertMoveOp.d.ts +0 -16
  69. package/dist/features/wrapUnwrap/revert/revertMoveOp.js +0 -122
  70. package/dist/features/wrapUnwrap/revert/revertStructureSuggestions.d.ts +0 -10
  71. package/dist/features/wrapUnwrap/revert/revertStructureSuggestions.js +0 -236
  72. package/dist/features/wrapUnwrap/sameParentChain.d.ts +0 -2
  73. package/dist/features/wrapUnwrap/sameParentChain.js +0 -4
  74. package/dist/features/wrapUnwrap/structureChangesPlugin.d.ts +0 -17
  75. package/dist/features/wrapUnwrap/structureChangesPlugin.js +0 -299
  76. package/dist/features/wrapUnwrap/types.d.ts +0 -54
  77. package/dist/features/wrapUnwrap/types.js +0 -23
  78. package/dist/features/wrapUnwrap/uniqueNodeIdsPlugin.d.ts +0 -17
  79. package/dist/features/wrapUnwrap/uniqueNodeIdsPlugin.js +0 -106
  80. package/dist/listInputRules.d.ts +0 -2
  81. package/dist/listInputRules.js +0 -14
  82. package/dist/rebaseStep.d.ts +0 -9
  83. package/dist/rebaseStep.js +0 -11
  84. package/dist/testing/e2eTestSchema.d.ts +0 -2
  85. package/dist/transformToSuggestionTransaction.d.ts +0 -22
  86. package/dist/transformToSuggestionTransaction.js +0 -101
  87. package/dist/wrappingInputRule.d.ts +0 -4
  88. 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
- import { areEquivalentStructureMarks } from "../wrapUnwrap/areEquivalentStructureMarks.js";
6
- import { guardStructureMarkAttrs } from "../wrapUnwrap/types.js";
7
- import { MAX_BLOCK_JOIN_DEPTH, normalizeJoinNodesMetadata } from "./normalizeJoinNodesMetadata.js";
8
- import { isJoinMark } from "./types.js";
9
- function serializeJoinNode(node) {
10
- return {
11
- type: node.type.name,
12
- attrs: node.attrs,
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 || !isJoinMark(mark) || node.text !== ZWSP) return false;
64
- const joinNodes = normalizeJoinNodesMetadata(mark.attrs);
65
- if (!joinNodes) return false;
66
- for (const node of [
67
- ...joinNodes.leftNodes,
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, joinDepth);
84
- const $splitFrom = tr.doc.resolve(from);
85
- const baseDepth = $splitFrom.depth;
86
- let rightPos = $splitFrom.after(baseDepth - joinDepth + 1);
87
- // Metadata is stored child-first, but markup must be restored outer-first so
88
- // positions inside the newly split structure remain addressable.
89
- for(let index = joinDepth - 1; index >= 0; index -= 1){
90
- const leftNode = joinNodes.leftNodes[index];
91
- const rightNode = joinNodes.rightNodes[index];
92
- if (!leftNode || !rightNode) return false;
93
- const leftPos = $splitFrom.before(baseDepth - index);
94
- if (!restoreNodeMarkup(tr, leftPos, leftNode) || !restoreNodeMarkup(tr, rightPos, rightNode)) {
95
- return false;
96
- }
97
- // Each deeper right node starts one position inside the right node restored before it.
98
- rightPos += 1;
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
- // List-item joins can start between non-textblock nodes; expand inward to
140
- // capture the visible textblock pair and its structural parent pair.
141
- const joinCandidate = getJoinCandidateAtBoundary(doc, endOfNode, from, to, MAX_BLOCK_JOIN_DEPTH);
142
- if (!joinCandidate) return true;
143
- const mappedJoinPos = transform.mapping.map(joinCandidate.joinPos);
144
- if (!canApplyJoinCandidate(transform.doc, mappedJoinPos, joinCandidate.leftNodes.length)) {
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 shouldSuppressJoinMark = [
148
- ...joinCandidate.leftNodes,
149
- ...joinCandidate.rightNodes
150
- ].some((node)=>hasStructureAddMark(node));
151
- transform.join(mappedJoinPos, joinCandidate.leftNodes.length);
152
- // Joining provisional structure cancels its pending add instead of creating
153
- // a second review artifact for the same user action.
154
- if (shouldSuppressJoinMark) return false;
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(mappedJoinPos);
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
- leftNodes: joinCandidate.leftNodes.map(serializeJoinNode),
164
- rightNodes: joinCandidate.rightNodes.map(serializeJoinNode)
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
@@ -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, structure } = getSuggestionMarks(schema);
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
- // find max suggestion id across all suggestion marks and across all suggestion marks that are serialized into metadata of the join marks
19
- const marks = node.marks.filter((mark)=>mark.type === insertion || mark.type === deletion || mark.type === modification || mark.type === structure);
20
- const markIds = marks.map((mark)=>mark.attrs["id"]);
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, structure, } from "./schema.js";
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, suggestStructureChanges as experimental_suggestStructureChanges, } from "./withSuggestChanges.js";
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, structure } from "./schema.js";
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, suggestStructureChanges as experimental_suggestStructureChanges } from "./withSuggestChanges.js";
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";
@@ -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 ReplaceStep, type Step } from "prosemirror-transform";
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" | "structure", MarkSpec>;
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
- export declare const schema: Schema<"blockquote" | "text" | "doc" | "paragraph" | "horizontal_rule" | "heading" | "code_block" | "image" | "hard_break" | "orderedList" | "bulletList" | "listItem", "insertion" | "deletion" | "modification" | "structure" | "code" | "em" | "link" | "strong" | "difficulty">;
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
@@ -3,7 +3,6 @@ export interface SuggestionMarks {
3
3
  insertion: MarkType;
4
4
  deletion: MarkType;
5
5
  modification: MarkType;
6
- structure: MarkType;
7
6
  }
8
7
  /**
9
8
  * Get the suggestion mark types from a schema, with proper error handling.
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, structure } = schema.marks;
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 Node, type Schema } from "prosemirror-model";
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
- import { type StructuralContextPath } from "./features/wrapUnwrap/types.js";
7
- export { transformToSuggestionTransaction } from "./transformToSuggestionTransaction.js";
8
- export { suggestStructureChanges } from "./features/wrapUnwrap/structureChangesPlugin.js";
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, opts?: {
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"];