-
Notifications
You must be signed in to change notification settings - Fork 127
Expand file tree
/
Copy pathreplaceStep.js
More file actions
91 lines (76 loc) · 2.95 KB
/
replaceStep.js
File metadata and controls
91 lines (76 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { ReplaceStep, Mapping } from 'prosemirror-transform';
import { Transaction, EditorState } from 'prosemirror-state';
import { Node } from 'prosemirror-model';
import { markInsertion } from './markInsertion.js';
import { markDeletion } from './markDeletion.js';
import { findMark } from '@core/helpers/index.js';
import { TrackDeleteMarkName } from '../constants.js';
import { TrackChangesBasePluginKey } from '../plugins/index.js';
/**
* Replace step.
* @param {EditorState} options.state Editor state.
* @param {Transaction} options.tr Transaction.
* @param {ReplaceStep} options.step Step.
* @param {Transaction} options.newTr New transaction.
* @param {Mapping} options.map Map.
* @param {Node} options.doc Doc.
* @param {object} options.user User object ({ name, email }).
* @param {string} options.date Date.
* @param {ReplaceStep} options.originalStep Original step.
* @param {number} options.originalStepIndex Original step index.
*/
export const replaceStep = ({ state, tr, step, newTr, map, doc, user, date, originalStep, originalStepIndex }) => {
const deletionMarkSchema = state.schema.marks[TrackDeleteMarkName];
const deletionMark = findMark(state, deletionMarkSchema, false);
const positionTo = deletionMark ? deletionMark.to : step.to;
const newStep = new ReplaceStep(
positionTo, // We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
positionTo,
step.slice,
step.structure,
);
// We didn't apply the original step in its original place. We adjust the map accordingly.
const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map);
map.appendMap(invertStep.getMap());
const meta = {};
if (newStep) {
const trTemp = state.apply(newTr).tr;
if (trTemp.maybeStep(newStep).failed) {
return;
}
const mappedNewStepTo = newStep.getMap().map(newStep.to);
const insertedMark = markInsertion({
tr: trTemp,
from: newStep.from,
to: mappedNewStepTo,
user,
date,
});
// We condense it down to a single replace step.
const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
newTr.step(condensedStep);
const mirrorIndex = map.maps.length - 1;
map.appendMap(condensedStep.getMap(), mirrorIndex);
if (newStep.from !== mappedNewStepTo) {
meta.insertedMark = insertedMark;
meta.step = condensedStep;
}
if (!newTr.selection.eq(trTemp.selection)) {
newTr.setSelection(trTemp.selection);
}
}
if (step.from !== step.to) {
const { deletionMark, deletionMap, nodes: deletionNodes } = markDeletion({
tr: newTr,
from: step.from,
to: step.to,
user,
date,
});
meta.deletionNodes = deletionNodes;
meta.deletionMark = deletionMark;
map.appendMapping(deletionMap);
}
// Add meta to the new transaction.
newTr.setMeta(TrackChangesBasePluginKey, meta);
};