@magic-marker/prosemirror-suggest-changes 0.3.3-wrap-unwrap.21 → 0.3.3-wrap-unwrap.23
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__/playwrightPage.d.ts +1 -0
- package/dist/commands.js +15 -3
- package/dist/ensureSelectionPlugin.js +1 -1
- package/dist/features/joinOnDelete/index.d.ts +3 -1
- package/dist/features/joinOnDelete/index.js +21 -1
- package/dist/features/wrapUnwrap/buildMaterializedPaths.js +1 -1
- package/dist/features/wrapUnwrap/revert/deleteNodeUpwards.js +1 -1
- package/dist/features/wrapUnwrap/revert/revertStructureSuggestions.js +1 -1
- package/dist/features/wrapUnwrap/structureChangesPlugin.js +1 -1
- package/dist/features/wrapUnwrap/uniqueNodeIdsPlugin.js +16 -8
- package/dist/withSuggestChanges.js +1 -1
- package/package.json +1 -1
package/dist/commands.js
CHANGED
|
@@ -31,6 +31,7 @@ import { applyAllStructureSuggestions, applyStructureSuggestion } from "./featur
|
|
|
31
31
|
tr.removeNodeMark(0, markTypeToApply);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
const restoredStructureSuggestionIds = new Set();
|
|
34
35
|
node.descendants((child, pos)=>{
|
|
35
36
|
if (from !== undefined && pos < from) {
|
|
36
37
|
return true;
|
|
@@ -62,8 +63,10 @@ import { applyAllStructureSuggestions, applyStructureSuggestion } from "./featur
|
|
|
62
63
|
const insertionTo = insertionFrom + child.nodeSize;
|
|
63
64
|
if (child.isInline) {
|
|
64
65
|
tr.removeMark(insertionFrom, insertionTo, markTypeToApply);
|
|
65
|
-
const
|
|
66
|
-
|
|
66
|
+
const joinRevertResult = maybeRevertJoinMark(tr, insertionFrom, insertionTo, child, markTypeToApply);
|
|
67
|
+
// reverting a join mark may produce new structure marks that were serialized in the join metadata
|
|
68
|
+
if (joinRevertResult) joinRevertResult.restoredStructureSuggestionIds.forEach((id)=>restoredStructureSuggestionIds.add(id));
|
|
69
|
+
if (!joinRevertResult && child.text === ZWSP) {
|
|
67
70
|
tr.delete(insertionFrom, insertionTo);
|
|
68
71
|
}
|
|
69
72
|
} else {
|
|
@@ -71,6 +74,9 @@ import { applyAllStructureSuggestions, applyStructureSuggestion } from "./featur
|
|
|
71
74
|
}
|
|
72
75
|
return true;
|
|
73
76
|
});
|
|
77
|
+
return {
|
|
78
|
+
restoredStructureSuggestionIds
|
|
79
|
+
};
|
|
74
80
|
}
|
|
75
81
|
function revertModifications(node, pos, tr) {
|
|
76
82
|
const { modification } = getSuggestionMarks(node.type.schema);
|
|
@@ -358,12 +364,18 @@ export function applySuggestionsToRange(doc, from, to) {
|
|
|
358
364
|
const structureTransform = revertStructureSuggestion(state.doc, suggestionId);
|
|
359
365
|
// then start a clear transform from the document where the structure changes are reverted
|
|
360
366
|
const suggestionsTransform = new Transform(structureTransform.doc);
|
|
361
|
-
applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, deletion, insertion, suggestionId, from, to);
|
|
367
|
+
const { restoredStructureSuggestionIds } = applySuggestionsToTransform(suggestionsTransform.doc, suggestionsTransform, deletion, insertion, suggestionId, from, to);
|
|
362
368
|
applyModificationsToTransform(suggestionsTransform.doc, suggestionsTransform, -1, undefined, from, to);
|
|
363
369
|
// replay suggestion transform on top of the structure transform
|
|
364
370
|
suggestionsTransform.steps.forEach((step)=>{
|
|
365
371
|
structureTransform.step(step);
|
|
366
372
|
});
|
|
373
|
+
restoredStructureSuggestionIds.forEach((suggestionId)=>{
|
|
374
|
+
const restoredStructureTransform = revertStructureSuggestion(structureTransform.doc, suggestionId);
|
|
375
|
+
restoredStructureTransform.steps.forEach((step)=>{
|
|
376
|
+
structureTransform.step(step);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
367
379
|
// apply the structure transform to the transaction
|
|
368
380
|
const transaction = state.tr;
|
|
369
381
|
structureTransform.steps.forEach((step)=>{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Plugin, PluginKey, TextSelection } from "prosemirror-state";
|
|
2
2
|
import { getSuggestionMarks } from "./utils.js";
|
|
3
3
|
import { ZWSP } from "./constants.js";
|
|
4
|
-
const TRACE_ENABLED =
|
|
4
|
+
const TRACE_ENABLED = false;
|
|
5
5
|
function trace(...args) {
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
7
7
|
if (!TRACE_ENABLED) return;
|
|
@@ -2,7 +2,9 @@ import { Mark, type Node, type MarkType, type ResolvedPos } from "prosemirror-mo
|
|
|
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):
|
|
5
|
+
export declare function maybeRevertJoinMark(tr: Transform, from: number, to: number, node: Node, markType: MarkType): false | {
|
|
6
|
+
restoredStructureSuggestionIds: Set<SuggestionId>;
|
|
7
|
+
};
|
|
6
8
|
/**
|
|
7
9
|
* Remove ZWSP text nodes marked as deletions (except for type=join) from the given range
|
|
8
10
|
*/
|
|
@@ -41,6 +41,23 @@ function restoreNodeMarkup(tr, pos, node) {
|
|
|
41
41
|
tr.setNodeMarkup(pos, nodeType, node.attrs, marks);
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
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
|
+
}
|
|
44
61
|
export function maybeRevertJoinMark(tr, from, to, node, markType) {
|
|
45
62
|
const mark = node.marks.find((mark)=>mark.type === markType);
|
|
46
63
|
if (!mark || !isJoinMark(mark) || node.text !== ZWSP) return false;
|
|
@@ -58,6 +75,7 @@ export function maybeRevertJoinMark(tr, from, to, node, markType) {
|
|
|
58
75
|
return false;
|
|
59
76
|
}
|
|
60
77
|
}
|
|
78
|
+
const restoredStructureSuggestionIds = getRestoredStructureSuggestionIds(joinNodes, tr.doc.type.schema);
|
|
61
79
|
// Reverting a join marker removes its ZWSP anchor, splits at that position,
|
|
62
80
|
// and restores markup because ProseMirror split creates nodes with defaults.
|
|
63
81
|
const joinDepth = joinNodes.leftNodes.length;
|
|
@@ -79,7 +97,9 @@ export function maybeRevertJoinMark(tr, from, to, node, markType) {
|
|
|
79
97
|
// Each deeper right node starts one position inside the right node restored before it.
|
|
80
98
|
rightPos += 1;
|
|
81
99
|
}
|
|
82
|
-
return
|
|
100
|
+
return {
|
|
101
|
+
restoredStructureSuggestionIds
|
|
102
|
+
};
|
|
83
103
|
}
|
|
84
104
|
/**
|
|
85
105
|
* Remove ZWSP text nodes marked as deletions (except for type=join) from the given range
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getNodeId } from "./getNodeId.js";
|
|
2
2
|
import { DOC_NODE_ID } from "./constants.js";
|
|
3
|
-
const TRACE_ENABLED =
|
|
3
|
+
const TRACE_ENABLED = false;
|
|
4
4
|
function trace(...args) {
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
6
6
|
if (!TRACE_ENABLED) return;
|
|
@@ -6,7 +6,7 @@ import { sameParentChain } from "../sameParentChain.js";
|
|
|
6
6
|
import { buildMaterializedPaths } from "../buildMaterializedPaths.js";
|
|
7
7
|
import { revertAddOp } from "./revertAddOp.js";
|
|
8
8
|
import { revertMoveOp } from "./revertMoveOp.js";
|
|
9
|
-
const TRACE_ENABLED =
|
|
9
|
+
const TRACE_ENABLED = false;
|
|
10
10
|
function trace(...args) {
|
|
11
11
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
12
12
|
if (!TRACE_ENABLED) return;
|
|
@@ -8,7 +8,7 @@ import { Transform } from "prosemirror-transform";
|
|
|
8
8
|
import { isSuggestChangesEnabled, suggestChangesKey } from "../../plugin.js";
|
|
9
9
|
import { buildMaterializedPaths } from "./buildMaterializedPaths.js";
|
|
10
10
|
import { sameParentChain } from "./sameParentChain.js";
|
|
11
|
-
const TRACE_ENABLED =
|
|
11
|
+
const TRACE_ENABLED = false;
|
|
12
12
|
function trace(...args) {
|
|
13
13
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
14
14
|
if (!TRACE_ENABLED) return;
|
|
@@ -6,22 +6,27 @@ import { Transform } from "prosemirror-transform";
|
|
|
6
6
|
// (also checks and fix duplicates that inevitably appear)
|
|
7
7
|
export const uniqueNodeIdsPluginKey = new PluginKey("@handlewithcare/prosemirror-suggest-changes-unique-node-ids");
|
|
8
8
|
export const UNIQUE_NODE_IDS_PLUGIN_META = "unique-node-ids-plugin";
|
|
9
|
+
const TRACE_ENABLED = false;
|
|
10
|
+
function trace(...args) {
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
12
|
+
if (!TRACE_ENABLED) return;
|
|
13
|
+
console.log("[uniqueNodeIdsPlugin]", ...args);
|
|
14
|
+
}
|
|
9
15
|
export function uniqueNodeIdsPlugin({ attributeName, generateID }) {
|
|
10
16
|
return new Plugin({
|
|
11
17
|
key: uniqueNodeIdsPluginKey,
|
|
12
18
|
appendTransaction (transactions, oldState, newState) {
|
|
13
|
-
|
|
19
|
+
trace("appendTransaction");
|
|
14
20
|
const pluginState = uniqueNodeIdsPluginKey.getState(newState);
|
|
15
21
|
// do nothing if doc hasn't changed (but make sure it runs initially)
|
|
16
22
|
const docChanged = transactions.some((transaction)=>transaction.docChanged);
|
|
17
23
|
if (!docChanged && pluginState?.completedInitialRun) {
|
|
18
|
-
|
|
24
|
+
trace("doc not changed, skipping", [
|
|
19
25
|
...transactions
|
|
20
26
|
]);
|
|
21
27
|
return;
|
|
22
28
|
}
|
|
23
|
-
|
|
24
|
-
console.log("uniqueNodeIdsPlugin", "appendTransaction", [
|
|
29
|
+
trace("appendTransaction", [
|
|
25
30
|
...transactions
|
|
26
31
|
]);
|
|
27
32
|
const tr = newState.tr;
|
|
@@ -32,8 +37,7 @@ export function uniqueNodeIdsPlugin({ attributeName, generateID }) {
|
|
|
32
37
|
transform.steps.forEach((step)=>{
|
|
33
38
|
tr.step(step);
|
|
34
39
|
});
|
|
35
|
-
|
|
36
|
-
console.groupEnd();
|
|
40
|
+
trace("tr steps", tr.steps);
|
|
37
41
|
if (!tr.steps.length) return;
|
|
38
42
|
tr.setMeta(uniqueNodeIdsPluginKey, UNIQUE_NODE_IDS_PLUGIN_META);
|
|
39
43
|
return tr;
|
|
@@ -59,6 +63,8 @@ export function uniqueNodeIdsPlugin({ attributeName, generateID }) {
|
|
|
59
63
|
export function ensureUniqueNodeIds(_transactions, _oldDoc, newDoc, options) {
|
|
60
64
|
const tr = new Transform(newDoc);
|
|
61
65
|
const nodeIds = new Set();
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
67
|
+
if (TRACE_ENABLED) console.groupCollapsed("ensureUniqueNodeIds");
|
|
62
68
|
tr.doc.descendants((node, pos)=>{
|
|
63
69
|
if (node.isText) return false;
|
|
64
70
|
const nodeId = getNodeId(node);
|
|
@@ -75,7 +81,7 @@ export function ensureUniqueNodeIds(_transactions, _oldDoc, newDoc, options) {
|
|
|
75
81
|
...node.attrs,
|
|
76
82
|
[options.attributeName]: id
|
|
77
83
|
}, node.marks);
|
|
78
|
-
|
|
84
|
+
trace("fixed duplicate id", id, "for node", node.type.name, "at pos", pos, {
|
|
79
85
|
was: nodeId,
|
|
80
86
|
is: id
|
|
81
87
|
});
|
|
@@ -89,10 +95,12 @@ export function ensureUniqueNodeIds(_transactions, _oldDoc, newDoc, options) {
|
|
|
89
95
|
...node.attrs,
|
|
90
96
|
[options.attributeName]: id
|
|
91
97
|
}, node.marks);
|
|
92
|
-
|
|
98
|
+
trace("set unique id", id, "for node", node.type.name, "at pos", pos);
|
|
93
99
|
return true;
|
|
94
100
|
}
|
|
95
101
|
return true;
|
|
96
102
|
});
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
104
|
+
if (TRACE_ENABLED) console.groupEnd();
|
|
97
105
|
return tr;
|
|
98
106
|
}
|
|
@@ -4,7 +4,7 @@ import { getRequiredStructuralContextPaths, suggestStructureChanges } from "./fe
|
|
|
4
4
|
import { handleSpecialTransactionShape } from "./features/transactionShaping/index.js";
|
|
5
5
|
import { transformToSuggestionTransaction } from "./transformToSuggestionTransaction.js";
|
|
6
6
|
export { transformToSuggestionTransaction } from "./transformToSuggestionTransaction.js";
|
|
7
|
-
const TRACE_ENABLED =
|
|
7
|
+
const TRACE_ENABLED = false;
|
|
8
8
|
function trace(...args) {
|
|
9
9
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
10
10
|
if (!TRACE_ENABLED) return;
|