follow redone items to prevent some undo-redo issues. Fixes #162

This commit is contained in:
Kevin Jahns 2019-10-08 18:31:56 +02:00
parent 6d4f0c0cdd
commit aeb23dbaa9
3 changed files with 21 additions and 4 deletions

View File

@ -35,6 +35,8 @@ import * as set from 'lib0/set.js'
import * as binary from 'lib0/binary.js'
/**
* @todo This should return several items
*
* @param {StructStore} store
* @param {ID} id
* @return {{item:Item, diff:number}}

View File

@ -75,15 +75,15 @@ const popStackItem = (undoManager, stack, eventType) => {
itemsToRedo.add(struct)
}
})
itemsToRedo.forEach(item => {
performedChange = redoItem(transaction, item, itemsToRedo) !== null || performedChange
itemsToRedo.forEach(struct => {
performedChange = redoItem(transaction, struct, itemsToRedo) !== null || performedChange
})
/**
* @type {Array<Item>}
*/
const itemsToDelete = []
iterateStructs(transaction, structs, stackStartClock, stackItem.len, struct => {
if (struct instanceof Item && !struct.deleted && scope.some(type => isParentOf(type, /** @type {Item} */ (struct)))) {
if (struct instanceof Item) {
if (struct.redone !== null) {
let { item, diff } = followRedone(store, struct.id)
if (diff > 0) {
@ -94,7 +94,9 @@ const popStackItem = (undoManager, stack, eventType) => {
}
struct = item
}
itemsToDelete.push(struct)
if (!struct.deleted && scope.some(type => isParentOf(type, /** @type {Item} */ (struct)))) {
itemsToDelete.push(struct)
}
}
})
// We want to delete in reverse order so that children are deleted before

View File

@ -13,10 +13,23 @@ import * as t from 'lib0/testing.js'
export const testUndoText = tc => {
const { testConnector, text0, text1 } = init(tc, { users: 3 })
const undoManager = new UndoManager(text0)
// items that are added & deleted in the same transaction won't be undo
text0.insert(0, 'test')
text0.delete(0, 4)
undoManager.undo()
t.assert(text0.toString() === '')
// follow redone items
text0.insert(0, 'a')
undoManager.stopCapturing()
text0.delete(0, 1)
undoManager.stopCapturing()
undoManager.undo()
t.assert(text0.toString() === 'a')
undoManager.undo()
t.assert(text0.toString() === '')
text0.insert(0, 'abc')
text1.insert(0, 'xyz')
testConnector.syncAll()