export class Action { redo ( ) { } undo ( ) { } } export class UndoStack { static current : UndoStack ; stack : Action [ ] ; pointer : number ; savedState : number = - 1 ; cleanStatusChanged : ( isClean : boolean ) => void = null ; constructor ( ) { this . pointer = - 1 ; this . stack = [ ] ; } push ( action ) { let isClean = this . isClean ( ) ; this . pointer += 1 ; this . stack . splice ( this . pointer ) ; this . stack . push ( action ) ; if ( isClean != this . isClean ( ) && this . cleanStatusChanged ) { this . cleanStatusChanged ( this . isClean ( ) ) ; } } undo ( ) { if ( this . pointer < 0 ) return ; let isClean = this . isClean ( ) ; const action = this . stack [ this . pointer ] ; action . undo ( ) ; this . pointer -= 1 ; if ( isClean != this . isClean ( ) && this . cleanStatusChanged ) { this . cleanStatusChanged ( this . isClean ( ) ) ; } } redo ( ) { if ( this . pointer >= this . stack . length - 1 ) return ; let isClean = this . isClean ( ) ; this . pointer += 1 ; const action = this . stack [ this . pointer ] ; action . redo ( ) ; if ( isClean != this . isClean ( ) && this . cleanStatusChanged ) { this . cleanStatusChanged ( this . isClean ( ) ) ; } } clear ( ) { let isClean = this . isClean ( ) ; this . pointer = - 1 ; this . savedState = - 1 ; this . stack = [ ] ; if ( ! isClean ) { this . cleanStatusChanged ( true ) ; } } setClean ( ) { this . savedState = this . pointer ; this . cleanStatusChanged ( true ) ; } isClean ( ) { return this . savedState == this . pointer ; } }