| 11 | const MaxUndoSnapshots = 30 |
| 12 | |
| 13 | export class UndoWatcher { |
| 14 | rootNode: SplootNode |
| 15 | selection: NodeSelection |
| 16 | currentSnapshotID: number |
| 17 | latestSnapshotID: number |
| 18 | currentSnapshot: SerializedNode |
| 19 | undoSnapshots: SerializedNode[] |
| 20 | redoSnapshots: SerializedNode[] |
| 21 | loadNewRootNode: (rootNode: SplootNode) => void |
| 22 | enabled: boolean |
| 23 | timeoutID: number |
| 24 | |
| 25 | constructor() { |
| 26 | this.rootNode = null |
| 27 | this.currentSnapshotID = null |
| 28 | this.currentSnapshot = null |
| 29 | this.undoSnapshots = [] |
| 30 | this.redoSnapshots = [] |
| 31 | this.enabled = true |
| 32 | this.timeoutID = null |
| 33 | } |
| 34 | |
| 35 | undo() { |
| 36 | // No undo snapshots to use. |
| 37 | if (this.undoSnapshots.length == 0) { |
| 38 | return |
| 39 | } |
| 40 | // Remove current snapshot |
| 41 | const newSnapshot = this.undoSnapshots.shift() |
| 42 | // Put current snapshot on the redo stack |
| 43 | this.redoSnapshots.unshift(this.currentSnapshot) |
| 44 | this.currentSnapshot = newSnapshot |
| 45 | |
| 46 | // Disable undo shapshotting (but not other mutation firing) and recursively apply the snapshot as edits. |
| 47 | this.enabled = false |
| 48 | this.rootNode.applySerializedSnapshot(this.currentSnapshot) |
| 49 | this.enabled = true |
| 50 | } |
| 51 | |
| 52 | redo() { |
| 53 | // No redo snapshots to use. |
| 54 | if (this.redoSnapshots.length == 0) { |
| 55 | return |
| 56 | } |
| 57 | // Remove current snapshot |
| 58 | const newSnapshot = this.redoSnapshots.shift() |
| 59 | // Put current snapshot on the undo stack |
| 60 | this.undoSnapshots.unshift(this.currentSnapshot) |
| 61 | this.currentSnapshot = newSnapshot |
| 62 | |
| 63 | // Disable undo shapshotting (but not other mutation firing) and recursively apply the snapshot as edits. |
| 64 | this.enabled = false |
| 65 | this.rootNode.applySerializedSnapshot(this.currentSnapshot) |
| 66 | this.enabled = true |
| 67 | } |
| 68 | |
| 69 | setRootNode(rootNode: SplootNode) { |
| 70 | this.rootNode = rootNode |