import { assertNotUndefined } from '../Common' ; import { EditId } from '../Identifiers' ; import { EditCommittedEventArguments , SharedTreeEvent } from '../generic' ; import { SharedTree } from './SharedTree' ; export interface IRevertible { revert ( ) ; discard ( ) ; } export interface IUndoConsumer { pushToCurrentOperation ( revertible ) ; } /**
 * A shared tree undo redo handler that will add revertible local tree changes to the provided
 * undo redo stack manager
 */ export class SharedTreeUndoRedoHandler { constructor ( private stackManager ) { } public attachTree ( tree ) { tree . on ( SharedTreeEvent . EditCommitted , this . treeDeltaHandler ) ; } public detachTree ( tree ) { tree . off ( SharedTreeEvent . EditCommitted , this . treeDeltaHandler ) ; } private readonly treeDeltaHandler = ( eventArguments ) => { const { editId , local , tree } = eventArguments ; if ( local ) { this . stackManager . pushToCurrentOperation ( new SharedTreeRevertible ( editId , assertNotUndefined ( tree , 'An edit committed event for a revertible edit should include the target SharedTree in its arguments.' ) ) ) ; } } ; } /**
 * Tracks a change on a shared tree and allows reverting it
 */ export class SharedTreeRevertible implements IRevertible { constructor ( private editId , private readonly tree ) { } public revert ( ) { const editIndex = this . tree . edits . getIndexOfId ( this . editId ) ; const edit = this . tree . edits . getEditInSessionAtIndex ( editIndex ) ; const snapshotBefore = this . tree . logViewer . getSnapshotInSession ( editIndex ) ; this . editId = this . tree . editor . revert ( edit , snapshotBefore ) ; } public discard ( ) { return ; } }