]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/javascript/tiny_mce/classes/UndoManager.js
Release 6.5.0
[Github/sugarcrm.git] / include / javascript / tiny_mce / classes / UndoManager.js
1 /**
2  * UndoManager.js
3  *
4  * Copyright 2009, Moxiecode Systems AB
5  * Released under LGPL License.
6  *
7  * License: http://tinymce.moxiecode.com/license
8  * Contributing: http://tinymce.moxiecode.com/contributing
9  */
10
11 (function(tinymce) {
12         var Dispatcher = tinymce.util.Dispatcher;
13
14         /**
15          * This class handles the undo/redo history levels for the editor. Since the build in undo/redo has major drawbacks a custom one was needed.
16          *
17          * @class tinymce.UndoManager
18          */
19         tinymce.UndoManager = function(editor) {
20                 var self, index = 0, data = [], beforeBookmark;
21
22                 function getContent() {
23                         return tinymce.trim(editor.getContent({format : 'raw', no_events : 1}));
24                 };
25
26                 return self = {
27                         /**
28                          * State if the user is currently typing or not. This will add a typing operation into one undo
29                          * level instead of one new level for each keystroke.
30                          *
31                          * @field {Boolean} typing
32                          */
33                         typing : false,
34
35                         /**
36                          * This event will fire each time a new undo level is added to the undo manager.
37                          *
38                          * @event onAdd
39                          * @param {tinymce.UndoManager} sender UndoManager instance that got the new level.
40                          * @param {Object} level The new level object containing a bookmark and contents.
41                          */
42                         onAdd : new Dispatcher(self),
43
44                         /**
45                          * This event will fire when the user make an undo of a change.
46                          *
47                          * @event onUndo
48                          * @param {tinymce.UndoManager} sender UndoManager instance that got the new level.
49                          * @param {Object} level The old level object containing a bookmark and contents.
50                          */
51                         onUndo : new Dispatcher(self),
52
53                         /**
54                          * This event will fire when the user make an redo of a change.
55                          *
56                          * @event onRedo
57                          * @param {tinymce.UndoManager} sender UndoManager instance that got the new level.
58                          * @param {Object} level The old level object containing a bookmark and contents.
59                          */
60                         onRedo : new Dispatcher(self),
61
62                         /**
63                          * Stores away a bookmark to be used when performing an undo action so that the selection is before
64                          * the change has been made.
65                          *
66                          * @method beforeChange
67                          */
68                         beforeChange : function() {
69                                 beforeBookmark = editor.selection.getBookmark(2, true);
70                         },
71
72                         /**
73                          * Adds a new undo level/snapshot to the undo list.
74                          *
75                          * @method add
76                          * @param {Object} l Optional undo level object to add.
77                          * @return {Object} Undo level that got added or null it a level wasn't needed.
78                          */
79                         add : function(level) {
80                                 var i, settings = editor.settings, lastLevel;
81
82                                 level = level || {};
83                                 level.content = getContent();
84
85                                 // Add undo level if needed
86                                 lastLevel = data[index];
87                                 if (lastLevel && lastLevel.content == level.content)
88                                         return null;
89
90                                 // Set before bookmark on previous level
91                                 if (data[index])
92                                         data[index].beforeBookmark = beforeBookmark;
93
94                                 // Time to compress
95                                 if (settings.custom_undo_redo_levels) {
96                                         if (data.length > settings.custom_undo_redo_levels) {
97                                                 for (i = 0; i < data.length - 1; i++)
98                                                         data[i] = data[i + 1];
99
100                                                 data.length--;
101                                                 index = data.length;
102                                         }
103                                 }
104
105                                 // Get a non intrusive normalized bookmark
106                                 level.bookmark = editor.selection.getBookmark(2, true);
107
108                                 // Crop array if needed
109                                 if (index < data.length - 1)
110                                         data.length = index + 1;
111
112                                 data.push(level);
113                                 index = data.length - 1;
114
115                                 self.onAdd.dispatch(self, level);
116                                 editor.isNotDirty = 0;
117
118                                 return level;
119                         },
120
121                         /**
122                          * Undoes the last action.
123                          *
124                          * @method undo
125                          * @return {Object} Undo level or null if no undo was performed.
126                          */
127                         undo : function() {
128                                 var level, i;
129
130                                 if (self.typing) {
131                                         self.add();
132                                         self.typing = false;
133                                 }
134
135                                 if (index > 0) {
136                                         level = data[--index];
137
138                                         editor.setContent(level.content, {format : 'raw'});
139                                         editor.selection.moveToBookmark(level.beforeBookmark);
140
141                                         self.onUndo.dispatch(self, level);
142                                 }
143
144                                 return level;
145                         },
146
147                         /**
148                          * Redoes the last action.
149                          *
150                          * @method redo
151                          * @return {Object} Redo level or null if no redo was performed.
152                          */
153                         redo : function() {
154                                 var level;
155
156                                 if (index < data.length - 1) {
157                                         level = data[++index];
158
159                                         editor.setContent(level.content, {format : 'raw'});
160                                         editor.selection.moveToBookmark(level.bookmark);
161
162                                         self.onRedo.dispatch(self, level);
163                                 }
164
165                                 return level;
166                         },
167
168                         /**
169                          * Removes all undo levels.
170                          *
171                          * @method clear
172                          */
173                         clear : function() {
174                                 data = [];
175                                 index = 0;
176                                 self.typing = false;
177                         },
178
179                         /**
180                          * Returns true/false if the undo manager has any undo levels.
181                          *
182                          * @method hasUndo
183                          * @return {Boolean} true/false if the undo manager has any undo levels.
184                          */
185                         hasUndo : function() {
186                                 return index > 0 || this.typing;
187                         },
188
189                         /**
190                          * Returns true/false if the undo manager has any redo levels.
191                          *
192                          * @method hasRedo
193                          * @return {Boolean} true/false if the undo manager has any redo levels.
194                          */
195                         hasRedo : function() {
196                                 return index < data.length - 1 && !this.typing;
197                         }
198                 };
199         };
200 })(tinymce);