]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/javascript/tiny_mce/classes/UndoManager.js
Release 6.2.2
[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 = [];
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                                 // Set before bookmark on previous level
70                                 if (data[index])
71                                         data[index].beforeBookmark = editor.selection.getBookmark(2, true);
72                         },
73
74                         /**
75                          * Adds a new undo level/snapshot to the undo list.
76                          *
77                          * @method add
78                          * @param {Object} l Optional undo level object to add.
79                          * @return {Object} Undo level that got added or null it a level wasn't needed.
80                          */
81                         add : function(level) {
82                                 var i, settings = editor.settings, lastLevel;
83
84                                 level = level || {};
85                                 level.content = getContent();
86
87                                 // Add undo level if needed
88                                 lastLevel = data[index];
89                                 if (lastLevel && lastLevel.content == level.content)
90                                         return null;
91
92                                 // Time to compress
93                                 if (settings.custom_undo_redo_levels) {
94                                         if (data.length > settings.custom_undo_redo_levels) {
95                                                 for (i = 0; i < data.length - 1; i++)
96                                                         data[i] = data[i + 1];
97
98                                                 data.length--;
99                                                 index = data.length;
100                                         }
101                                 }
102
103                                 // Get a non intrusive normalized bookmark
104                                 level.bookmark = editor.selection.getBookmark(2, true);
105
106                                 // Crop array if needed
107                                 if (index < data.length - 1)
108                                         data.length = index + 1;
109
110                                 data.push(level);
111                                 index = data.length - 1;
112
113                                 self.onAdd.dispatch(self, level);
114                                 editor.isNotDirty = 0;
115
116                                 return level;
117                         },
118
119                         /**
120                          * Undoes the last action.
121                          *
122                          * @method undo
123                          * @return {Object} Undo level or null if no undo was performed.
124                          */
125                         undo : function() {
126                                 var level, i;
127
128                                 if (self.typing) {
129                                         self.add();
130                                         self.typing = false;
131                                 }
132
133                                 if (index > 0) {
134                                         level = data[--index];
135
136                                         editor.setContent(level.content, {format : 'raw'});
137                                         editor.selection.moveToBookmark(level.beforeBookmark);
138
139                                         self.onUndo.dispatch(self, level);
140                                 }
141
142                                 return level;
143                         },
144
145                         /**
146                          * Redoes the last action.
147                          *
148                          * @method redo
149                          * @return {Object} Redo level or null if no redo was performed.
150                          */
151                         redo : function() {
152                                 var level;
153
154                                 if (index < data.length - 1) {
155                                         level = data[++index];
156
157                                         editor.setContent(level.content, {format : 'raw'});
158                                         editor.selection.moveToBookmark(level.bookmark);
159
160                                         self.onRedo.dispatch(self, level);
161                                 }
162
163                                 return level;
164                         },
165
166                         /**
167                          * Removes all undo levels.
168                          *
169                          * @method clear
170                          */
171                         clear : function() {
172                                 data = [];
173                                 index = 0;
174                                 self.typing = false;
175                         },
176
177                         /**
178                          * Returns true/false if the undo manager has any undo levels.
179                          *
180                          * @method hasUndo
181                          * @return {Boolean} true/false if the undo manager has any undo levels.
182                          */
183                         hasUndo : function() {
184                                 return index > 0 || this.typing;
185                         },
186
187                         /**
188                          * Returns true/false if the undo manager has any redo levels.
189                          *
190                          * @method hasRedo
191                          * @return {Boolean} true/false if the undo manager has any redo levels.
192                          */
193                         hasRedo : function() {
194                                 return index < data.length - 1 && !this.typing;
195                         }
196                 };
197         };
198 })(tinymce);