Mercurial > hg > extraction-interface
comparison geotemco/lib/simile/ajax/scripts/history.js @ 0:b12c99b7c3f0
commit for previous development
author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
---|---|
date | Mon, 19 Jan 2015 17:13:49 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b12c99b7c3f0 |
---|---|
1 /*====================================================================== | |
2 * History | |
3 * | |
4 * This is a singleton that keeps track of undoable user actions and | |
5 * performs undos and redos in response to the browser's Back and | |
6 * Forward buttons. | |
7 * | |
8 * Call addAction(action) to register an undoable user action. action | |
9 * must have 4 fields: | |
10 * | |
11 * perform: an argument-less function that carries out the action | |
12 * undo: an argument-less function that undos the action | |
13 * label: a short, user-friendly string describing the action | |
14 * uiLayer: the UI layer on which the action takes place | |
15 * | |
16 * By default, the history keeps track of upto 10 actions. You can | |
17 * configure this behavior by setting | |
18 * SimileAjax.History.maxHistoryLength | |
19 * to a different number. | |
20 * | |
21 * An iframe is inserted into the document's body element to track | |
22 * onload events. | |
23 *====================================================================== | |
24 */ | |
25 | |
26 SimileAjax.History = { | |
27 maxHistoryLength: 10, | |
28 historyFile: "__history__.html", | |
29 enabled: true, | |
30 | |
31 _initialized: false, | |
32 _listeners: new SimileAjax.ListenerQueue(), | |
33 | |
34 _actions: [], | |
35 _baseIndex: 0, | |
36 _currentIndex: 0, | |
37 | |
38 _plainDocumentTitle: document.title | |
39 }; | |
40 | |
41 SimileAjax.History.formatHistoryEntryTitle = function(actionLabel) { | |
42 return SimileAjax.History._plainDocumentTitle + " {" + actionLabel + "}"; | |
43 }; | |
44 | |
45 SimileAjax.History.initialize = function() { | |
46 if (SimileAjax.History._initialized) { | |
47 return; | |
48 } | |
49 | |
50 if (SimileAjax.History.enabled) { | |
51 var iframe = document.createElement("iframe"); | |
52 iframe.id = "simile-ajax-history"; | |
53 iframe.style.position = "absolute"; | |
54 iframe.style.width = "10px"; | |
55 iframe.style.height = "10px"; | |
56 iframe.style.top = "0px"; | |
57 iframe.style.left = "0px"; | |
58 iframe.style.visibility = "hidden"; | |
59 iframe.src = SimileAjax.History.historyFile + "?0"; | |
60 | |
61 document.body.appendChild(iframe); | |
62 SimileAjax.DOM.registerEvent(iframe, "load", SimileAjax.History._handleIFrameOnLoad); | |
63 | |
64 SimileAjax.History._iframe = iframe; | |
65 } | |
66 SimileAjax.History._initialized = true; | |
67 }; | |
68 | |
69 SimileAjax.History.addListener = function(listener) { | |
70 SimileAjax.History.initialize(); | |
71 | |
72 SimileAjax.History._listeners.add(listener); | |
73 }; | |
74 | |
75 SimileAjax.History.removeListener = function(listener) { | |
76 SimileAjax.History.initialize(); | |
77 | |
78 SimileAjax.History._listeners.remove(listener); | |
79 }; | |
80 | |
81 SimileAjax.History.addAction = function(action) { | |
82 SimileAjax.History.initialize(); | |
83 | |
84 SimileAjax.History._listeners.fire("onBeforePerform", [ action ]); | |
85 window.setTimeout(function() { | |
86 try { | |
87 action.perform(); | |
88 SimileAjax.History._listeners.fire("onAfterPerform", [ action ]); | |
89 | |
90 if (SimileAjax.History.enabled) { | |
91 SimileAjax.History._actions = SimileAjax.History._actions.slice( | |
92 0, SimileAjax.History._currentIndex - SimileAjax.History._baseIndex); | |
93 | |
94 SimileAjax.History._actions.push(action); | |
95 SimileAjax.History._currentIndex++; | |
96 | |
97 var diff = SimileAjax.History._actions.length - SimileAjax.History.maxHistoryLength; | |
98 if (diff > 0) { | |
99 SimileAjax.History._actions = SimileAjax.History._actions.slice(diff); | |
100 SimileAjax.History._baseIndex += diff; | |
101 } | |
102 | |
103 try { | |
104 SimileAjax.History._iframe.contentWindow.location.search = | |
105 "?" + SimileAjax.History._currentIndex; | |
106 } catch (e) { | |
107 /* | |
108 * We can't modify location.search most probably because it's a file:// url. | |
109 * We'll just going to modify the document's title. | |
110 */ | |
111 var title = SimileAjax.History.formatHistoryEntryTitle(action.label); | |
112 document.title = title; | |
113 } | |
114 } | |
115 } catch (e) { | |
116 SimileAjax.Debug.exception(e, "Error adding action {" + action.label + "} to history"); | |
117 } | |
118 }, 0); | |
119 }; | |
120 | |
121 SimileAjax.History.addLengthyAction = function(perform, undo, label) { | |
122 SimileAjax.History.addAction({ | |
123 perform: perform, | |
124 undo: undo, | |
125 label: label, | |
126 uiLayer: SimileAjax.WindowManager.getBaseLayer(), | |
127 lengthy: true | |
128 }); | |
129 }; | |
130 | |
131 SimileAjax.History._handleIFrameOnLoad = function() { | |
132 /* | |
133 * This function is invoked when the user herself | |
134 * navigates backward or forward. We need to adjust | |
135 * the application's state accordingly. | |
136 */ | |
137 | |
138 try { | |
139 var q = SimileAjax.History._iframe.contentWindow.location.search; | |
140 var c = (q.length == 0) ? 0 : Math.max(0, parseInt(q.substr(1))); | |
141 | |
142 var finishUp = function() { | |
143 var diff = c - SimileAjax.History._currentIndex; | |
144 SimileAjax.History._currentIndex += diff; | |
145 SimileAjax.History._baseIndex += diff; | |
146 | |
147 SimileAjax.History._iframe.contentWindow.location.search = "?" + c; | |
148 }; | |
149 | |
150 if (c < SimileAjax.History._currentIndex) { // need to undo | |
151 SimileAjax.History._listeners.fire("onBeforeUndoSeveral", []); | |
152 window.setTimeout(function() { | |
153 while (SimileAjax.History._currentIndex > c && | |
154 SimileAjax.History._currentIndex > SimileAjax.History._baseIndex) { | |
155 | |
156 SimileAjax.History._currentIndex--; | |
157 | |
158 var action = SimileAjax.History._actions[SimileAjax.History._currentIndex - SimileAjax.History._baseIndex]; | |
159 | |
160 try { | |
161 action.undo(); | |
162 } catch (e) { | |
163 SimileAjax.Debug.exception(e, "History: Failed to undo action {" + action.label + "}"); | |
164 } | |
165 } | |
166 | |
167 SimileAjax.History._listeners.fire("onAfterUndoSeveral", []); | |
168 finishUp(); | |
169 }, 0); | |
170 } else if (c > SimileAjax.History._currentIndex) { // need to redo | |
171 SimileAjax.History._listeners.fire("onBeforeRedoSeveral", []); | |
172 window.setTimeout(function() { | |
173 while (SimileAjax.History._currentIndex < c && | |
174 SimileAjax.History._currentIndex - SimileAjax.History._baseIndex < SimileAjax.History._actions.length) { | |
175 | |
176 var action = SimileAjax.History._actions[SimileAjax.History._currentIndex - SimileAjax.History._baseIndex]; | |
177 | |
178 try { | |
179 action.perform(); | |
180 } catch (e) { | |
181 SimileAjax.Debug.exception(e, "History: Failed to redo action {" + action.label + "}"); | |
182 } | |
183 | |
184 SimileAjax.History._currentIndex++; | |
185 } | |
186 | |
187 SimileAjax.History._listeners.fire("onAfterRedoSeveral", []); | |
188 finishUp(); | |
189 }, 0); | |
190 } else { | |
191 var index = SimileAjax.History._currentIndex - SimileAjax.History._baseIndex - 1; | |
192 var title = (index >= 0 && index < SimileAjax.History._actions.length) ? | |
193 SimileAjax.History.formatHistoryEntryTitle(SimileAjax.History._actions[index].label) : | |
194 SimileAjax.History._plainDocumentTitle; | |
195 | |
196 SimileAjax.History._iframe.contentWindow.document.title = title; | |
197 document.title = title; | |
198 } | |
199 } catch (e) { | |
200 // silent | |
201 } | |
202 }; | |
203 | |
204 SimileAjax.History.getNextUndoAction = function() { | |
205 try { | |
206 var index = SimileAjax.History._currentIndex - SimileAjax.History._baseIndex - 1; | |
207 return SimileAjax.History._actions[index]; | |
208 } catch (e) { | |
209 return null; | |
210 } | |
211 }; | |
212 | |
213 SimileAjax.History.getNextRedoAction = function() { | |
214 try { | |
215 var index = SimileAjax.History._currentIndex - SimileAjax.History._baseIndex; | |
216 return SimileAjax.History._actions[index]; | |
217 } catch (e) { | |
218 return null; | |
219 } | |
220 }; |