Fix collaborative undo correctness (fixes #2105) #2500
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Inspired by #2433. Thank you to @rhysbrettbowen for the bug report and suggested solution. This PR takes a similar approach, but calls
guessUndoDelta
(nowinvertDelta
) directly fromchange(...)
for simpler logic.In this PR:
{undo,redo}
records.guessUndoDelta
to be a real delta inversion,invertDelta
, because it was not too far off! This routine could be extracted into quill-delta (see Could we have anundoCompose
function? For calculating the reverse of a delta when composed with a base delta. delta#28 ; I thinkinvert
is perhaps a better name thanundoCompose
).To give an example of why (2) is necessary, even after fixing (1): Suppose you type
xxx
, and a collaborator comes along and makes ityxyxyxy
. You then undo, and the editor correctly removes the x's and leaves you withyyyy
. However, when you then go to redo, the correct redo is to insert three x's in different places. If you use the original redo delta with appropriate transformations, what you get isinsert xxx
transformed againstinsert yyyy
, which is not going to result in inserting the three x's in different places. So with this change, the redo delta is generated at the time the undo is applied. I added this example as a test case.I have lightly tested undo in Quill after this change, but not in a real collaborative context (i.e. the real the version of what the tests are testing).