@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.
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 -222
  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 -36
  26. package/dist/features/joinOnDelete/types.js +0 -23
  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
@@ -140,9 +140,9 @@ export declare function assertReverted(finalState: EditorState, initialState: Ed
140
140
  * This helper replaces the editor document with the provided JSON,
141
141
  * clears transactions, and returns initial state.
142
142
  */
143
- export declare function setupDocFromJSON(page: Page, docJSON: object): Promise<{
143
+ export declare function setupDocFromJSON(page: Page, docJSON: unknown): Promise<{
144
144
  initialState: EditorState;
145
- initialDoc: object;
145
+ initialDoc: unknown;
146
146
  }>;
147
147
  /**
148
148
  * Assert that document fully reverted to initial state.
@@ -1,63 +1,15 @@
1
- import { type Node } from "prosemirror-model";
2
1
  import { type Locator, type Page } from "@playwright/test";
3
2
  export declare class EditorPage {
4
3
  readonly page: Page;
5
- readonly deletionMarksVisibility: "hidden" | "visible";
6
4
  private readonly selectors;
7
- constructor(page: Page, deletionMarksVisibility?: "hidden" | "visible");
5
+ constructor(page: Page);
8
6
  get editor(): Locator;
9
- getParagraphText(index: number, childIndexes?: number[]): Promise<string>;
10
- getParagraphAt(index: number): Locator;
7
+ getParagraphText(index: number): Promise<string>;
11
8
  getParagraphCount(): Promise<number>;
12
- getListItems(): Locator;
13
- getParagraphs(): Locator;
14
- getListItemCount(): Promise<number>;
15
9
  getProseMirrorMarkCount(name: string): Promise<number>;
16
- getProseMirrorMarksJSON(): Promise<unknown[]>;
17
10
  getProseMirrorSelection(): Promise<{
18
11
  anchor: number;
19
12
  head: number;
20
13
  }>;
21
14
  getDOMTextContentOfChildAtIndex(index: number): Promise<string>;
22
- getDocJSON(): Promise<object>;
23
- getCurrentDoc(): Promise<Node>;
24
- getCurrentAndExpectedDoc(expectedDocJSON: object): Promise<{
25
- currentDoc: Node;
26
- expectedDoc: Node;
27
- }>;
28
- revertSuggestion(suggestionId: number): Promise<void>;
29
- revertAll(): Promise<void>;
30
- applyAll(): Promise<void>;
31
- /**
32
- * Perform an action and wait for ProseMirror state to update.
33
- * Stores the current state reference before pressing, then polls until
34
- * editor.view.state is a different object (ProseMirror creates a new
35
- * immutable state on every transaction).
36
- */
37
- private doActionAndWaitForState;
38
- /**
39
- * Press a key and wait for ProseMirror state to update.
40
- * Stores the current state reference before pressing, then polls until
41
- * editor.view.state is a different object (ProseMirror creates a new
42
- * immutable state on every transaction).
43
- */
44
- pressKey(key: string, opts?: {
45
- waitForSelectionChange?: boolean;
46
- }): Promise<void>;
47
- /**
48
- * Insert text and wait for ProseMirror state to update.
49
- * Stores the current state reference before pressing, then polls until
50
- * editor.view.state is a different object (ProseMirror creates a new
51
- * immutable state on every transaction).
52
- */
53
- insertText(text: string, opts?: {
54
- waitForSelectionChange?: boolean;
55
- }): Promise<void>;
56
- /**
57
- * Press a key multiple times, waiting for editor state update after each press.
58
- */
59
- pressKeyMultiple(key: string, count: number, opts?: {
60
- waitForSelectionChange?: boolean;
61
- }): Promise<void>;
62
- setNextNodeId(nextNodeId: number): Promise<void>;
63
15
  }
package/dist/commands.js CHANGED
@@ -5,9 +5,6 @@ import { suggestChangesKey } from "./plugin.js";
5
5
  import { getSuggestionMarks } from "./utils.js";
6
6
  import { ZWSP } from "./constants.js";
7
7
  import { maybeRevertJoinMark } from "./features/joinOnDelete/index.js";
8
- import { isJoinMark } from "./features/joinOnDelete/types.js";
9
- import { revertAllStructureSuggestions, revertStructureSuggestion } from "./features/wrapUnwrap/revert/index.js";
10
- import { applyAllStructureSuggestions, applyStructureSuggestion } from "./features/wrapUnwrap/apply/index.js";
11
8
  /**
12
9
  * Given a node and a transform, add a set of steps to the
13
10
  * transform that applies all marks of type markTypeToApply
@@ -32,7 +29,6 @@ import { applyAllStructureSuggestions, applyStructureSuggestion } from "./featur
32
29
  tr.removeNodeMark(0, markTypeToApply);
33
30
  }
34
31
  }
35
- const restoredStructureSuggestionIds = new Set();
36
32
  node.descendants((child, pos)=>{
37
33
  if (from !== undefined && pos < from) {
38
34
  return true;
@@ -64,12 +60,8 @@ import { applyAllStructureSuggestions, applyStructureSuggestion } from "./featur
64
60
  const insertionTo = insertionFrom + child.nodeSize;
65
61
  if (child.isInline) {
66
62
  tr.removeMark(insertionFrom, insertionTo, markTypeToApply);
67
- const joinRevertResult = maybeRevertJoinMark(tr, insertionFrom, insertionTo, child, markTypeToApply);
68
- // reverting a join mark may produce new structure marks that were serialized in the join metadata
69
- if (joinRevertResult) {
70
- joinRevertResult.restoredStructureSuggestionIds.forEach((id)=>restoredStructureSuggestionIds.add(id));
71
- }
72
- if (!joinRevertResult && child.text === ZWSP) {
63
+ const reverted = maybeRevertJoinMark(tr, insertionFrom, insertionTo, child, markTypeToApply);
64
+ if (!reverted && child.text === ZWSP) {
73
65
  tr.delete(insertionFrom, insertionTo);
74
66
  }
75
67
  } else {
@@ -77,50 +69,6 @@ import { applyAllStructureSuggestions, applyStructureSuggestion } from "./featur
77
69
  }
78
70
  return true;
79
71
  });
80
- return {
81
- restoredStructureSuggestionIds
82
- };
83
- }
84
- /**
85
- * Collect suggestion IDs of join marks in the node
86
- *
87
- * @param node
88
- * @param deletion
89
- * @returns an array of suggestion IDs
90
- */ function findJoinSuggestionIds(node, deletion) {
91
- const joinSuggestionIds = [];
92
- node.descendants((child)=>{
93
- const mark = deletion.isInSet(child.marks);
94
- if (!mark || !isJoinMark(mark)) return true;
95
- if (!child.isText || child.text !== ZWSP) return true;
96
- joinSuggestionIds.push(mark.attrs.id);
97
- return true;
98
- });
99
- return joinSuggestionIds.reverse();
100
- }
101
- /**
102
- * Revert suggestions revealed by reverting a join mark
103
- * Prioritize reverting revealed suggestions with the same id as the join mark
104
- * (that means they are linked to the join mark and has to be reverted together as one)
105
- * Revert other revealed suggestions as well so the user doesn't have to revert multiple times at the same place
106
- *
107
- * @param tr
108
- * @param suggestionId
109
- * @param restoredStructureSuggestionIds
110
- */ function revertRestoredStructureSuggestions(tr, suggestionId, restoredStructureSuggestionIds) {
111
- if (restoredStructureSuggestionIds.has(suggestionId)) {
112
- const restoredStructureTransform = revertStructureSuggestion(tr.doc, suggestionId);
113
- restoredStructureTransform.steps.forEach((step)=>{
114
- tr.step(step);
115
- });
116
- }
117
- restoredStructureSuggestionIds.forEach((restoredSuggestionId)=>{
118
- if (restoredSuggestionId === suggestionId) return;
119
- const restoredStructureTransform = revertStructureSuggestion(tr.doc, restoredSuggestionId);
120
- restoredStructureTransform.steps.forEach((step)=>{
121
- tr.step(step);
122
- });
123
- });
124
72
  }
125
73
  function revertModifications(node, pos, tr) {
126
74
  const { modification } = getSuggestionMarks(node.type.schema);
@@ -186,42 +134,20 @@ function applyModificationsToTransform(node, tr, dir, suggestionId, from, to) {
186
134
  }
187
135
  export function applySuggestionsToNode(node) {
188
136
  const { deletion, insertion } = getSuggestionMarks(node.type.schema);
189
- // first, create a structure transform that applies all structure changes on the given node
190
- const structureTransform = applyAllStructureSuggestions(node);
191
- // then start a clear transform from the document where the structure changes are applied
192
- const suggestionsTransform = new Transform(structureTransform.doc);
193
- applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, insertion, deletion);
194
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, 1);
195
- // replay suggestion transform on top of the structure transform
196
- suggestionsTransform.steps.forEach((step)=>{
197
- structureTransform.step(step);
198
- });
199
- const secondStructureTransform = applyAllStructureSuggestions(structureTransform.doc);
200
- secondStructureTransform.steps.forEach((step)=>{
201
- structureTransform.step(step);
202
- });
203
- return structureTransform.doc;
137
+ const transform = new Transform(node);
138
+ applySuggestionsToTransform(node, transform, insertion, deletion);
139
+ applyModificationsToTransform(node, transform, 1);
140
+ return transform.doc;
204
141
  }
205
142
  export function applySuggestionsToRange(doc, from, to) {
206
- const { deletion, insertion } = getSuggestionMarks(doc.type.schema);
207
143
  // blockRange can only return null if a predicate is provided
208
144
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
209
145
  const nodeRange = doc.resolve(from).blockRange(doc.resolve(to));
210
- // create a structure transform that applies all structure changes on the given node range
211
- const structureTransform = applyAllStructureSuggestions(doc, nodeRange.start, nodeRange.end);
212
- // then start a clear transform from the document where the structure changes are applied
213
- const suggestionsTransform = new Transform(structureTransform.doc);
214
- applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, insertion, deletion, undefined, nodeRange.start, nodeRange.end);
215
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, 1, undefined, nodeRange.start, nodeRange.end);
216
- // replay suggestion transform on top of the structure transform
217
- suggestionsTransform.steps.forEach((step)=>{
218
- structureTransform.step(step);
219
- });
220
- const secondStructureTransform = applyAllStructureSuggestions(structureTransform.doc, structureTransform.mapping.map(from), structureTransform.mapping.map(to));
221
- secondStructureTransform.steps.forEach((step)=>{
222
- structureTransform.step(step);
223
- });
224
- return structureTransform.doc.slice(structureTransform.mapping.map(from), structureTransform.mapping.map(to));
146
+ const { deletion, insertion } = getSuggestionMarks(doc.type.schema);
147
+ const transform = new Transform(doc);
148
+ applySuggestionsToTransform(doc, transform, insertion, deletion, undefined, nodeRange.start, nodeRange.end);
149
+ applyModificationsToTransform(doc, transform, 1, undefined, nodeRange.start, nodeRange.end);
150
+ return transform.doc.slice(transform.mapping.map(from), transform.mapping.map(to));
225
151
  }
226
152
  /**
227
153
  * Command that applies all tracked changes in a document.
@@ -231,30 +157,13 @@ export function applySuggestionsToRange(doc, from, to) {
231
157
  * contents left in the doc.
232
158
  */ export function applySuggestions(state, dispatch) {
233
159
  const { deletion, insertion } = getSuggestionMarks(state.schema);
234
- // create a structure transform that applies all structure changes on the given document
235
- const structureTransform = applyAllStructureSuggestions(state.doc);
236
- // then start a clear transform from the document where the structure changes are applied
237
- const suggestionsTransform = new Transform(structureTransform.doc);
238
- applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, insertion, deletion);
239
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, 1);
240
- // replay suggestion transform on top of the structure transform
241
- suggestionsTransform.steps.forEach((step)=>{
242
- structureTransform.step(step);
243
- });
244
- const secondStructureTransform = applyAllStructureSuggestions(structureTransform.doc);
245
- secondStructureTransform.steps.forEach((step)=>{
246
- structureTransform.step(step);
247
- });
248
- // apply the structure transform to the transaction
249
- const transaction = state.tr;
250
- structureTransform.steps.forEach((step)=>{
251
- transaction.step(step);
252
- });
253
- if (!transaction.steps.length) return false;
254
- transaction.setMeta(suggestChangesKey, {
160
+ const tr = state.tr;
161
+ applySuggestionsToTransform(state.doc, tr, insertion, deletion);
162
+ applyModificationsToTransform(tr.doc, tr, 1);
163
+ tr.setMeta(suggestChangesKey, {
255
164
  skip: true
256
165
  });
257
- dispatch?.(transaction);
166
+ dispatch?.(tr);
258
167
  return true;
259
168
  }
260
169
  /**
@@ -266,30 +175,13 @@ export function applySuggestionsToRange(doc, from, to) {
266
175
  */ export function applySuggestionsInRange(from, to) {
267
176
  return (state, dispatch)=>{
268
177
  const { deletion, insertion } = getSuggestionMarks(state.schema);
269
- // create a structure transform that applies all structure changes on the given node range
270
- const structureTransform = applyAllStructureSuggestions(state.doc, from, to);
271
- // then start a clear transform from the document where the structure changes are applied
272
- const suggestionsTransform = new Transform(structureTransform.doc);
273
- applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, insertion, deletion, undefined, from, to);
274
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, 1, undefined, from, to);
275
- // replay suggestion transform on top of the structure transform
276
- suggestionsTransform.steps.forEach((step)=>{
277
- structureTransform.step(step);
278
- });
279
- const secondStructureTransform = applyAllStructureSuggestions(structureTransform.doc, from === undefined ? undefined : structureTransform.mapping.map(from), to === undefined ? undefined : structureTransform.mapping.map(to));
280
- secondStructureTransform.steps.forEach((step)=>{
281
- structureTransform.step(step);
282
- });
283
- // apply the structure transform to the transaction
284
- const transaction = state.tr;
285
- structureTransform.steps.forEach((step)=>{
286
- transaction.step(step);
287
- });
288
- if (!transaction.steps.length) return false;
289
- transaction.setMeta(suggestChangesKey, {
178
+ const tr = state.tr;
179
+ applySuggestionsToTransform(state.doc, tr, insertion, deletion, undefined, from, to);
180
+ applyModificationsToTransform(tr.doc, tr, 1, undefined, from, to);
181
+ tr.setMeta(suggestChangesKey, {
290
182
  skip: true
291
183
  });
292
- dispatch?.(transaction);
184
+ dispatch?.(tr);
293
185
  return true;
294
186
  };
295
187
  }
@@ -302,26 +194,14 @@ export function applySuggestionsToRange(doc, from, to) {
302
194
  */ export function applySuggestion(suggestionId, from, to) {
303
195
  return (state, dispatch)=>{
304
196
  const { deletion, insertion } = getSuggestionMarks(state.schema);
305
- // create a structure transform that applies the given structure change on the given node
306
- const structureTransform = applyStructureSuggestion(state.doc, suggestionId);
307
- // then start a clear transform from the document where the structure changes are applied
308
- const suggestionsTransform = new Transform(structureTransform.doc);
309
- applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, insertion, deletion, suggestionId, from, to);
310
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, 1, undefined, from, to);
311
- // replay suggestion transform on top of the structure transform
312
- suggestionsTransform.steps.forEach((step)=>{
313
- structureTransform.step(step);
314
- });
315
- // apply the structure transform to the transaction
316
- const transaction = state.tr;
317
- structureTransform.steps.forEach((step)=>{
318
- transaction.step(step);
319
- });
320
- if (!transaction.steps.length) return false;
321
- transaction.setMeta(suggestChangesKey, {
197
+ const tr = state.tr;
198
+ applySuggestionsToTransform(state.doc, tr, insertion, deletion, suggestionId, from, to);
199
+ applyModificationsToTransform(tr.doc, tr, 1, undefined, from, to);
200
+ if (!tr.steps.length) return false;
201
+ tr.setMeta(suggestChangesKey, {
322
202
  skip: true
323
203
  });
324
- dispatch?.(transaction);
204
+ dispatch?.(tr);
325
205
  return true;
326
206
  };
327
207
  }
@@ -333,40 +213,13 @@ export function applySuggestionsToRange(doc, from, to) {
333
213
  * Modifications tracked in modification marks will be reverted.
334
214
  */ export function revertSuggestions(state, dispatch) {
335
215
  const { deletion, insertion } = getSuggestionMarks(state.schema);
336
- // create a structure transform that reverts all structure changes on the given document
337
- const structureTransform = revertAllStructureSuggestions(state.doc);
338
- // revert all join marks first as well as any structure marks they contain serialized
339
- const joinSuggestionIds = findJoinSuggestionIds(structureTransform.doc, deletion);
340
- joinSuggestionIds.forEach((suggestionId)=>{
341
- const suggestionsTransform = new Transform(structureTransform.doc);
342
- const { restoredStructureSuggestionIds } = applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, deletion, insertion, suggestionId);
343
- suggestionsTransform.steps.forEach((step)=>{
344
- structureTransform.step(step);
345
- });
346
- revertRestoredStructureSuggestions(structureTransform, suggestionId, restoredStructureSuggestionIds);
347
- });
348
- // then start a clear transform from the document where the structure changes and join marks are reverted
349
- const suggestionsTransform = new Transform(structureTransform.doc);
350
- applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, deletion, insertion);
351
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, -1);
352
- // replay suggestion transform on top of the structure transform
353
- suggestionsTransform.steps.forEach((step)=>{
354
- structureTransform.step(step);
355
- });
356
- const secondStructureTransform = revertAllStructureSuggestions(structureTransform.doc);
357
- secondStructureTransform.steps.forEach((step)=>{
358
- structureTransform.step(step);
359
- });
360
- // apply the structure transform to the transaction
361
- const transaction = state.tr;
362
- structureTransform.steps.forEach((step)=>{
363
- transaction.step(step);
364
- });
365
- if (!transaction.steps.length) return false;
366
- transaction.setMeta(suggestChangesKey, {
216
+ const tr = state.tr;
217
+ applySuggestionsToTransform(state.doc, tr, deletion, insertion);
218
+ applyModificationsToTransform(tr.doc, tr, -1);
219
+ tr.setMeta(suggestChangesKey, {
367
220
  skip: true
368
221
  });
369
- dispatch?.(transaction);
222
+ dispatch?.(tr);
370
223
  return true;
371
224
  }
372
225
  /**
@@ -378,30 +231,13 @@ export function applySuggestionsToRange(doc, from, to) {
378
231
  */ export function revertSuggestionsInRange(from, to) {
379
232
  return (state, dispatch)=>{
380
233
  const { deletion, insertion } = getSuggestionMarks(state.schema);
381
- // create a structure transform that reverts all structure changes on the given node range
382
- const structureTransform = revertAllStructureSuggestions(state.doc, from, to);
383
- // then start a clear transform from the document where the structure changes are reverted
384
- const suggestionsTransform = new Transform(structureTransform.doc);
385
- applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, deletion, insertion, undefined, from, to);
386
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, -1, undefined, from, to);
387
- // replay suggestion transform on top of the structure transform
388
- suggestionsTransform.steps.forEach((step)=>{
389
- structureTransform.step(step);
390
- });
391
- const secondStructureTransform = revertAllStructureSuggestions(structureTransform.doc, from === undefined ? undefined : structureTransform.mapping.map(from), to === undefined ? undefined : structureTransform.mapping.map(to));
392
- secondStructureTransform.steps.forEach((step)=>{
393
- structureTransform.step(step);
394
- });
395
- // apply the structure transform to the transaction
396
- const transaction = state.tr;
397
- structureTransform.steps.forEach((step)=>{
398
- transaction.step(step);
399
- });
400
- if (!transaction.steps.length) return false;
401
- transaction.setMeta(suggestChangesKey, {
234
+ const tr = state.tr;
235
+ applySuggestionsToTransform(state.doc, tr, deletion, insertion, undefined, from, to);
236
+ applyModificationsToTransform(tr.doc, tr, -1, undefined, from, to);
237
+ tr.setMeta(suggestChangesKey, {
402
238
  skip: true
403
239
  });
404
- dispatch?.(transaction);
240
+ dispatch?.(tr);
405
241
  return true;
406
242
  };
407
243
  }
@@ -414,29 +250,14 @@ export function applySuggestionsToRange(doc, from, to) {
414
250
  */ export function revertSuggestion(suggestionId, from, to) {
415
251
  return (state, dispatch)=>{
416
252
  const { deletion, insertion } = getSuggestionMarks(state.schema);
417
- // create a structure transform that reverts the given structure change on the given node
418
- const structureTransform = revertStructureSuggestion(state.doc, suggestionId);
419
- // then start a clear transform from the document where the structure changes are reverted
420
- const suggestionsTransform = new Transform(structureTransform.doc);
421
- const { restoredStructureSuggestionIds } = applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, deletion, insertion, suggestionId, from, to);
422
- applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, -1, undefined, from, to);
423
- // replay suggestion transform on top of the structure transform
424
- suggestionsTransform.steps.forEach((step)=>{
425
- structureTransform.step(step);
426
- });
427
- // in case there are structure marks revealed after join mark revert,
428
- // revert them as well
429
- revertRestoredStructureSuggestions(structureTransform, suggestionId, restoredStructureSuggestionIds);
430
- // apply the structure transform to the transaction
431
- const transaction = state.tr;
432
- structureTransform.steps.forEach((step)=>{
433
- transaction.step(step);
434
- });
435
- if (!transaction.steps.length) return false;
436
- transaction.setMeta(suggestChangesKey, {
253
+ const tr = state.tr;
254
+ applySuggestionsToTransform(state.doc, tr, deletion, insertion, suggestionId, from, to);
255
+ if (!tr.steps.length) return false;
256
+ tr.setMeta(suggestChangesKey, {
437
257
  skip: true
438
258
  });
439
- dispatch?.(transaction);
259
+ applyModificationsToTransform(tr.doc, tr, -1, undefined, from, to);
260
+ dispatch?.(tr);
440
261
  return true;
441
262
  };
442
263
  }
@@ -63,7 +63,7 @@ export function ensureSelection() {
63
63
  $newAnchor
64
64
  });
65
65
  trace("appendTransaction", "search for new valid $head...");
66
- let $newHead = newState.selection.empty ? $newAnchor : getNewValidPos(newState.selection.$head, getDirection(oldState.selection.$head, newState.selection.$head, pluginState));
66
+ let $newHead = getNewValidPos(newState.selection.$head, getDirection(oldState.selection.$head, newState.selection.$head, pluginState));
67
67
  trace("appendTransaction", "new valid $head", $newHead?.pos, {
68
68
  $newHead
69
69
  });
@@ -147,8 +147,8 @@ function isPosValid($pos) {
147
147
  const insertionBefore = insertion.isInSet($pos.nodeBefore?.marks ?? []);
148
148
  const insertionAfter = insertion.isInSet($pos.nodeAfter?.marks ?? []);
149
149
  const ZWSP_REGEXP = new RegExp(ZWSP, "g");
150
- const isZWSPBefore = $pos.nodeBefore && $pos.nodeBefore.isText && $pos.nodeBefore.textContent.replace(ZWSP_REGEXP, "") === "";
151
- const isZWSPAfter = $pos.nodeAfter && $pos.nodeAfter.isText && $pos.nodeAfter.textContent.replace(ZWSP_REGEXP, "") === "";
150
+ const isZWSPBefore = $pos.nodeBefore && $pos.nodeBefore.textContent.replace(ZWSP_REGEXP, "") === "";
151
+ const isZWSPAfter = $pos.nodeAfter && $pos.nodeAfter.textContent.replace(ZWSP_REGEXP, "") === "";
152
152
  if (insertionBefore && insertionAfter && isZWSPBefore && isZWSPAfter) {
153
153
  trace("isPosValid", $pos.pos, "pos invalid", "reason: between two ZWSP insertions", {
154
154
  $pos
@@ -1,10 +1,24 @@
1
- import { Mark, type Node, type MarkType, type ResolvedPos } from "prosemirror-model";
1
+ import { Mark, type Node, type Attrs, type MarkType, type ResolvedPos } from "prosemirror-model";
2
2
  import { Transform } from "prosemirror-transform";
3
3
  import { type Transaction } from "prosemirror-state";
4
4
  import { type SuggestionId } from "../../generateId.js";
5
- export declare function maybeRevertJoinMark(tr: Transform, from: number, to: number, node: Node, markType: MarkType): false | {
6
- restoredStructureSuggestionIds: Set<SuggestionId>;
7
- };
5
+ interface JoinMarkAttrs {
6
+ type: "join";
7
+ data: {
8
+ leftNode: {
9
+ type: string;
10
+ attrs: object;
11
+ marks: object[];
12
+ };
13
+ rightNode: {
14
+ type: string;
15
+ attrs: object;
16
+ marks: object[];
17
+ };
18
+ };
19
+ }
20
+ export declare function isJoinMarkAttrs(attrs: Attrs): attrs is JoinMarkAttrs;
21
+ export declare function maybeRevertJoinMark(tr: Transform, from: number, to: number, node: Node, markType: MarkType): boolean;
8
22
  /**
9
23
  * Remove ZWSP text nodes marked as deletions (except for type=join) from the given range
10
24
  */
@@ -20,3 +34,4 @@ export declare function joinNodesAndMarkJoinPoints(trackedTransaction: Transacti
20
34
  */
21
35
  export declare function collapseZWSPNodes(trackedTransaction: Transaction, from: number, to: number): Transform;
22
36
  export declare function findJoinMark(pos: ResolvedPos): Mark | null;
37
+ export {};