Mercurial > hg > dml-open-vis
comparison src/DML/MainVisBundle/Resources/assets/marionette/modules/ContextModule/ContextModule.30-StateHistory.js @ 0:493bcb69166c
added public content
author | Daniel Wolff |
---|---|
date | Tue, 09 Feb 2016 20:54:02 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:493bcb69166c |
---|---|
1 "use strict"; | |
2 | |
3 App.module("ContextModule", function(ContextModule, App, Backbone, Marionette, $, _, Logger) { | |
4 | |
5 // Define private variables | |
6 var logger = null; | |
7 | |
8 ContextModule.addInitializer(function(options){ | |
9 | |
10 // logger = Logger.get("ContextModule.StateBookmark"); | |
11 // logger.setLevel(Logger.DEBUG); | |
12 | |
13 /** | |
14 * StateHistory stores a history of a serialized state | |
15 * and provides an API to switch between these states | |
16 * | |
17 * A user simply updates the value of currentSerializedState attribute | |
18 * and calls undo(), redo() or reset() to move along the history | |
19 * There is no direct access to undo and redo stacks, but it is possible | |
20 * to know about them by calling canUndo() and canRedo() | |
21 * | |
22 * serialize / unserialize deal with the object of the following structure | |
23 * { | |
24 * undoStack: [{recent}, {less recent}, ... {the oldest}] | |
25 * redoStack: [{next}, {the following}, ... {the last}] | |
26 * currentSerializedState: {} | |
27 * } | |
28 * | |
29 * attribute compoundChangeDetector is a function that helps decide if the changes between | |
30 * the given three serialized states can be treated as a single change. | |
31 * This is needed to avoid too many undo states on simple actions like text typing | |
32 * compoundChangeDetector returns true if the change between the first, the second | |
33 * and the third object can be considered as a single compound change | |
34 * (i.e. there is no need to create an extra undo action) | |
35 */ | |
36 ContextModule.StateHistory = Backbone.Model.extend({ | |
37 defaults: { | |
38 maxStackSize: 50, | |
39 currentSerializedState: undefined, | |
40 compoundChangeDetector: undefined | |
41 }, | |
42 | |
43 _NONE: 0, | |
44 _UNDO: 1, | |
45 _REDO: 2, | |
46 _UNSERIALIZE: 3, | |
47 | |
48 /** | |
49 * @memberOf App.ContextModule.StateBookmark | |
50 */ | |
51 initialize: function() { | |
52 this._undoStack = []; | |
53 this._redoStack = []; | |
54 this._currentSerializedStateChangeMode = this._NONE; | |
55 | |
56 this.on("change:maxStackSize", this._trimStacks, this); | |
57 this.on("change:currentSerializedState", this._registerNewSerializedState, this); | |
58 }, | |
59 | |
60 _registerNewSerializedState: function() { | |
61 var previousSerialisedState = this.previous("currentSerializedState"); | |
62 if (this._currentSerializedStateChangeMode == this._UNDO) { | |
63 this._redoStack.unshift(previousSerialisedState); | |
64 } else if (this._currentSerializedStateChangeMode == this._REDO) { | |
65 this._undoStack.unshift(previousSerialisedState); | |
66 } else if (this._currentSerializedStateChangeMode == this._UNSERIALIZE) { | |
67 } else { | |
68 if (!_.isEqual(previousSerialisedState, this.attributes.currentSerializedState)) { | |
69 if (this._undoStack.length == 0 | |
70 || !_.isFunction(this.attributes.compoundChangeDetector) | |
71 || !this.attributes.compoundChangeDetector.call(currentSerializedState, previousSerialisedState, this._undoStack[0])) | |
72 { | |
73 this._undoStack.unshift(previousSerialisedState); | |
74 } | |
75 this._redoStack = []; | |
76 } | |
77 } | |
78 this._trimStacks(); | |
79 }, | |
80 | |
81 getCurrentSerializedState: function() { | |
82 | |
83 }, | |
84 | |
85 undo: function() { | |
86 if (this._undoStack.length) { | |
87 this._currentSerializedStateChangeMode = this._UNDO; | |
88 this.set("currentSerializedState", this._undoStack.shift()); | |
89 this._currentSerializedStateChangeMode = this._NONE; | |
90 } else { | |
91 throw "Undo was called when undo stack was empty"; | |
92 } | |
93 }, | |
94 | |
95 redo: function() { | |
96 if (this._redoStack.length) { | |
97 this._currentSerializedStateChangeMode = this._REDO; | |
98 this.set("currentSerializedState", this._redoStack.shift()); | |
99 this._currentSerializedStateChangeMode = this._NONE; | |
100 } else { | |
101 throw "Redo was called when undo stack was empty"; | |
102 } | |
103 }, | |
104 | |
105 reset: function() { | |
106 var stacksWereNotEmpty = this._undoStack.length || this._redoStack.length; | |
107 this._undoStack = []; | |
108 this._redoStack = []; | |
109 if (stacksWereNotEmpty) { | |
110 this.trigger("change"); | |
111 } | |
112 }, | |
113 | |
114 canUndo: function() { | |
115 return !!this._undoStack.length; | |
116 }, | |
117 | |
118 canRedo: function() { | |
119 return !!this._redoStack.length; | |
120 }, | |
121 | |
122 serialize: function() { | |
123 // logger.debug("method called: StateHistory::serialize"); | |
124 | |
125 var result = { | |
126 currentSerializedState: this.attributes.currentSerializedState, | |
127 undoStack: _.clone(this._undoStack), | |
128 redoStack: _.clone(this._redoStack), | |
129 }; | |
130 | |
131 return result; | |
132 }, | |
133 | |
134 unserialize: function(serializedAttributes) { | |
135 this._currentSerializedStateChangeMode = this._UNSERIALIZE; | |
136 | |
137 var fixedSerializedAttributes = serializedAttributes; | |
138 if (!_.isSimpleObject(serializedAttributes)) { | |
139 fixedSerializedAttributes = {}; | |
140 } | |
141 | |
142 this._undoStack = _.isArray(fixedSerializedAttributes.undoStack) ? | |
143 fixedSerializedAttributes.undoStack : []; | |
144 this._redoStack = _.isArray(fixedSerializedAttributes.redoStack) ? | |
145 fixedSerializedAttributes.redoStack : []; | |
146 this._trimStacks(); | |
147 | |
148 this.set("currentSerializedState", fixedSerializedAttributes.currentSerializedState); | |
149 | |
150 this._currentSerializedStateChangeMode = this._NONE; | |
151 }, | |
152 | |
153 _trimStacks: function() { | |
154 if (this._undoStack.length > this.attributes.maxStackSize) { | |
155 this._undoStack = this._undoStack.slice(0, this.attributes.maxStackSize); | |
156 } | |
157 if (this._redoStack.length > this.attributes.maxStackSize) { | |
158 this._redoStack = this._redoStack.slice(0, this.attributes.maxStackSize); | |
159 } | |
160 } | |
161 }); | |
162 | |
163 }); | |
164 }, Logger); |