follow redone items to prevent some undo-redo issues. Fixes #162
This commit is contained in:
parent
6d4f0c0cdd
commit
aeb23dbaa9
@ -35,6 +35,8 @@ import * as set from 'lib0/set.js'
|
|||||||
import * as binary from 'lib0/binary.js'
|
import * as binary from 'lib0/binary.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @todo This should return several items
|
||||||
|
*
|
||||||
* @param {StructStore} store
|
* @param {StructStore} store
|
||||||
* @param {ID} id
|
* @param {ID} id
|
||||||
* @return {{item:Item, diff:number}}
|
* @return {{item:Item, diff:number}}
|
||||||
|
@ -75,15 +75,15 @@ const popStackItem = (undoManager, stack, eventType) => {
|
|||||||
itemsToRedo.add(struct)
|
itemsToRedo.add(struct)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
itemsToRedo.forEach(item => {
|
itemsToRedo.forEach(struct => {
|
||||||
performedChange = redoItem(transaction, item, itemsToRedo) !== null || performedChange
|
performedChange = redoItem(transaction, struct, itemsToRedo) !== null || performedChange
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
* @type {Array<Item>}
|
* @type {Array<Item>}
|
||||||
*/
|
*/
|
||||||
const itemsToDelete = []
|
const itemsToDelete = []
|
||||||
iterateStructs(transaction, structs, stackStartClock, stackItem.len, struct => {
|
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) {
|
if (struct.redone !== null) {
|
||||||
let { item, diff } = followRedone(store, struct.id)
|
let { item, diff } = followRedone(store, struct.id)
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
@ -94,7 +94,9 @@ const popStackItem = (undoManager, stack, eventType) => {
|
|||||||
}
|
}
|
||||||
struct = item
|
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
|
// We want to delete in reverse order so that children are deleted before
|
||||||
|
@ -13,10 +13,23 @@ import * as t from 'lib0/testing.js'
|
|||||||
export const testUndoText = tc => {
|
export const testUndoText = tc => {
|
||||||
const { testConnector, text0, text1 } = init(tc, { users: 3 })
|
const { testConnector, text0, text1 } = init(tc, { users: 3 })
|
||||||
const undoManager = new UndoManager(text0)
|
const undoManager = new UndoManager(text0)
|
||||||
|
|
||||||
|
// items that are added & deleted in the same transaction won't be undo
|
||||||
text0.insert(0, 'test')
|
text0.insert(0, 'test')
|
||||||
text0.delete(0, 4)
|
text0.delete(0, 4)
|
||||||
undoManager.undo()
|
undoManager.undo()
|
||||||
t.assert(text0.toString() === '')
|
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')
|
text0.insert(0, 'abc')
|
||||||
text1.insert(0, 'xyz')
|
text1.insert(0, 'xyz')
|
||||||
testConnector.syncAll()
|
testConnector.syncAll()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user