@manuscripts/track-changes-plugin 2.0.11 → 2.0.12
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/cjs/ChangeSet.js +17 -0
- package/dist/cjs/actions.js +1 -0
- package/dist/cjs/change-steps/processChangeSteps.js +15 -11
- package/dist/cjs/changes/applyChanges.js +5 -3
- package/dist/cjs/changes/updateChangesStatus.js +2 -2
- package/dist/cjs/mutate/deleteNode.js +18 -1
- package/dist/cjs/mutate/dropStructureChange.js +106 -0
- package/dist/cjs/steps/trackReplaceStep.js +6 -3
- package/dist/cjs/steps/trackTransaction.js +14 -2
- package/dist/cjs/types/change.js +1 -0
- package/dist/cjs/utils/track-utils.js +33 -2
- package/dist/es/ChangeSet.js +17 -0
- package/dist/es/actions.js +1 -0
- package/dist/es/change-steps/processChangeSteps.js +15 -11
- package/dist/es/changes/applyChanges.js +6 -4
- package/dist/es/changes/updateChangesStatus.js +2 -2
- package/dist/es/mutate/deleteNode.js +16 -1
- package/dist/es/mutate/dropStructureChange.js +100 -0
- package/dist/es/steps/trackReplaceStep.js +7 -4
- package/dist/es/steps/trackTransaction.js +15 -3
- package/dist/es/types/change.js +1 -0
- package/dist/es/utils/track-utils.js +29 -1
- package/dist/types/ChangeSet.d.ts +2 -1
- package/dist/types/actions.d.ts +3 -1
- package/dist/types/mutate/deleteNode.d.ts +1 -0
- package/dist/types/mutate/dropStructureChange.d.ts +6 -0
- package/dist/types/types/change.d.ts +7 -2
- package/dist/types/types/track.d.ts +1 -1
- package/dist/types/utils/track-utils.d.ts +4 -1
- package/package.json +1 -1
package/dist/cjs/ChangeSet.js
CHANGED
|
@@ -89,6 +89,9 @@ class ChangeSet {
|
|
|
89
89
|
currentInlineChange = undefined;
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
+
if (this.joinRelatedStructuralChanges(rootNodes, change)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
92
95
|
rootNodes.push([change]);
|
|
93
96
|
});
|
|
94
97
|
return rootNodes.filter((changes) => changes.filter((c) => c.dataTracked.operation !== change_1.CHANGE_OPERATION.reference &&
|
|
@@ -161,6 +164,20 @@ class ChangeSet {
|
|
|
161
164
|
change.to === nextChange.from &&
|
|
162
165
|
hasMatchingOperation(change, nextChange));
|
|
163
166
|
}
|
|
167
|
+
joinRelatedStructuralChanges(rootNodes, change) {
|
|
168
|
+
if (change.dataTracked.operation !== change_1.CHANGE_OPERATION.structure) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const index = rootNodes.findIndex((c) => c[0].dataTracked.operation === change_1.CHANGE_OPERATION.structure &&
|
|
172
|
+
c[0].dataTracked.moveNodeId === change.dataTracked.moveNodeId);
|
|
173
|
+
if (index !== -1) {
|
|
174
|
+
rootNodes[index] = [...rootNodes[index], change];
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
rootNodes.push([change]);
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
164
181
|
static flattenTreeToIds(changes) {
|
|
165
182
|
return changes.flatMap((c) => (this.isNodeChange(c) ? [c.id, ...c.children.map((c) => c.id)] : c.id));
|
|
166
183
|
}
|
package/dist/cjs/actions.js
CHANGED
|
@@ -12,6 +12,7 @@ var TrackChangesAction;
|
|
|
12
12
|
TrackChangesAction["setChangeStatuses"] = "track-changes-set-change-statuses";
|
|
13
13
|
TrackChangesAction["refreshChanges"] = "track-changes-refresh-changes";
|
|
14
14
|
TrackChangesAction["updateMetaNode"] = "track-changes-update-meta-node";
|
|
15
|
+
TrackChangesAction["structuralChangeAction"] = "track-changes-structural-change-action";
|
|
15
16
|
TrackChangesAction["indentationAction"] = "track-changes-indentation-action";
|
|
16
17
|
})(TrackChangesAction || (exports.TrackChangesAction = TrackChangesAction = {}));
|
|
17
18
|
function hasAction(tr) {
|
|
@@ -59,7 +59,7 @@ function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema, delete
|
|
|
59
59
|
let selectionPos = startPos;
|
|
60
60
|
let deletesCounter = 0;
|
|
61
61
|
let isInserted = false;
|
|
62
|
-
let
|
|
62
|
+
let prevDelete;
|
|
63
63
|
changes.forEach((c) => {
|
|
64
64
|
let step = newTr.steps[newTr.steps.length - 1];
|
|
65
65
|
switch (c.type) {
|
|
@@ -68,10 +68,12 @@ function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema, delete
|
|
|
68
68
|
const prevDeletedNodeInserted = isInserted;
|
|
69
69
|
const trackedData = (0, nodeHelpers_1.getBlockInlineTrackedData)(c.node);
|
|
70
70
|
const inserted = trackedData === null || trackedData === void 0 ? void 0 : trackedData.find((d) => d.operation === change_1.CHANGE_OPERATION.insert);
|
|
71
|
-
|
|
71
|
+
const structure = trackedData === null || trackedData === void 0 ? void 0 : trackedData.find((c) => c.operation === change_1.CHANGE_OPERATION.structure &&
|
|
72
|
+
deleteAttrs.moveNodeId &&
|
|
73
|
+
c.moveNodeId !== deleteAttrs.moveNodeId);
|
|
72
74
|
let childOfDeleted = false;
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
+
if (prevDelete) {
|
|
76
|
+
prevDelete.node.descendants((node) => {
|
|
75
77
|
if (childOfDeleted) {
|
|
76
78
|
return false;
|
|
77
79
|
}
|
|
@@ -80,18 +82,20 @@ function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema, delete
|
|
|
80
82
|
}
|
|
81
83
|
});
|
|
82
84
|
}
|
|
83
|
-
const nodeAtMappedPos = newTr.doc.nodeAt(mapping.map(c.pos));
|
|
84
|
-
const nodeWasAlreadyDeleted = !nodeAtMappedPos || nodeAtMappedPos !== c.node;
|
|
85
85
|
const isMoveOperation = !!emptyAttrs.moveNodeId;
|
|
86
|
-
if ((
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
if ((prevDelete &&
|
|
87
|
+
c.pos < prevDelete.nodeEnd &&
|
|
88
|
+
isInserted &&
|
|
89
|
+
deletesCounter > 1 &&
|
|
90
|
+
!isMoveOperation) ||
|
|
91
|
+
(childOfDeleted && prevDeletedNodeInserted)) {
|
|
89
92
|
return false;
|
|
90
93
|
}
|
|
91
94
|
(0, deleteNode_1.deleteOrSetNodeDeleted)(c.node, mapping.map(c.pos), newTr, deleteAttrs);
|
|
92
|
-
|
|
95
|
+
prevDelete = c;
|
|
96
|
+
isInserted = !!inserted || !!structure || (!trackedData && isInserted);
|
|
93
97
|
const newestStep = newTr.steps[newTr.steps.length - 1];
|
|
94
|
-
if (isInserted) {
|
|
98
|
+
if (isInserted || structure) {
|
|
95
99
|
deletedNodeMapping.appendMap(newestStep.getMap());
|
|
96
100
|
}
|
|
97
101
|
if (step !== newestStep) {
|
|
@@ -41,7 +41,8 @@ function applyAcceptedRejectedChanges(tr, schema, changes, changeSet, deleteMap
|
|
|
41
41
|
return c1.dataTracked.updatedAt - c2.dataTracked.updatedAt;
|
|
42
42
|
});
|
|
43
43
|
changes.forEach((change) => {
|
|
44
|
-
if (change.dataTracked.operation === change_1.CHANGE_OPERATION.move
|
|
44
|
+
if (change.dataTracked.operation === change_1.CHANGE_OPERATION.move ||
|
|
45
|
+
change.dataTracked.operation === change_1.CHANGE_OPERATION.structure) {
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
48
|
if (change.dataTracked.operation === change_1.CHANGE_OPERATION.delete && change.dataTracked.moveNodeId) {
|
|
@@ -74,7 +75,7 @@ function applyAcceptedRejectedChanges(tr, schema, changes, changeSet, deleteMap
|
|
|
74
75
|
deleteMap.appendMap(tr.steps[tr.steps.length - 1].getMap());
|
|
75
76
|
}
|
|
76
77
|
else if (ChangeSet_1.ChangeSet.isNodeChange(change) && noChangeNeeded) {
|
|
77
|
-
const attrs = Object.assign(Object.assign({}, node.attrs), { dataTracked:
|
|
78
|
+
const attrs = Object.assign(Object.assign({}, node.attrs), { dataTracked: (0, deleteNode_1.keepDeleteWithMoveNodeId)(node) });
|
|
78
79
|
tr.setNodeMarkup(from, undefined, attrs, node.marks);
|
|
79
80
|
if (node.isAtom) {
|
|
80
81
|
tr.removeMark(from, deleteMap.map(change.to), schema.marks.tracked_insert);
|
|
@@ -100,7 +101,8 @@ function applyAcceptedRejectedChanges(tr, schema, changes, changeSet, deleteMap
|
|
|
100
101
|
}
|
|
101
102
|
});
|
|
102
103
|
changes.forEach((change) => {
|
|
103
|
-
if (change.dataTracked.operation !== change_1.CHANGE_OPERATION.move
|
|
104
|
+
if (change.dataTracked.operation !== change_1.CHANGE_OPERATION.move &&
|
|
105
|
+
change.dataTracked.operation !== change_1.CHANGE_OPERATION.structure) {
|
|
104
106
|
return;
|
|
105
107
|
}
|
|
106
108
|
const { pos: from, deleted } = deleteMap.mapResult(change.from);
|
|
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
18
|
exports.updateChangesStatus = updateChangesStatus;
|
|
19
19
|
const prosemirror_history_1 = require("prosemirror-history");
|
|
20
20
|
const ChangeSet_1 = require("../ChangeSet");
|
|
21
|
+
const dropStructureChange_1 = require("../mutate/dropStructureChange");
|
|
21
22
|
const change_1 = require("../types/change");
|
|
22
23
|
const applyChanges_1 = require("./applyChanges");
|
|
23
24
|
const updateChangeAttrs_1 = require("./updateChangeAttrs");
|
|
@@ -46,9 +47,7 @@ function updateChangesStatus(createdTr, changeSet, ids, status, userID, oldState
|
|
|
46
47
|
c.dataTracked.operation === 'delete' &&
|
|
47
48
|
c.dataTracked.moveNodeId === change.dataTracked.moveNodeId);
|
|
48
49
|
if (oldChange && ChangeSet_1.ChangeSet.isNodeChange(oldChange)) {
|
|
49
|
-
createdTr = (0, updateChangeAttrs_1.updateChangeAttrs)(createdTr, oldChange, Object.assign(Object.assign({}, oldChange.dataTracked), { status, statusUpdateAt: changeTime, reviewedByID: userID }), oldState.schema);
|
|
50
50
|
oldChange.children.forEach((child) => {
|
|
51
|
-
createdTr = (0, updateChangeAttrs_1.updateChangeAttrs)(createdTr, child, Object.assign(Object.assign({}, child.dataTracked), { status, statusUpdateAt: changeTime, reviewedByID: userID }), oldState.schema);
|
|
52
51
|
if (ChangeSet_1.ChangeSet.isTextChange(child)) {
|
|
53
52
|
textChanges.push(child);
|
|
54
53
|
}
|
|
@@ -64,6 +63,7 @@ function updateChangesStatus(createdTr, changeSet, ids, status, userID, oldState
|
|
|
64
63
|
});
|
|
65
64
|
const mapping = (0, applyChanges_1.applyAcceptedRejectedChanges)(createdTr, oldState.schema, nonTextChanges, changeSet);
|
|
66
65
|
(0, applyChanges_1.applyAcceptedRejectedChanges)(createdTr, oldState.schema, textChanges, changeSet, mapping);
|
|
66
|
+
(0, dropStructureChange_1.dropOrphanChanges)(createdTr);
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
69
|
ids.forEach((changeId) => {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.keepDeleteWithMoveNodeId = void 0;
|
|
3
4
|
exports.deleteNode = deleteNode;
|
|
4
5
|
exports.deleteOrSetNodeDeleted = deleteOrSetNodeDeleted;
|
|
5
6
|
const prosemirror_model_1 = require("prosemirror-model");
|
|
6
7
|
const nodeHelpers_1 = require("../compute/nodeHelpers");
|
|
7
8
|
const change_1 = require("../types/change");
|
|
8
9
|
const logger_1 = require("../utils/logger");
|
|
10
|
+
const dropStructureChange_1 = require("./dropStructureChange");
|
|
9
11
|
function deleteNode(node, pos, tr) {
|
|
10
12
|
var _a;
|
|
11
13
|
const startPos = tr.doc.resolve(pos + 1);
|
|
@@ -22,7 +24,13 @@ function deleteOrSetNodeDeleted(node, pos, newTr, deleteAttrs) {
|
|
|
22
24
|
const dataTracked = (0, nodeHelpers_1.getBlockInlineTrackedData)(node);
|
|
23
25
|
const inserted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => (d.operation === change_1.CHANGE_OPERATION.insert || d.operation === change_1.CHANGE_OPERATION.wrap_with_node) &&
|
|
24
26
|
(d.status === change_1.CHANGE_STATUS.pending || d.status === change_1.CHANGE_STATUS.accepted));
|
|
25
|
-
const updated = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === change_1.CHANGE_OPERATION.set_node_attributes ||
|
|
27
|
+
const updated = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === change_1.CHANGE_OPERATION.set_node_attributes ||
|
|
28
|
+
d.operation === change_1.CHANGE_OPERATION.reference ||
|
|
29
|
+
(d.operation === change_1.CHANGE_OPERATION.delete && d.moveNodeId));
|
|
30
|
+
const structure = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((c) => c.operation === change_1.CHANGE_OPERATION.structure);
|
|
31
|
+
if (deleteAttrs.moveNodeId && structure && structure.moveNodeId !== deleteAttrs.moveNodeId) {
|
|
32
|
+
return newTr.delete(pos, pos + node.nodeSize);
|
|
33
|
+
}
|
|
26
34
|
const moved = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === change_1.CHANGE_OPERATION.move && d.status === change_1.CHANGE_STATUS.pending);
|
|
27
35
|
if (inserted) {
|
|
28
36
|
return deleteNode(node, pos, newTr);
|
|
@@ -37,4 +45,13 @@ function deleteOrSetNodeDeleted(node, pos, newTr, deleteAttrs) {
|
|
|
37
45
|
}
|
|
38
46
|
const newDeleted = (0, nodeHelpers_1.addTrackIdIfDoesntExist)(deleteAttrs);
|
|
39
47
|
newTr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { dataTracked: updated ? [newDeleted, updated] : moved ? [newDeleted, moved] : [newDeleted] }), node.marks);
|
|
48
|
+
if (!deleteAttrs.moveNodeId && (structure === null || structure === void 0 ? void 0 : structure.moveNodeId)) {
|
|
49
|
+
(0, dropStructureChange_1.dropStructuralChangeShadow)(structure.moveNodeId, newTr);
|
|
50
|
+
}
|
|
40
51
|
}
|
|
52
|
+
const keepDeleteWithMoveNodeId = (node) => {
|
|
53
|
+
var _a;
|
|
54
|
+
const dataTracked = (_a = (0, nodeHelpers_1.getBlockInlineTrackedData)(node)) === null || _a === void 0 ? void 0 : _a.filter((c) => c.operation === change_1.CHANGE_OPERATION.delete && c.moveNodeId);
|
|
55
|
+
return (dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.length) ? dataTracked : null;
|
|
56
|
+
};
|
|
57
|
+
exports.keepDeleteWithMoveNodeId = keepDeleteWithMoveNodeId;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.joinStructureChanges = exports.dropOrphanChanges = exports.dropStructuralChangeShadow = void 0;
|
|
15
|
+
const prosemirror_model_1 = require("prosemirror-model");
|
|
16
|
+
const prosemirror_state_1 = require("prosemirror-state");
|
|
17
|
+
const findChanges_1 = require("../changes/findChanges");
|
|
18
|
+
const updateChangeAttrs_1 = require("../changes/updateChangeAttrs");
|
|
19
|
+
const nodeHelpers_1 = require("../compute/nodeHelpers");
|
|
20
|
+
const setFragmentAsInserted_1 = require("../compute/setFragmentAsInserted");
|
|
21
|
+
const change_1 = require("../types/change");
|
|
22
|
+
const track_utils_1 = require("../utils/track-utils");
|
|
23
|
+
const dropStructuralChangeShadow = (moveNodeId, tr) => {
|
|
24
|
+
const changeSet = (0, findChanges_1.findChanges)(prosemirror_state_1.EditorState.create({ doc: tr.doc }));
|
|
25
|
+
const changes = changeSet.changes.filter((c) => c.type === 'node-change' && c.dataTracked.moveNodeId === moveNodeId);
|
|
26
|
+
const shadow = changes.filter((c) => c.dataTracked.operation === change_1.CHANGE_OPERATION.delete);
|
|
27
|
+
const structures = changes.filter((c) => c.dataTracked.operation === change_1.CHANGE_OPERATION.structure);
|
|
28
|
+
structures.map((c) => {
|
|
29
|
+
tr.setNodeMarkup(c.from, undefined, Object.assign(Object.assign({}, c.node.attrs), { dataTracked: null }));
|
|
30
|
+
});
|
|
31
|
+
if (shadow.length > 0) {
|
|
32
|
+
tr.delete(shadow[0].from, shadow[shadow.length - 1].to);
|
|
33
|
+
}
|
|
34
|
+
return tr;
|
|
35
|
+
};
|
|
36
|
+
exports.dropStructuralChangeShadow = dropStructuralChangeShadow;
|
|
37
|
+
const dropOrphanChanges = (newTr, dropDataTracked) => {
|
|
38
|
+
const changeSet = (0, findChanges_1.findChanges)(prosemirror_state_1.EditorState.create({ doc: newTr.doc }));
|
|
39
|
+
const shadowIds = new Set();
|
|
40
|
+
const changesIds = new Set();
|
|
41
|
+
changeSet.changes.forEach((c) => {
|
|
42
|
+
if (c.dataTracked.moveNodeId && c.dataTracked.operation === change_1.CHANGE_OPERATION.delete) {
|
|
43
|
+
shadowIds.add(c.dataTracked.moveNodeId);
|
|
44
|
+
}
|
|
45
|
+
if (c.dataTracked.operation === change_1.CHANGE_OPERATION.structure ||
|
|
46
|
+
c.dataTracked.operation === change_1.CHANGE_OPERATION.move) {
|
|
47
|
+
changesIds.add(c.dataTracked.moveNodeId);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
if (!shadowIds.size && !changesIds.size) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
changeSet.changes.forEach((c) => {
|
|
54
|
+
if (c.dataTracked.moveNodeId &&
|
|
55
|
+
!(shadowIds.has(c.dataTracked.moveNodeId) && changesIds.has(c.dataTracked.moveNodeId))) {
|
|
56
|
+
if (c.dataTracked.operation === change_1.CHANGE_OPERATION.delete || dropDataTracked) {
|
|
57
|
+
if (c.type === 'text-change') {
|
|
58
|
+
newTr.removeMark(c.from, c.to, newTr.doc.type.schema.marks.tracked_delete);
|
|
59
|
+
}
|
|
60
|
+
else if (c.type === 'node-change') {
|
|
61
|
+
newTr.setNodeMarkup(c.from, undefined, Object.assign(Object.assign({}, c.node.attrs), { dataTracked: null }));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (c.type === 'node-change') {
|
|
65
|
+
const _a = c.dataTracked, { id, moveNodeId } = _a, attrs = __rest(_a, ["id", "moveNodeId"]);
|
|
66
|
+
newTr.replaceWith(c.from, c.to, (0, setFragmentAsInserted_1.setFragmentAsInserted)(prosemirror_model_1.Fragment.from(c.node), (0, track_utils_1.createNewInsertAttrs)(attrs), newTr.doc.type.schema));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
exports.dropOrphanChanges = dropOrphanChanges;
|
|
72
|
+
const groupStructureChanges = (tr, toNode) => {
|
|
73
|
+
const moveNodeIds = new Set();
|
|
74
|
+
const [insertStep, deleteStep] = tr.steps;
|
|
75
|
+
const fromNodes = tr.docs[1].slice(deleteStep.from, deleteStep.to).content;
|
|
76
|
+
const ignoredNode = tr.docs[1].nodeAt(deleteStep.from);
|
|
77
|
+
prosemirror_model_1.Fragment.from(toNode)
|
|
78
|
+
.append(insertStep.slice.content)
|
|
79
|
+
.append(fromNodes)
|
|
80
|
+
.descendants((node) => {
|
|
81
|
+
var _a;
|
|
82
|
+
const moveNodeId = (_a = ((0, nodeHelpers_1.getBlockInlineTrackedData)(node) || []).find((c) => c.operation === change_1.CHANGE_OPERATION.structure)) === null || _a === void 0 ? void 0 : _a.moveNodeId;
|
|
83
|
+
moveNodeId && moveNodeIds.add(moveNodeId);
|
|
84
|
+
});
|
|
85
|
+
return moveNodeIds;
|
|
86
|
+
};
|
|
87
|
+
const joinStructureChanges = (attrs, sliceContent, content, tr, newTr) => {
|
|
88
|
+
var _a, _b, _c;
|
|
89
|
+
const moveNodeId = attrs.moveNodeId;
|
|
90
|
+
let toNode = tr.docs[0].resolve(tr.steps[0].from).node();
|
|
91
|
+
toNode = ((_a = toNode === null || toNode === void 0 ? void 0 : toNode.type.spec.attrs) === null || _a === void 0 ? void 0 : _a.dataTracked) ? toNode : null;
|
|
92
|
+
const idsSet = groupStructureChanges(tr, toNode);
|
|
93
|
+
const changeSet = (0, findChanges_1.findChanges)(prosemirror_state_1.EditorState.create({ doc: newTr.doc }));
|
|
94
|
+
const relatedChanges = changeSet.changes.filter((c) => c.dataTracked.moveNodeId && idsSet.has(c.dataTracked.moveNodeId));
|
|
95
|
+
relatedChanges.map((c) => (0, updateChangeAttrs_1.updateChangeAttrs)(newTr, c, Object.assign(Object.assign({}, c.dataTracked), { moveNodeId }), newTr.doc.type.schema));
|
|
96
|
+
const toInsertChange = toNode && ((_b = (0, nodeHelpers_1.getBlockInlineTrackedData)(toNode)) === null || _b === void 0 ? void 0 : _b.find((c) => c.operation === change_1.CHANGE_OPERATION.insert));
|
|
97
|
+
const fromInsertChange = sliceContent.firstChild &&
|
|
98
|
+
((_c = (0, nodeHelpers_1.getBlockInlineTrackedData)(sliceContent.firstChild)) === null || _c === void 0 ? void 0 : _c.find((c) => c.operation === change_1.CHANGE_OPERATION.insert));
|
|
99
|
+
if (toInsertChange || fromInsertChange) {
|
|
100
|
+
return (0, setFragmentAsInserted_1.setFragmentAsInserted)(content, (0, track_utils_1.createNewInsertAttrs)(attrs), newTr.doc.type.schema);
|
|
101
|
+
}
|
|
102
|
+
return (0, track_utils_1.updateBlockNodesAttrs)(sliceContent, (_, node) => {
|
|
103
|
+
return Object.assign(Object.assign({}, _), { dataTracked: [(0, nodeHelpers_1.addTrackIdIfDoesntExist)((0, track_utils_1.createNewStructureAttrs)(Object.assign(Object.assign({}, attrs), { moveNodeId })))] });
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
exports.joinStructureChanges = joinStructureChanges;
|
|
@@ -38,6 +38,7 @@ const prosemirror_model_1 = require("prosemirror-model");
|
|
|
38
38
|
const actions_1 = require("../actions");
|
|
39
39
|
const setFragmentAsInserted_1 = require("../compute/setFragmentAsInserted");
|
|
40
40
|
const deleteAndMergeSplitNodes_1 = require("../mutate/deleteAndMergeSplitNodes");
|
|
41
|
+
const dropStructureChange_1 = require("../mutate/dropStructureChange");
|
|
41
42
|
const logger_1 = require("../utils/logger");
|
|
42
43
|
const trackUtils = __importStar(require("../utils/track-utils"));
|
|
43
44
|
const track_utils_1 = require("../utils/track-utils");
|
|
@@ -47,7 +48,6 @@ function trackReplaceStep(step, oldState, newTr, attrsTemplate, stepResult, curr
|
|
|
47
48
|
const changeSteps = [];
|
|
48
49
|
const attrs = Object.assign({}, attrsTemplate);
|
|
49
50
|
if (moveID) {
|
|
50
|
-
console.log('Detected Node Moving ReplaceStep and assigning the following movenodeID: ' + moveID);
|
|
51
51
|
attrs.moveNodeId = moveID;
|
|
52
52
|
}
|
|
53
53
|
step.getMap().forEach((fromA, toA, fromB, toB) => {
|
|
@@ -78,10 +78,13 @@ function trackReplaceStep(step, oldState, newTr, attrsTemplate, stepResult, curr
|
|
|
78
78
|
if (!backSpacedText && newSliceContent.size > 0) {
|
|
79
79
|
logger_1.log.info('newSliceContent', newSliceContent);
|
|
80
80
|
let fragment = (0, setFragmentAsInserted_1.setFragmentAsInserted)(newSliceContent, trackUtils.createNewInsertAttrs(attrs), oldState.schema);
|
|
81
|
-
if ((0, track_utils_1.
|
|
81
|
+
if ((0, track_utils_1.isStructureSteps)(tr)) {
|
|
82
|
+
fragment = (0, dropStructureChange_1.joinStructureChanges)(attrs, newSliceContent, fragment, tr, newTr);
|
|
83
|
+
}
|
|
84
|
+
else if ((0, track_utils_1.isSplitStep)(step, oldState.selection, tr.getMeta('uiEvent'))) {
|
|
82
85
|
fragment = (0, setFragmentAsInserted_1.setFragmentAsNodeSplit)(newTr.doc.resolve(step.from), newTr, fragment, attrs);
|
|
83
86
|
}
|
|
84
|
-
if (moveID) {
|
|
87
|
+
else if (moveID) {
|
|
85
88
|
const indentationType = (_a = (0, actions_1.getAction)(tr, actions_1.TrackChangesAction.indentationAction)) === null || _a === void 0 ? void 0 : _a.action;
|
|
86
89
|
fragment = (0, setFragmentAsInserted_1.setFragmentAsMoveChange)(newSliceContent, trackUtils.createNewMoveAttrs(attrs, indentationType));
|
|
87
90
|
}
|
|
@@ -74,7 +74,7 @@ function trackTransaction(tr, oldState, newTr, authorID, changeSet) {
|
|
|
74
74
|
const invertedStep = step.invert(tr.docs[i]);
|
|
75
75
|
const isDelete = step.from !== step.to && step.slice.content.size < invertedStep.slice.content.size;
|
|
76
76
|
let thisStepMapping = tr.mapping.slice(i + 1, i + 1);
|
|
77
|
-
if (isDelete) {
|
|
77
|
+
if (isDelete || (0, track_utils_1.isStructureSteps)(tr)) {
|
|
78
78
|
thisStepMapping = deletedNodeMapping;
|
|
79
79
|
}
|
|
80
80
|
const newStep = new prosemirror_transform_1.ReplaceStep(thisStepMapping.map(invertedStep.from), thisStepMapping.map(invertedStep.to), invertedStep.slice);
|
|
@@ -124,7 +124,19 @@ function trackTransaction(tr, oldState, newTr, authorID, changeSet) {
|
|
|
124
124
|
tr.getMeta('uiEvent') && newTr.setMeta('uiEvent', tr.getMeta('uiEvent'));
|
|
125
125
|
}
|
|
126
126
|
if (setsNewSelection && tr.selection instanceof prosemirror_state_1.TextSelection) {
|
|
127
|
-
|
|
127
|
+
let from = tr.selection.from;
|
|
128
|
+
if ((0, track_utils_1.isStructureSteps)(tr)) {
|
|
129
|
+
const selectionMapping = new prosemirror_transform_1.Mapping();
|
|
130
|
+
tr.steps.map((step) => {
|
|
131
|
+
const isDeleteStep = step instanceof prosemirror_transform_1.ReplaceStep && step.from !== step.to && step.slice.size === 0;
|
|
132
|
+
if (isDeleteStep) {
|
|
133
|
+
selectionMapping.appendMap(step.getMap().invert());
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
selectionMapping.appendMapping(deletedNodeMapping);
|
|
137
|
+
from = selectionMapping.map(tr.selection.from);
|
|
138
|
+
}
|
|
139
|
+
const newPos = newTr.doc.resolve(from);
|
|
128
140
|
newTr.setSelection(new prosemirror_state_1.TextSelection(newPos));
|
|
129
141
|
}
|
|
130
142
|
if (wasNodeSelection) {
|
package/dist/cjs/types/change.js
CHANGED
|
@@ -25,6 +25,7 @@ var CHANGE_OPERATION;
|
|
|
25
25
|
CHANGE_OPERATION["node_split"] = "node_split";
|
|
26
26
|
CHANGE_OPERATION["reference"] = "reference";
|
|
27
27
|
CHANGE_OPERATION["move"] = "move";
|
|
28
|
+
CHANGE_OPERATION["structure"] = "structure";
|
|
28
29
|
})(CHANGE_OPERATION || (exports.CHANGE_OPERATION = CHANGE_OPERATION = {}));
|
|
29
30
|
var CHANGE_STATUS;
|
|
30
31
|
(function (CHANGE_STATUS) {
|
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.filterMeaninglessMoveSteps = exports.handleDirectPendingMoveDeletions = exports.isDirectPendingMoveDeletion = exports.isDeletingPendingMovedNode = exports.isPendingChange = exports.HasMoveOperations = exports.trFromHistory = exports.isLiftStep = exports.isWrapStep = exports.isSplitStep = void 0;
|
|
14
|
+
exports.updateBlockNodesAttrs = exports.filterMeaninglessMoveSteps = exports.handleDirectPendingMoveDeletions = exports.isDirectPendingMoveDeletion = exports.isDeletingPendingMovedNode = exports.isPendingChange = exports.HasMoveOperations = exports.trFromHistory = exports.isStructureSteps = exports.isLiftStep = exports.isWrapStep = exports.isSplitStep = void 0;
|
|
15
15
|
exports.createNewInsertAttrs = createNewInsertAttrs;
|
|
16
16
|
exports.createNewWrapAttrs = createNewWrapAttrs;
|
|
17
17
|
exports.createNewSplitAttrs = createNewSplitAttrs;
|
|
@@ -19,8 +19,11 @@ exports.createNewReferenceAttrs = createNewReferenceAttrs;
|
|
|
19
19
|
exports.createNewDeleteAttrs = createNewDeleteAttrs;
|
|
20
20
|
exports.createNewMoveAttrs = createNewMoveAttrs;
|
|
21
21
|
exports.createNewUpdateAttrs = createNewUpdateAttrs;
|
|
22
|
+
exports.createNewStructureAttrs = createNewStructureAttrs;
|
|
22
23
|
exports.stepIsLift = stepIsLift;
|
|
24
|
+
const prosemirror_model_1 = require("prosemirror-model");
|
|
23
25
|
const prosemirror_transform_1 = require("prosemirror-transform");
|
|
26
|
+
const actions_1 = require("../actions");
|
|
24
27
|
const change_1 = require("../types/change");
|
|
25
28
|
const uuidv4_1 = require("./uuidv4");
|
|
26
29
|
function createNewInsertAttrs(attrs) {
|
|
@@ -45,6 +48,9 @@ function createNewUpdateAttrs(attrs, oldAttrs) {
|
|
|
45
48
|
const { dataTracked } = oldAttrs, restAttrs = __rest(oldAttrs, ["dataTracked"]);
|
|
46
49
|
return Object.assign(Object.assign({}, attrs), { operation: change_1.CHANGE_OPERATION.set_node_attributes, oldAttrs: JSON.parse(JSON.stringify(restAttrs)) });
|
|
47
50
|
}
|
|
51
|
+
function createNewStructureAttrs(attrs) {
|
|
52
|
+
return Object.assign(Object.assign({}, attrs), { operation: change_1.CHANGE_OPERATION.structure });
|
|
53
|
+
}
|
|
48
54
|
const isSplitStep = (step, selection, uiEvent) => {
|
|
49
55
|
var _a, _b, _c, _d;
|
|
50
56
|
const { from, to, slice } = step;
|
|
@@ -89,6 +95,11 @@ exports.isLiftStep = isLiftStep;
|
|
|
89
95
|
function stepIsLift(gap, node, to) {
|
|
90
96
|
return gap.start < gap.end && gap.insert === 0 && gap.end === to && !node.isText;
|
|
91
97
|
}
|
|
98
|
+
const isStructureSteps = (tr) => tr.getMeta(actions_1.TrackChangesAction.structuralChangeAction) &&
|
|
99
|
+
tr.steps.length === 2 &&
|
|
100
|
+
tr.steps[0] instanceof prosemirror_transform_1.ReplaceStep &&
|
|
101
|
+
tr.steps[1] instanceof prosemirror_transform_1.ReplaceStep;
|
|
102
|
+
exports.isStructureSteps = isStructureSteps;
|
|
92
103
|
const trFromHistory = (tr) => Object.keys(tr.meta).find((s) => s.startsWith('history$'));
|
|
93
104
|
exports.trFromHistory = trFromHistory;
|
|
94
105
|
const HasMoveOperations = (tr) => {
|
|
@@ -96,6 +107,12 @@ const HasMoveOperations = (tr) => {
|
|
|
96
107
|
if (tr.steps.length < 2) {
|
|
97
108
|
return movingAssoc;
|
|
98
109
|
}
|
|
110
|
+
if (tr.getMeta(actions_1.TrackChangesAction.structuralChangeAction)) {
|
|
111
|
+
const commonID = (0, uuidv4_1.uuidv4)();
|
|
112
|
+
movingAssoc.set(tr.steps[0], commonID);
|
|
113
|
+
movingAssoc.set(tr.steps[1], commonID);
|
|
114
|
+
return movingAssoc;
|
|
115
|
+
}
|
|
99
116
|
const matched = [];
|
|
100
117
|
for (let i = 0; i < tr.steps.length; i++) {
|
|
101
118
|
if (matched.includes(i)) {
|
|
@@ -211,7 +228,7 @@ const filterMeaninglessMoveSteps = (tr, movingSteps) => {
|
|
|
211
228
|
});
|
|
212
229
|
continue;
|
|
213
230
|
}
|
|
214
|
-
if (step instanceof prosemirror_transform_1.ReplaceStep) {
|
|
231
|
+
if (step instanceof prosemirror_transform_1.ReplaceStep && !tr.getMeta(actions_1.TrackChangesAction.structuralChangeAction)) {
|
|
215
232
|
const { slice } = step;
|
|
216
233
|
if ((_a = slice === null || slice === void 0 ? void 0 : slice.content) === null || _a === void 0 ? void 0 : _a.firstChild) {
|
|
217
234
|
const insertedNode = slice.content.firstChild;
|
|
@@ -229,3 +246,17 @@ const filterMeaninglessMoveSteps = (tr, movingSteps) => {
|
|
|
229
246
|
return cleanSteps;
|
|
230
247
|
};
|
|
231
248
|
exports.filterMeaninglessMoveSteps = filterMeaninglessMoveSteps;
|
|
249
|
+
const updateBlockNodesAttrs = (fragment, predicate) => {
|
|
250
|
+
const updatedNodes = [];
|
|
251
|
+
fragment.forEach((child) => {
|
|
252
|
+
if (!child.isBlock) {
|
|
253
|
+
updatedNodes.push(child);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const newContent = child.content.size ? (0, exports.updateBlockNodesAttrs)(child.content, predicate) : child.content;
|
|
257
|
+
const newAttrs = predicate(child.attrs, child);
|
|
258
|
+
updatedNodes.push(child.type.create(newAttrs, newContent, child.marks));
|
|
259
|
+
});
|
|
260
|
+
return prosemirror_model_1.Fragment.fromArray(updatedNodes);
|
|
261
|
+
};
|
|
262
|
+
exports.updateBlockNodesAttrs = updateBlockNodesAttrs;
|
package/dist/es/ChangeSet.js
CHANGED
|
@@ -86,6 +86,9 @@ export class ChangeSet {
|
|
|
86
86
|
currentInlineChange = undefined;
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
|
+
if (this.joinRelatedStructuralChanges(rootNodes, change)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
89
92
|
rootNodes.push([change]);
|
|
90
93
|
});
|
|
91
94
|
return rootNodes.filter((changes) => changes.filter((c) => c.dataTracked.operation !== CHANGE_OPERATION.reference &&
|
|
@@ -158,6 +161,20 @@ export class ChangeSet {
|
|
|
158
161
|
change.to === nextChange.from &&
|
|
159
162
|
hasMatchingOperation(change, nextChange));
|
|
160
163
|
}
|
|
164
|
+
joinRelatedStructuralChanges(rootNodes, change) {
|
|
165
|
+
if (change.dataTracked.operation !== CHANGE_OPERATION.structure) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const index = rootNodes.findIndex((c) => c[0].dataTracked.operation === CHANGE_OPERATION.structure &&
|
|
169
|
+
c[0].dataTracked.moveNodeId === change.dataTracked.moveNodeId);
|
|
170
|
+
if (index !== -1) {
|
|
171
|
+
rootNodes[index] = [...rootNodes[index], change];
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
rootNodes.push([change]);
|
|
175
|
+
}
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
161
178
|
static flattenTreeToIds(changes) {
|
|
162
179
|
return changes.flatMap((c) => (this.isNodeChange(c) ? [c.id, ...c.children.map((c) => c.id)] : c.id));
|
|
163
180
|
}
|
package/dist/es/actions.js
CHANGED
|
@@ -6,6 +6,7 @@ export var TrackChangesAction;
|
|
|
6
6
|
TrackChangesAction["setChangeStatuses"] = "track-changes-set-change-statuses";
|
|
7
7
|
TrackChangesAction["refreshChanges"] = "track-changes-refresh-changes";
|
|
8
8
|
TrackChangesAction["updateMetaNode"] = "track-changes-update-meta-node";
|
|
9
|
+
TrackChangesAction["structuralChangeAction"] = "track-changes-structural-change-action";
|
|
9
10
|
TrackChangesAction["indentationAction"] = "track-changes-indentation-action";
|
|
10
11
|
})(TrackChangesAction || (TrackChangesAction = {}));
|
|
11
12
|
export function hasAction(tr) {
|
|
@@ -23,7 +23,7 @@ export function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema,
|
|
|
23
23
|
let selectionPos = startPos;
|
|
24
24
|
let deletesCounter = 0;
|
|
25
25
|
let isInserted = false;
|
|
26
|
-
let
|
|
26
|
+
let prevDelete;
|
|
27
27
|
changes.forEach((c) => {
|
|
28
28
|
let step = newTr.steps[newTr.steps.length - 1];
|
|
29
29
|
switch (c.type) {
|
|
@@ -32,10 +32,12 @@ export function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema,
|
|
|
32
32
|
const prevDeletedNodeInserted = isInserted;
|
|
33
33
|
const trackedData = getBlockInlineTrackedData(c.node);
|
|
34
34
|
const inserted = trackedData === null || trackedData === void 0 ? void 0 : trackedData.find((d) => d.operation === CHANGE_OPERATION.insert);
|
|
35
|
-
|
|
35
|
+
const structure = trackedData === null || trackedData === void 0 ? void 0 : trackedData.find((c) => c.operation === CHANGE_OPERATION.structure &&
|
|
36
|
+
deleteAttrs.moveNodeId &&
|
|
37
|
+
c.moveNodeId !== deleteAttrs.moveNodeId);
|
|
36
38
|
let childOfDeleted = false;
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
+
if (prevDelete) {
|
|
40
|
+
prevDelete.node.descendants((node) => {
|
|
39
41
|
if (childOfDeleted) {
|
|
40
42
|
return false;
|
|
41
43
|
}
|
|
@@ -44,18 +46,20 @@ export function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema,
|
|
|
44
46
|
}
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
|
-
const nodeAtMappedPos = newTr.doc.nodeAt(mapping.map(c.pos));
|
|
48
|
-
const nodeWasAlreadyDeleted = !nodeAtMappedPos || nodeAtMappedPos !== c.node;
|
|
49
49
|
const isMoveOperation = !!emptyAttrs.moveNodeId;
|
|
50
|
-
if ((
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
if ((prevDelete &&
|
|
51
|
+
c.pos < prevDelete.nodeEnd &&
|
|
52
|
+
isInserted &&
|
|
53
|
+
deletesCounter > 1 &&
|
|
54
|
+
!isMoveOperation) ||
|
|
55
|
+
(childOfDeleted && prevDeletedNodeInserted)) {
|
|
53
56
|
return false;
|
|
54
57
|
}
|
|
55
58
|
deleteOrSetNodeDeleted(c.node, mapping.map(c.pos), newTr, deleteAttrs);
|
|
56
|
-
|
|
59
|
+
prevDelete = c;
|
|
60
|
+
isInserted = !!inserted || !!structure || (!trackedData && isInserted);
|
|
57
61
|
const newestStep = newTr.steps[newTr.steps.length - 1];
|
|
58
|
-
if (isInserted) {
|
|
62
|
+
if (isInserted || structure) {
|
|
59
63
|
deletedNodeMapping.appendMap(newestStep.getMap());
|
|
60
64
|
}
|
|
61
65
|
if (step !== newestStep) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Mapping } from 'prosemirror-transform';
|
|
2
2
|
import { ChangeSet } from '../ChangeSet';
|
|
3
|
-
import { deleteNode } from '../mutate/deleteNode';
|
|
3
|
+
import { deleteNode, keepDeleteWithMoveNodeId } from '../mutate/deleteNode';
|
|
4
4
|
import { mergeNode } from '../mutate/mergeNode';
|
|
5
5
|
import { CHANGE_OPERATION, CHANGE_STATUS } from '../types/change';
|
|
6
6
|
import { log } from '../utils/logger';
|
|
@@ -37,7 +37,8 @@ export function applyAcceptedRejectedChanges(tr, schema, changes, changeSet, del
|
|
|
37
37
|
return c1.dataTracked.updatedAt - c2.dataTracked.updatedAt;
|
|
38
38
|
});
|
|
39
39
|
changes.forEach((change) => {
|
|
40
|
-
if (change.dataTracked.operation === CHANGE_OPERATION.move
|
|
40
|
+
if (change.dataTracked.operation === CHANGE_OPERATION.move ||
|
|
41
|
+
change.dataTracked.operation === CHANGE_OPERATION.structure) {
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
if (change.dataTracked.operation === CHANGE_OPERATION.delete && change.dataTracked.moveNodeId) {
|
|
@@ -70,7 +71,7 @@ export function applyAcceptedRejectedChanges(tr, schema, changes, changeSet, del
|
|
|
70
71
|
deleteMap.appendMap(tr.steps[tr.steps.length - 1].getMap());
|
|
71
72
|
}
|
|
72
73
|
else if (ChangeSet.isNodeChange(change) && noChangeNeeded) {
|
|
73
|
-
const attrs = Object.assign(Object.assign({}, node.attrs), { dataTracked:
|
|
74
|
+
const attrs = Object.assign(Object.assign({}, node.attrs), { dataTracked: keepDeleteWithMoveNodeId(node) });
|
|
74
75
|
tr.setNodeMarkup(from, undefined, attrs, node.marks);
|
|
75
76
|
if (node.isAtom) {
|
|
76
77
|
tr.removeMark(from, deleteMap.map(change.to), schema.marks.tracked_insert);
|
|
@@ -96,7 +97,8 @@ export function applyAcceptedRejectedChanges(tr, schema, changes, changeSet, del
|
|
|
96
97
|
}
|
|
97
98
|
});
|
|
98
99
|
changes.forEach((change) => {
|
|
99
|
-
if (change.dataTracked.operation !== CHANGE_OPERATION.move
|
|
100
|
+
if (change.dataTracked.operation !== CHANGE_OPERATION.move &&
|
|
101
|
+
change.dataTracked.operation !== CHANGE_OPERATION.structure) {
|
|
100
102
|
return;
|
|
101
103
|
}
|
|
102
104
|
const { pos: from, deleted } = deleteMap.mapResult(change.from);
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { closeHistory } from 'prosemirror-history';
|
|
17
17
|
import { ChangeSet } from '../ChangeSet';
|
|
18
|
+
import { dropOrphanChanges } from '../mutate/dropStructureChange';
|
|
18
19
|
import { CHANGE_OPERATION, CHANGE_STATUS } from '../types/change';
|
|
19
20
|
import { applyAcceptedRejectedChanges } from './applyChanges';
|
|
20
21
|
import { updateChangeAttrs } from './updateChangeAttrs';
|
|
@@ -43,9 +44,7 @@ export function updateChangesStatus(createdTr, changeSet, ids, status, userID, o
|
|
|
43
44
|
c.dataTracked.operation === 'delete' &&
|
|
44
45
|
c.dataTracked.moveNodeId === change.dataTracked.moveNodeId);
|
|
45
46
|
if (oldChange && ChangeSet.isNodeChange(oldChange)) {
|
|
46
|
-
createdTr = updateChangeAttrs(createdTr, oldChange, Object.assign(Object.assign({}, oldChange.dataTracked), { status, statusUpdateAt: changeTime, reviewedByID: userID }), oldState.schema);
|
|
47
47
|
oldChange.children.forEach((child) => {
|
|
48
|
-
createdTr = updateChangeAttrs(createdTr, child, Object.assign(Object.assign({}, child.dataTracked), { status, statusUpdateAt: changeTime, reviewedByID: userID }), oldState.schema);
|
|
49
48
|
if (ChangeSet.isTextChange(child)) {
|
|
50
49
|
textChanges.push(child);
|
|
51
50
|
}
|
|
@@ -61,6 +60,7 @@ export function updateChangesStatus(createdTr, changeSet, ids, status, userID, o
|
|
|
61
60
|
});
|
|
62
61
|
const mapping = applyAcceptedRejectedChanges(createdTr, oldState.schema, nonTextChanges, changeSet);
|
|
63
62
|
applyAcceptedRejectedChanges(createdTr, oldState.schema, textChanges, changeSet, mapping);
|
|
63
|
+
dropOrphanChanges(createdTr);
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
66
|
ids.forEach((changeId) => {
|
|
@@ -2,6 +2,7 @@ import { Fragment } from 'prosemirror-model';
|
|
|
2
2
|
import { addTrackIdIfDoesntExist, getBlockInlineTrackedData } from '../compute/nodeHelpers';
|
|
3
3
|
import { CHANGE_OPERATION, CHANGE_STATUS } from '../types/change';
|
|
4
4
|
import { log } from '../utils/logger';
|
|
5
|
+
import { dropStructuralChangeShadow } from './dropStructureChange';
|
|
5
6
|
export function deleteNode(node, pos, tr) {
|
|
6
7
|
var _a;
|
|
7
8
|
const startPos = tr.doc.resolve(pos + 1);
|
|
@@ -18,7 +19,13 @@ export function deleteOrSetNodeDeleted(node, pos, newTr, deleteAttrs) {
|
|
|
18
19
|
const dataTracked = getBlockInlineTrackedData(node);
|
|
19
20
|
const inserted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => (d.operation === CHANGE_OPERATION.insert || d.operation === CHANGE_OPERATION.wrap_with_node) &&
|
|
20
21
|
(d.status === CHANGE_STATUS.pending || d.status === CHANGE_STATUS.accepted));
|
|
21
|
-
const updated = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.set_node_attributes ||
|
|
22
|
+
const updated = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.set_node_attributes ||
|
|
23
|
+
d.operation === CHANGE_OPERATION.reference ||
|
|
24
|
+
(d.operation === CHANGE_OPERATION.delete && d.moveNodeId));
|
|
25
|
+
const structure = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((c) => c.operation === CHANGE_OPERATION.structure);
|
|
26
|
+
if (deleteAttrs.moveNodeId && structure && structure.moveNodeId !== deleteAttrs.moveNodeId) {
|
|
27
|
+
return newTr.delete(pos, pos + node.nodeSize);
|
|
28
|
+
}
|
|
22
29
|
const moved = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.move && d.status === CHANGE_STATUS.pending);
|
|
23
30
|
if (inserted) {
|
|
24
31
|
return deleteNode(node, pos, newTr);
|
|
@@ -33,4 +40,12 @@ export function deleteOrSetNodeDeleted(node, pos, newTr, deleteAttrs) {
|
|
|
33
40
|
}
|
|
34
41
|
const newDeleted = addTrackIdIfDoesntExist(deleteAttrs);
|
|
35
42
|
newTr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { dataTracked: updated ? [newDeleted, updated] : moved ? [newDeleted, moved] : [newDeleted] }), node.marks);
|
|
43
|
+
if (!deleteAttrs.moveNodeId && (structure === null || structure === void 0 ? void 0 : structure.moveNodeId)) {
|
|
44
|
+
dropStructuralChangeShadow(structure.moveNodeId, newTr);
|
|
45
|
+
}
|
|
36
46
|
}
|
|
47
|
+
export const keepDeleteWithMoveNodeId = (node) => {
|
|
48
|
+
var _a;
|
|
49
|
+
const dataTracked = (_a = getBlockInlineTrackedData(node)) === null || _a === void 0 ? void 0 : _a.filter((c) => c.operation === CHANGE_OPERATION.delete && c.moveNodeId);
|
|
50
|
+
return (dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.length) ? dataTracked : null;
|
|
51
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { Fragment } from 'prosemirror-model';
|
|
13
|
+
import { EditorState } from 'prosemirror-state';
|
|
14
|
+
import { findChanges } from '../changes/findChanges';
|
|
15
|
+
import { updateChangeAttrs } from '../changes/updateChangeAttrs';
|
|
16
|
+
import { addTrackIdIfDoesntExist, getBlockInlineTrackedData } from '../compute/nodeHelpers';
|
|
17
|
+
import { setFragmentAsInserted } from '../compute/setFragmentAsInserted';
|
|
18
|
+
import { CHANGE_OPERATION } from '../types/change';
|
|
19
|
+
import { createNewInsertAttrs, createNewStructureAttrs, updateBlockNodesAttrs } from '../utils/track-utils';
|
|
20
|
+
export const dropStructuralChangeShadow = (moveNodeId, tr) => {
|
|
21
|
+
const changeSet = findChanges(EditorState.create({ doc: tr.doc }));
|
|
22
|
+
const changes = changeSet.changes.filter((c) => c.type === 'node-change' && c.dataTracked.moveNodeId === moveNodeId);
|
|
23
|
+
const shadow = changes.filter((c) => c.dataTracked.operation === CHANGE_OPERATION.delete);
|
|
24
|
+
const structures = changes.filter((c) => c.dataTracked.operation === CHANGE_OPERATION.structure);
|
|
25
|
+
structures.map((c) => {
|
|
26
|
+
tr.setNodeMarkup(c.from, undefined, Object.assign(Object.assign({}, c.node.attrs), { dataTracked: null }));
|
|
27
|
+
});
|
|
28
|
+
if (shadow.length > 0) {
|
|
29
|
+
tr.delete(shadow[0].from, shadow[shadow.length - 1].to);
|
|
30
|
+
}
|
|
31
|
+
return tr;
|
|
32
|
+
};
|
|
33
|
+
export const dropOrphanChanges = (newTr, dropDataTracked) => {
|
|
34
|
+
const changeSet = findChanges(EditorState.create({ doc: newTr.doc }));
|
|
35
|
+
const shadowIds = new Set();
|
|
36
|
+
const changesIds = new Set();
|
|
37
|
+
changeSet.changes.forEach((c) => {
|
|
38
|
+
if (c.dataTracked.moveNodeId && c.dataTracked.operation === CHANGE_OPERATION.delete) {
|
|
39
|
+
shadowIds.add(c.dataTracked.moveNodeId);
|
|
40
|
+
}
|
|
41
|
+
if (c.dataTracked.operation === CHANGE_OPERATION.structure ||
|
|
42
|
+
c.dataTracked.operation === CHANGE_OPERATION.move) {
|
|
43
|
+
changesIds.add(c.dataTracked.moveNodeId);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
if (!shadowIds.size && !changesIds.size) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
changeSet.changes.forEach((c) => {
|
|
50
|
+
if (c.dataTracked.moveNodeId &&
|
|
51
|
+
!(shadowIds.has(c.dataTracked.moveNodeId) && changesIds.has(c.dataTracked.moveNodeId))) {
|
|
52
|
+
if (c.dataTracked.operation === CHANGE_OPERATION.delete || dropDataTracked) {
|
|
53
|
+
if (c.type === 'text-change') {
|
|
54
|
+
newTr.removeMark(c.from, c.to, newTr.doc.type.schema.marks.tracked_delete);
|
|
55
|
+
}
|
|
56
|
+
else if (c.type === 'node-change') {
|
|
57
|
+
newTr.setNodeMarkup(c.from, undefined, Object.assign(Object.assign({}, c.node.attrs), { dataTracked: null }));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (c.type === 'node-change') {
|
|
61
|
+
const _a = c.dataTracked, { id, moveNodeId } = _a, attrs = __rest(_a, ["id", "moveNodeId"]);
|
|
62
|
+
newTr.replaceWith(c.from, c.to, setFragmentAsInserted(Fragment.from(c.node), createNewInsertAttrs(attrs), newTr.doc.type.schema));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
const groupStructureChanges = (tr, toNode) => {
|
|
68
|
+
const moveNodeIds = new Set();
|
|
69
|
+
const [insertStep, deleteStep] = tr.steps;
|
|
70
|
+
const fromNodes = tr.docs[1].slice(deleteStep.from, deleteStep.to).content;
|
|
71
|
+
const ignoredNode = tr.docs[1].nodeAt(deleteStep.from);
|
|
72
|
+
Fragment.from(toNode)
|
|
73
|
+
.append(insertStep.slice.content)
|
|
74
|
+
.append(fromNodes)
|
|
75
|
+
.descendants((node) => {
|
|
76
|
+
var _a;
|
|
77
|
+
const moveNodeId = (_a = (getBlockInlineTrackedData(node) || []).find((c) => c.operation === CHANGE_OPERATION.structure)) === null || _a === void 0 ? void 0 : _a.moveNodeId;
|
|
78
|
+
moveNodeId && moveNodeIds.add(moveNodeId);
|
|
79
|
+
});
|
|
80
|
+
return moveNodeIds;
|
|
81
|
+
};
|
|
82
|
+
export const joinStructureChanges = (attrs, sliceContent, content, tr, newTr) => {
|
|
83
|
+
var _a, _b, _c;
|
|
84
|
+
const moveNodeId = attrs.moveNodeId;
|
|
85
|
+
let toNode = tr.docs[0].resolve(tr.steps[0].from).node();
|
|
86
|
+
toNode = ((_a = toNode === null || toNode === void 0 ? void 0 : toNode.type.spec.attrs) === null || _a === void 0 ? void 0 : _a.dataTracked) ? toNode : null;
|
|
87
|
+
const idsSet = groupStructureChanges(tr, toNode);
|
|
88
|
+
const changeSet = findChanges(EditorState.create({ doc: newTr.doc }));
|
|
89
|
+
const relatedChanges = changeSet.changes.filter((c) => c.dataTracked.moveNodeId && idsSet.has(c.dataTracked.moveNodeId));
|
|
90
|
+
relatedChanges.map((c) => updateChangeAttrs(newTr, c, Object.assign(Object.assign({}, c.dataTracked), { moveNodeId }), newTr.doc.type.schema));
|
|
91
|
+
const toInsertChange = toNode && ((_b = getBlockInlineTrackedData(toNode)) === null || _b === void 0 ? void 0 : _b.find((c) => c.operation === CHANGE_OPERATION.insert));
|
|
92
|
+
const fromInsertChange = sliceContent.firstChild &&
|
|
93
|
+
((_c = getBlockInlineTrackedData(sliceContent.firstChild)) === null || _c === void 0 ? void 0 : _c.find((c) => c.operation === CHANGE_OPERATION.insert));
|
|
94
|
+
if (toInsertChange || fromInsertChange) {
|
|
95
|
+
return setFragmentAsInserted(content, createNewInsertAttrs(attrs), newTr.doc.type.schema);
|
|
96
|
+
}
|
|
97
|
+
return updateBlockNodesAttrs(sliceContent, (_, node) => {
|
|
98
|
+
return Object.assign(Object.assign({}, _), { dataTracked: [addTrackIdIfDoesntExist(createNewStructureAttrs(Object.assign(Object.assign({}, attrs), { moveNodeId })))] });
|
|
99
|
+
});
|
|
100
|
+
};
|
|
@@ -2,16 +2,16 @@ import { Slice } from 'prosemirror-model';
|
|
|
2
2
|
import { getAction, TrackChangesAction } from '../actions';
|
|
3
3
|
import { setFragmentAsInserted, setFragmentAsMoveChange, setFragmentAsNodeSplit, } from '../compute/setFragmentAsInserted';
|
|
4
4
|
import { deleteAndMergeSplitNodes } from '../mutate/deleteAndMergeSplitNodes';
|
|
5
|
+
import { joinStructureChanges } from '../mutate/dropStructureChange';
|
|
5
6
|
import { log } from '../utils/logger';
|
|
6
7
|
import * as trackUtils from '../utils/track-utils';
|
|
7
|
-
import { isSplitStep } from '../utils/track-utils';
|
|
8
|
+
import { isSplitStep, isStructureSteps } from '../utils/track-utils';
|
|
8
9
|
export function trackReplaceStep(step, oldState, newTr, attrsTemplate, stepResult, currentStepDoc, tr, moveID) {
|
|
9
10
|
log.info('###### ReplaceStep ######');
|
|
10
11
|
let selectionPos = 0;
|
|
11
12
|
const changeSteps = [];
|
|
12
13
|
const attrs = Object.assign({}, attrsTemplate);
|
|
13
14
|
if (moveID) {
|
|
14
|
-
console.log('Detected Node Moving ReplaceStep and assigning the following movenodeID: ' + moveID);
|
|
15
15
|
attrs.moveNodeId = moveID;
|
|
16
16
|
}
|
|
17
17
|
step.getMap().forEach((fromA, toA, fromB, toB) => {
|
|
@@ -42,10 +42,13 @@ export function trackReplaceStep(step, oldState, newTr, attrsTemplate, stepResul
|
|
|
42
42
|
if (!backSpacedText && newSliceContent.size > 0) {
|
|
43
43
|
log.info('newSliceContent', newSliceContent);
|
|
44
44
|
let fragment = setFragmentAsInserted(newSliceContent, trackUtils.createNewInsertAttrs(attrs), oldState.schema);
|
|
45
|
-
if (
|
|
45
|
+
if (isStructureSteps(tr)) {
|
|
46
|
+
fragment = joinStructureChanges(attrs, newSliceContent, fragment, tr, newTr);
|
|
47
|
+
}
|
|
48
|
+
else if (isSplitStep(step, oldState.selection, tr.getMeta('uiEvent'))) {
|
|
46
49
|
fragment = setFragmentAsNodeSplit(newTr.doc.resolve(step.from), newTr, fragment, attrs);
|
|
47
50
|
}
|
|
48
|
-
if (moveID) {
|
|
51
|
+
else if (moveID) {
|
|
49
52
|
const indentationType = (_a = getAction(tr, TrackChangesAction.indentationAction)) === null || _a === void 0 ? void 0 : _a.action;
|
|
50
53
|
fragment = setFragmentAsMoveChange(newSliceContent, trackUtils.createNewMoveAttrs(attrs, indentationType));
|
|
51
54
|
}
|
|
@@ -8,7 +8,7 @@ import { getNodeTrackedData } from '../compute/nodeHelpers';
|
|
|
8
8
|
import { CHANGE_STATUS } from '../types/change';
|
|
9
9
|
import { log } from '../utils/logger';
|
|
10
10
|
import { mapChangeSteps } from '../utils/mapChangeStep';
|
|
11
|
-
import { filterMeaninglessMoveSteps, handleDirectPendingMoveDeletions, HasMoveOperations, } from '../utils/track-utils';
|
|
11
|
+
import { filterMeaninglessMoveSteps, handleDirectPendingMoveDeletions, HasMoveOperations, isStructureSteps, } from '../utils/track-utils';
|
|
12
12
|
import { uuidv4 } from '../utils/uuidv4';
|
|
13
13
|
import trackAttrsChange from './trackAttrsChange';
|
|
14
14
|
import { trackReplaceAroundStep } from './trackReplaceAroundStep';
|
|
@@ -68,7 +68,7 @@ export function trackTransaction(tr, oldState, newTr, authorID, changeSet) {
|
|
|
68
68
|
const invertedStep = step.invert(tr.docs[i]);
|
|
69
69
|
const isDelete = step.from !== step.to && step.slice.content.size < invertedStep.slice.content.size;
|
|
70
70
|
let thisStepMapping = tr.mapping.slice(i + 1, i + 1);
|
|
71
|
-
if (isDelete) {
|
|
71
|
+
if (isDelete || isStructureSteps(tr)) {
|
|
72
72
|
thisStepMapping = deletedNodeMapping;
|
|
73
73
|
}
|
|
74
74
|
const newStep = new ReplaceStep(thisStepMapping.map(invertedStep.from), thisStepMapping.map(invertedStep.to), invertedStep.slice);
|
|
@@ -118,7 +118,19 @@ export function trackTransaction(tr, oldState, newTr, authorID, changeSet) {
|
|
|
118
118
|
tr.getMeta('uiEvent') && newTr.setMeta('uiEvent', tr.getMeta('uiEvent'));
|
|
119
119
|
}
|
|
120
120
|
if (setsNewSelection && tr.selection instanceof TextSelection) {
|
|
121
|
-
|
|
121
|
+
let from = tr.selection.from;
|
|
122
|
+
if (isStructureSteps(tr)) {
|
|
123
|
+
const selectionMapping = new Mapping();
|
|
124
|
+
tr.steps.map((step) => {
|
|
125
|
+
const isDeleteStep = step instanceof ReplaceStep && step.from !== step.to && step.slice.size === 0;
|
|
126
|
+
if (isDeleteStep) {
|
|
127
|
+
selectionMapping.appendMap(step.getMap().invert());
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
selectionMapping.appendMapping(deletedNodeMapping);
|
|
131
|
+
from = selectionMapping.map(tr.selection.from);
|
|
132
|
+
}
|
|
133
|
+
const newPos = newTr.doc.resolve(from);
|
|
122
134
|
newTr.setSelection(new TextSelection(newPos));
|
|
123
135
|
}
|
|
124
136
|
if (wasNodeSelection) {
|
package/dist/es/types/change.js
CHANGED
|
@@ -22,6 +22,7 @@ export var CHANGE_OPERATION;
|
|
|
22
22
|
CHANGE_OPERATION["node_split"] = "node_split";
|
|
23
23
|
CHANGE_OPERATION["reference"] = "reference";
|
|
24
24
|
CHANGE_OPERATION["move"] = "move";
|
|
25
|
+
CHANGE_OPERATION["structure"] = "structure";
|
|
25
26
|
})(CHANGE_OPERATION || (CHANGE_OPERATION = {}));
|
|
26
27
|
export var CHANGE_STATUS;
|
|
27
28
|
(function (CHANGE_STATUS) {
|
|
@@ -9,7 +9,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
+
import { Fragment } from 'prosemirror-model';
|
|
12
13
|
import { ReplaceStep } from 'prosemirror-transform';
|
|
14
|
+
import { TrackChangesAction } from '../actions';
|
|
13
15
|
import { CHANGE_OPERATION, CHANGE_STATUS } from '../types/change';
|
|
14
16
|
import { uuidv4 } from './uuidv4';
|
|
15
17
|
export function createNewInsertAttrs(attrs) {
|
|
@@ -34,6 +36,9 @@ export function createNewUpdateAttrs(attrs, oldAttrs) {
|
|
|
34
36
|
const { dataTracked } = oldAttrs, restAttrs = __rest(oldAttrs, ["dataTracked"]);
|
|
35
37
|
return Object.assign(Object.assign({}, attrs), { operation: CHANGE_OPERATION.set_node_attributes, oldAttrs: JSON.parse(JSON.stringify(restAttrs)) });
|
|
36
38
|
}
|
|
39
|
+
export function createNewStructureAttrs(attrs) {
|
|
40
|
+
return Object.assign(Object.assign({}, attrs), { operation: CHANGE_OPERATION.structure });
|
|
41
|
+
}
|
|
37
42
|
export const isSplitStep = (step, selection, uiEvent) => {
|
|
38
43
|
var _a, _b, _c, _d;
|
|
39
44
|
const { from, to, slice } = step;
|
|
@@ -75,12 +80,22 @@ export const isLiftStep = (step) => {
|
|
|
75
80
|
export function stepIsLift(gap, node, to) {
|
|
76
81
|
return gap.start < gap.end && gap.insert === 0 && gap.end === to && !node.isText;
|
|
77
82
|
}
|
|
83
|
+
export const isStructureSteps = (tr) => tr.getMeta(TrackChangesAction.structuralChangeAction) &&
|
|
84
|
+
tr.steps.length === 2 &&
|
|
85
|
+
tr.steps[0] instanceof ReplaceStep &&
|
|
86
|
+
tr.steps[1] instanceof ReplaceStep;
|
|
78
87
|
export const trFromHistory = (tr) => Object.keys(tr.meta).find((s) => s.startsWith('history$'));
|
|
79
88
|
export const HasMoveOperations = (tr) => {
|
|
80
89
|
const movingAssoc = new Map();
|
|
81
90
|
if (tr.steps.length < 2) {
|
|
82
91
|
return movingAssoc;
|
|
83
92
|
}
|
|
93
|
+
if (tr.getMeta(TrackChangesAction.structuralChangeAction)) {
|
|
94
|
+
const commonID = uuidv4();
|
|
95
|
+
movingAssoc.set(tr.steps[0], commonID);
|
|
96
|
+
movingAssoc.set(tr.steps[1], commonID);
|
|
97
|
+
return movingAssoc;
|
|
98
|
+
}
|
|
84
99
|
const matched = [];
|
|
85
100
|
for (let i = 0; i < tr.steps.length; i++) {
|
|
86
101
|
if (matched.includes(i)) {
|
|
@@ -191,7 +206,7 @@ export const filterMeaninglessMoveSteps = (tr, movingSteps) => {
|
|
|
191
206
|
});
|
|
192
207
|
continue;
|
|
193
208
|
}
|
|
194
|
-
if (step instanceof ReplaceStep) {
|
|
209
|
+
if (step instanceof ReplaceStep && !tr.getMeta(TrackChangesAction.structuralChangeAction)) {
|
|
195
210
|
const { slice } = step;
|
|
196
211
|
if ((_a = slice === null || slice === void 0 ? void 0 : slice.content) === null || _a === void 0 ? void 0 : _a.firstChild) {
|
|
197
212
|
const insertedNode = slice.content.firstChild;
|
|
@@ -208,3 +223,16 @@ export const filterMeaninglessMoveSteps = (tr, movingSteps) => {
|
|
|
208
223
|
}
|
|
209
224
|
return cleanSteps;
|
|
210
225
|
};
|
|
226
|
+
export const updateBlockNodesAttrs = (fragment, predicate) => {
|
|
227
|
+
const updatedNodes = [];
|
|
228
|
+
fragment.forEach((child) => {
|
|
229
|
+
if (!child.isBlock) {
|
|
230
|
+
updatedNodes.push(child);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const newContent = child.content.size ? updateBlockNodesAttrs(child.content, predicate) : child.content;
|
|
234
|
+
const newAttrs = predicate(child.attrs, child);
|
|
235
|
+
updatedNodes.push(child.type.create(newAttrs, newContent, child.marks));
|
|
236
|
+
});
|
|
237
|
+
return Fragment.fromArray(updatedNodes);
|
|
238
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IncompleteChange, NodeAttrChange, NodeChange, ReferenceChange, TextChange, TrackedAttrs, TrackedChange } from './types/change';
|
|
1
|
+
import { IncompleteChange, NodeAttrChange, NodeChange, ReferenceChange, RootChanges, TextChange, TrackedAttrs, TrackedChange } from './types/change';
|
|
2
2
|
export declare class ChangeSet {
|
|
3
3
|
#private;
|
|
4
4
|
constructor(changes?: (TrackedChange | IncompleteChange)[]);
|
|
@@ -23,6 +23,7 @@ export declare class ChangeSet {
|
|
|
23
23
|
root: NodeChange;
|
|
24
24
|
} | undefined;
|
|
25
25
|
canJoinAdjacentInlineChanges(change: TrackedChange, index: number): boolean | undefined;
|
|
26
|
+
joinRelatedStructuralChanges(rootNodes: RootChanges, change: TrackedChange): true | undefined;
|
|
26
27
|
static flattenTreeToIds(changes: TrackedChange[]): string[];
|
|
27
28
|
static shouldDeleteChange(change: TrackedChange): boolean;
|
|
28
29
|
static isValidDataTracked(dataTracked?: Partial<TrackedAttrs>): boolean;
|
package/dist/types/actions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transaction } from 'prosemirror-state';
|
|
2
|
-
import { CHANGE_STATUS } from './types/change';
|
|
2
|
+
import { CHANGE_STATUS, StructureAttrs } from './types/change';
|
|
3
3
|
import { TrackChangesStatus } from './types/track';
|
|
4
4
|
export declare enum TrackChangesAction {
|
|
5
5
|
skipTrack = "track-changes-skip-tracking",
|
|
@@ -8,6 +8,7 @@ export declare enum TrackChangesAction {
|
|
|
8
8
|
setChangeStatuses = "track-changes-set-change-statuses",
|
|
9
9
|
refreshChanges = "track-changes-refresh-changes",
|
|
10
10
|
updateMetaNode = "track-changes-update-meta-node",
|
|
11
|
+
structuralChangeAction = "track-changes-structural-change-action",
|
|
11
12
|
indentationAction = "track-changes-indentation-action"
|
|
12
13
|
}
|
|
13
14
|
export type TrackChangesActionParams = {
|
|
@@ -20,6 +21,7 @@ export type TrackChangesActionParams = {
|
|
|
20
21
|
};
|
|
21
22
|
[TrackChangesAction.refreshChanges]: boolean;
|
|
22
23
|
[TrackChangesAction.updateMetaNode]: boolean;
|
|
24
|
+
[TrackChangesAction.structuralChangeAction]: StructureAttrs['action'];
|
|
23
25
|
[TrackChangesAction.indentationAction]: {
|
|
24
26
|
action: 'indent' | 'unindent';
|
|
25
27
|
};
|
|
@@ -3,3 +3,4 @@ import { Transaction } from 'prosemirror-state';
|
|
|
3
3
|
import { NewDeleteAttrs } from '../types/track';
|
|
4
4
|
export declare function deleteNode(node: PMNode, pos: number, tr: Transaction): Transaction;
|
|
5
5
|
export declare function deleteOrSetNodeDeleted(node: PMNode, pos: number, newTr: Transaction, deleteAttrs: NewDeleteAttrs): Transaction | undefined;
|
|
6
|
+
export declare const keepDeleteWithMoveNodeId: (node: PMNode) => Partial<import("../types/change").TrackedAttrs>[] | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Fragment } from 'prosemirror-model';
|
|
2
|
+
import { Transaction } from 'prosemirror-state';
|
|
3
|
+
import { NewEmptyAttrs } from '../types/track';
|
|
4
|
+
export declare const dropStructuralChangeShadow: (moveNodeId: string | undefined, tr: Transaction) => Transaction;
|
|
5
|
+
export declare const dropOrphanChanges: (newTr: Transaction, dropDataTracked?: boolean) => void;
|
|
6
|
+
export declare const joinStructureChanges: (attrs: NewEmptyAttrs, sliceContent: Fragment, content: Fragment, tr: Transaction, newTr: Transaction) => Fragment;
|
|
@@ -21,7 +21,8 @@ export declare enum CHANGE_OPERATION {
|
|
|
21
21
|
wrap_with_node = "wrap_with_node",
|
|
22
22
|
node_split = "node_split",
|
|
23
23
|
reference = "reference",
|
|
24
|
-
move = "move"
|
|
24
|
+
move = "move",
|
|
25
|
+
structure = "structure"
|
|
25
26
|
}
|
|
26
27
|
export declare enum CHANGE_STATUS {
|
|
27
28
|
accepted = "accepted",
|
|
@@ -57,7 +58,11 @@ export type NodeMoveAttrs = Omit<InsertDeleteAttrs, 'operation'> & {
|
|
|
57
58
|
operation: CHANGE_OPERATION.move;
|
|
58
59
|
indentationType?: 'indent' | 'unindent';
|
|
59
60
|
};
|
|
60
|
-
export type
|
|
61
|
+
export type StructureAttrs = Omit<InsertDeleteAttrs, 'operation'> & {
|
|
62
|
+
operation: CHANGE_OPERATION.structure;
|
|
63
|
+
action: string;
|
|
64
|
+
};
|
|
65
|
+
export type TrackedAttrs = InsertDeleteAttrs | UpdateAttrs | WrapAttrs | NodeSplitAttrs | ReferenceAttrs | NodeMoveAttrs | StructureAttrs;
|
|
61
66
|
type Change = {
|
|
62
67
|
id: string;
|
|
63
68
|
from: number;
|
|
@@ -16,7 +16,7 @@ export interface TrackChangesState {
|
|
|
16
16
|
}
|
|
17
17
|
export type NewEmptyAttrs = Omit<TrackedAttrs, 'id' | 'operation'>;
|
|
18
18
|
export type NewInsertAttrs = Omit<TrackedAttrs, 'id' | 'operation'> & {
|
|
19
|
-
operation: CHANGE_OPERATION.insert | CHANGE_OPERATION.wrap_with_node;
|
|
19
|
+
operation: CHANGE_OPERATION.insert | CHANGE_OPERATION.wrap_with_node | CHANGE_OPERATION.structure;
|
|
20
20
|
};
|
|
21
21
|
export type NewDeleteAttrs = Omit<TrackedAttrs, 'id' | 'operation'> & {
|
|
22
22
|
operation: CHANGE_OPERATION.delete;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Node as PMNode, Slice } from 'prosemirror-model';
|
|
1
|
+
import { Attrs, Fragment, Node as PMNode, Slice } from 'prosemirror-model';
|
|
2
2
|
import { Selection, Transaction } from 'prosemirror-state';
|
|
3
3
|
import { ReplaceAroundStep, ReplaceStep, Step } from 'prosemirror-transform';
|
|
4
4
|
import { CHANGE_OPERATION, TrackedAttrs } from '../types/change';
|
|
@@ -10,6 +10,7 @@ export declare function createNewReferenceAttrs(attrs: NewEmptyAttrs, id: string
|
|
|
10
10
|
export declare function createNewDeleteAttrs(attrs: NewEmptyAttrs): NewDeleteAttrs;
|
|
11
11
|
export declare function createNewMoveAttrs(attrs: NewEmptyAttrs, indentationType?: 'indent' | 'unindent'): NewMoveAttrs;
|
|
12
12
|
export declare function createNewUpdateAttrs(attrs: NewEmptyAttrs, oldAttrs: Record<string, any>): NewUpdateAttrs;
|
|
13
|
+
export declare function createNewStructureAttrs(attrs: NewEmptyAttrs): NewInsertAttrs;
|
|
13
14
|
export declare const isSplitStep: (step: ReplaceStep, selection: Selection, uiEvent: string) => boolean;
|
|
14
15
|
export declare const isWrapStep: (step: ReplaceAroundStep) => boolean;
|
|
15
16
|
export declare const isLiftStep: (step: ReplaceAroundStep) => boolean;
|
|
@@ -19,6 +20,7 @@ export declare function stepIsLift(gap: {
|
|
|
19
20
|
slice: Slice;
|
|
20
21
|
insert: number;
|
|
21
22
|
}, node: PMNode, to: number): boolean;
|
|
23
|
+
export declare const isStructureSteps: (tr: Transaction) => any;
|
|
22
24
|
export declare const trFromHistory: (tr: Transaction) => string | undefined;
|
|
23
25
|
export declare const HasMoveOperations: (tr: Transaction) => Map<ReplaceStep, string>;
|
|
24
26
|
export declare const isPendingChange: (trackedAttrs: TrackedAttrs[] | undefined, operation: CHANGE_OPERATION) => boolean;
|
|
@@ -26,3 +28,4 @@ export declare const isDeletingPendingMovedNode: (step: ReplaceStep, doc: PMNode
|
|
|
26
28
|
export declare const isDirectPendingMoveDeletion: (step: ReplaceStep, doc: PMNode, movingSteps: Map<ReplaceStep, string>) => boolean;
|
|
27
29
|
export declare const handleDirectPendingMoveDeletions: (tr: Transaction, newTr: Transaction, movingSteps: Map<ReplaceStep, string>) => void;
|
|
28
30
|
export declare const filterMeaninglessMoveSteps: (tr: Transaction, movingSteps: Map<ReplaceStep, string>) => Step[];
|
|
31
|
+
export declare const updateBlockNodesAttrs: (fragment: Fragment, predicate: (attrs: Attrs, node: PMNode) => Attrs) => Fragment;
|
package/package.json
CHANGED