123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /*
- Simple Javascript undo and redo.
- https://github.com/ArthurClemens/Javascript-Undo-Manager
- */
- ;(function() {
- 'use strict';
- function removeFromTo(array, from, to) {
- array.splice(from,
- !to ||
- 1 + to - from + (!(to < 0 ^ from >= 0) && (to < 0 || -1) * array.length));
- return array.length;
- }
- var UndoManager = function() {
- var commands = [],
- index = -1,
- limit = 0,
- isExecuting = false,
- callback,
-
- // functions
- execute;
- execute = function(command, action) {
- if (!command || typeof command[action] !== "function") {
- return this;
- }
- isExecuting = true;
- command[action]();
- isExecuting = false;
- return this;
- };
- return {
- /*
- Add a command to the queue.
- */
- add: function (command) {
- if (isExecuting) {
- return this;
- }
- // if we are here after having called undo,
- // invalidate items higher on the stack
- commands.splice(index + 1, commands.length - index);
- commands.push(command);
-
- // if limit is set, remove items from the start
- if (limit && commands.length > limit) {
- removeFromTo(commands, 0, -(limit+1));
- }
-
- // set the current index to the end
- index = commands.length - 1;
- if (callback) {
- callback();
- }
- return this;
- },
- /*
- Pass a function to be called on undo and redo actions.
- */
- setCallback: function (callbackFunc) {
- callback = callbackFunc;
- },
- /*
- Perform undo: call the undo function at the current index and decrease the index by 1.
- */
- undo: function () {
- var command = commands[index];
- if (!command) {
- return this;
- }
- execute(command, "undo");
- index -= 1;
- if (callback) {
- callback();
- }
- return this;
- },
- /*
- Perform redo: call the redo function at the next index and increase the index by 1.
- */
- redo: function () {
- var command = commands[index + 1];
- if (!command) {
- return this;
- }
- execute(command, "redo");
- index += 1;
- if (callback) {
- callback();
- }
- return this;
- },
- /*
- Clears the memory, losing all stored states. Reset the index.
- */
- clear: function () {
- var prev_size = commands.length;
- commands = [];
- index = -1;
- if (callback && (prev_size > 0)) {
- callback();
- }
- },
- hasUndo: function () {
- return index !== -1;
- },
- hasRedo: function () {
- return index < (commands.length - 1);
- },
- getCommands: function () {
- return commands;
- },
- getIndex: function() {
- return index;
- },
-
- setLimit: function (l) {
- limit = l;
- }
- };
- };
- if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
- // AMD. Register as an anonymous module.
- define(function() {
- return UndoManager;
- });
- } else if (typeof module !== 'undefined' && module.exports) {
- module.exports = UndoManager;
- } else {
- window.UndoManager = UndoManager;
- }
- }());
|