Created
October 20, 2016 08:14
-
-
Save ducksoupdev/1e13d40debea2d19d9ff6f20678a630c to your computer and use it in GitHub Desktop.
Angular_1_undo_manager_service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| namespace MyModule { | |
| export interface IUndoCommand { | |
| undo: Function; | |
| redo: Function; | |
| } | |
| export interface IUndoManagerService { | |
| add(command: IUndoCommand): IUndoManagerService; | |
| setCallback(callback: Function); | |
| undo(): IUndoManagerService; | |
| redo(): IUndoManagerService; | |
| clear(); | |
| hasUndo(): boolean; | |
| hasRedo(): boolean; | |
| getCommands(): IUndoCommand[]; | |
| getIndex(): number; | |
| setLimit(limit: number); | |
| } | |
| export class UndoManagerService implements IUndoManagerService { | |
| private commands: IUndoCommand[]; | |
| private index = -1; | |
| private limit = 0; | |
| private isExecuting = false; | |
| private callback: Function; | |
| constructor() { | |
| this.commands = []; | |
| } | |
| private execute(command: IUndoCommand, action: string) { | |
| if (!command || typeof command[action] !== "function") { | |
| return this; | |
| } | |
| this.isExecuting = true; | |
| // call the command | |
| command[action](); | |
| this.isExecuting = false; | |
| return this; | |
| } | |
| private removeFromTo(array: any[], from: number, to: number): number { | |
| array.splice(from, | |
| !to || | |
| 1 + to - from + (!(to < 0 ^ from >= 0) && (to < 0 || -1) * array.length)); | |
| return array.length; | |
| } | |
| add(command: IUndoCommand) { | |
| if (this.isExecuting) { | |
| return this; | |
| } | |
| // if we are here after having called undo, | |
| // invalidate items higher on the stack | |
| this.commands.splice(this.index + 1, this.commands.length - this.index); | |
| this.commands.push(command); | |
| // if limit is set, remove items from the start | |
| if (this.limit && this.commands.length > this.limit) { | |
| this.removeFromTo(this.commands, 0, -(this.limit + 1)); | |
| } | |
| // set the current index to the end | |
| this.index = this.commands.length - 1; | |
| if (this.callback) { | |
| this.callback(); | |
| } | |
| return this; | |
| } | |
| setCallback(callback: Function) { | |
| this.callback = callback; | |
| } | |
| undo() { | |
| var command = this.commands[this.index]; | |
| if (!command) { | |
| return this; | |
| } | |
| this.execute(command, "undo"); | |
| this.index -= 1; | |
| if (this.callback) { | |
| this.callback(); | |
| } | |
| return this; | |
| } | |
| redo() { | |
| var command = this.commands[this.index + 1]; | |
| if (!command) { | |
| return this; | |
| } | |
| this.execute(command, "redo"); | |
| this.index += 1; | |
| if (this.callback) { | |
| this.callback(); | |
| } | |
| return this; | |
| } | |
| clear() { | |
| let prev_size = this.commands.length; | |
| this.commands = []; | |
| this.index = -1; | |
| if (this.callback && (prev_size > 0)) { | |
| this.callback(); | |
| } | |
| } | |
| hasUndo() { | |
| return this.index !== -1; | |
| } | |
| hasRedo() { | |
| return this.index < (this.commands.length - 1); | |
| } | |
| getCommands() { | |
| return this.commands; | |
| } | |
| getIndex() { | |
| return this.index; | |
| } | |
| setLimit(limit: number) { | |
| this.limit = limit; | |
| } | |
| } | |
| angular | |
| .module('myModule') | |
| .service('undoManagerService', UndoManagerService); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment