scratch – Blame information for rev 84

Subversion Repositories:
Rev:
Rev Author Line No. Line
84 office 1 (function() {
2  
3 'use strict';
4  
5 /**
6 * SimpleUndo is a very basic javascript undo/redo stack for managing histories of basically anything.
7 *
8 * options are: {
9 * * `provider` : required. a function to call on `save`, which should provide the current state of the historized object through the given "done" callback
10 * * `maxLength` : the maximum number of items in history
11 * * `opUpdate` : a function to call to notify of changes in history. Will be called on `save`, `undo`, `redo` and `clear`
12 * }
13 *
14 */
15 var SimpleUndo = function(options) {
16  
17 var settings = options ? options : {};
18 var defaultOptions = {
19 provider: function() {
20 throw new Error("No provider!");
21 },
22 maxLength: 30,
23 onUpdate: function() {}
24 };
25  
26 this.provider = (typeof settings.provider != 'undefined') ? settings.provider : defaultOptions.provider;
27 this.maxLength = (typeof settings.maxLength != 'undefined') ? settings.maxLength : defaultOptions.maxLength;
28 this.onUpdate = (typeof settings.onUpdate != 'undefined') ? settings.onUpdate : defaultOptions.onUpdate;
29  
30 this.initialItem = null;
31 this.clear();
32 };
33  
34 function truncate (stack, limit) {
35 while (stack.length > limit) {
36 stack.shift();
37 }
38 }
39  
40 SimpleUndo.prototype.initialize = function(initialItem) {
41 this.stack[0] = initialItem;
42 this.initialItem = initialItem;
43 };
44  
45  
46 SimpleUndo.prototype.clear = function() {
47 this.stack = [this.initialItem];
48 this.position = 0;
49 this.onUpdate();
50 };
51  
52 SimpleUndo.prototype.save = function() {
53 this.provider(function(current) {
54 truncate(this.stack, this.maxLength);
55 this.position = Math.min(this.position,this.stack.length - 1);
56  
57 this.stack = this.stack.slice(0, this.position + 1);
58 this.stack.push(current);
59 this.position++;
60 this.onUpdate();
61 }.bind(this));
62 };
63  
64 SimpleUndo.prototype.undo = function(callback) {
65 if (this.canUndo()) {
66 var item = this.stack[--this.position];
67 this.onUpdate();
68  
69 if (callback) {
70 callback(item);
71 }
72 }
73 };
74  
75 SimpleUndo.prototype.redo = function(callback) {
76 if (this.canRedo()) {
77 var item = this.stack[++this.position];
78 this.onUpdate();
79  
80 if (callback) {
81 callback(item);
82 }
83 }
84 };
85  
86 SimpleUndo.prototype.canUndo = function() {
87 return this.position > 0;
88 };
89  
90 SimpleUndo.prototype.canRedo = function() {
91 return this.position < this.count();
92 };
93  
94 SimpleUndo.prototype.count = function() {
95 return this.stack.length - 1; // -1 because of initial item
96 };
97  
98  
99  
100  
101  
102 //exports
103 // node module
104 if (typeof module != 'undefined') {
105 module.exports = SimpleUndo;
106 }
107  
108 // browser global
109 if (typeof window != 'undefined') {
110 window.SimpleUndo = SimpleUndo;
111 }
112  
113 })();