Add UndoManager.prototype.transact

The `transact` method takes a function and batches all operations within that function as a single transaction to be undone and redone. The edit session now uses generic operations to restore selection state around transactions. The `undo` and `do` methods on operations are now optional. In addition, the undo manager now supports an optional `redo` method on an operation for code that should *only* be run on redo, and not when the operation is initially pushed. This is used by edit session to restore selection state after redo.
This commit is contained in:
Nathan Sobo
2012-07-05 20:04:16 -06:00
parent c053be3394
commit 42eefb49a9
4 changed files with 49 additions and 61 deletions

View File

@@ -63,49 +63,37 @@ describe "UndoManager", ->
undoManager.redo()
expect(buffer.getText()).toContain 'qsport'
describe "startUndoBatch() / endUndoBatch()", ->
it "causes changes in batch to be undone simultaneously and returns an array of ranges to select from undo and redo", ->
describe "transact(fn)", ->
it "causes changes in the transaction to be undone simultaneously", ->
buffer.insert([0, 0], "foo")
ignoredRanges = [[[666, 666], [666, 666]], [[666, 666], [666, 666]]]
beforeRanges = [[[1, 2], [1, 2]], [[1, 9], [1, 9]]]
afterRanges =[[[1, 5], [1, 5]], [[1, 12], [1, 12]]]
undoManager.startUndoBatch(beforeRanges)
undoManager.startUndoBatch(ignoredRanges) # calls can be nested
buffer.insert([1, 2], "111")
buffer.insert([1, 9], "222")
undoManager.endUndoBatch(ignoredRanges) # calls can be nested
undoManager.endUndoBatch(afterRanges)
undoManager.transact ->
undoManager.transact ->
buffer.insert([1, 2], "111")
buffer.insert([1, 9], "222")
expect(buffer.lineForRow(1)).toBe ' 111var 222sort = function(items) {'
ranges = undoManager.undo()
expect(ranges).toBe beforeRanges
undoManager.undo()
expect(buffer.lineForRow(1)).toBe ' var sort = function(items) {'
expect(buffer.lineForRow(0)).toContain 'foo'
ranges = undoManager.undo()
expect(ranges).toBeUndefined()
undoManager.undo()
expect(buffer.lineForRow(0)).not.toContain 'foo'
ranges = undoManager.redo()
expect(ranges).toBeUndefined()
undoManager.redo()
expect(buffer.lineForRow(0)).toContain 'foo'
ranges = undoManager.redo()
expect(ranges).toBe afterRanges
undoManager.redo()
expect(buffer.lineForRow(1)).toBe ' 111var 222sort = function(items) {'
ranges = undoManager.undo()
expect(ranges).toBe beforeRanges
undoManager.undo()
expect(buffer.lineForRow(1)).toBe ' var sort = function(items) {'
it "does not store empty batches", ->
it "does not record empty transactions", ->
buffer.insert([0,0], "foo")
undoManager.startUndoBatch()
undoManager.endUndoBatch()
undoManager.transact ->
undoManager.undo()
expect(buffer.lineForRow(0)).not.toContain("foo")