|
1 (function($) { |
|
2 |
|
3 window.PyAMS_zodbbrowser = { |
|
4 |
|
5 filterAll: function () { |
|
6 $('.filter').attr('checked', true); |
|
7 PyAMS_zodbbrowser.filterHistory(true); |
|
8 }, |
|
9 |
|
10 filterNone: function () { |
|
11 $('.filter').attr('checked', false); |
|
12 PyAMS_zodbbrowser.filterHistory(); |
|
13 }, |
|
14 |
|
15 filterHistory: function (showAll) { |
|
16 var transactions = $('div.transaction'); |
|
17 var filters = $('.filter'); |
|
18 var filterMap = Array(); |
|
19 var MAPPING_PREFIX = "map"; |
|
20 |
|
21 for (var i = 0; i < filters.length; i++) { |
|
22 var filter = filters[i]; |
|
23 if (filter.checked) { |
|
24 filterMap[MAPPING_PREFIX + filter.name] = filter.checked; |
|
25 } |
|
26 } |
|
27 |
|
28 for (i = 0; i < transactions.length; i++) { |
|
29 var transaction = transactions[i]; |
|
30 var diffs = $(transaction).children('div.diff').children('div.diffitem'); |
|
31 var n_hidden = 0; |
|
32 for (var j = 0; j < diffs.length; j++) { |
|
33 var id = $($(diffs[j]).children()[0]).text(); |
|
34 if (MAPPING_PREFIX + id in filterMap || showAll) { |
|
35 $(diffs[j]).show(); |
|
36 } else { |
|
37 $(diffs[j]).hide(); |
|
38 n_hidden += 1; |
|
39 } |
|
40 } |
|
41 var hidden_text = null; |
|
42 if (n_hidden == 1) { |
|
43 hidden_text = '1 item hidden'; |
|
44 } else if (n_hidden) { |
|
45 hidden_text = n_hidden + ' items hidden'; |
|
46 } |
|
47 $(transaction).children('.filtered').remove(); |
|
48 if (hidden_text) { |
|
49 $(transaction).append('<div class="filtered">' + hidden_text + '</div>'); |
|
50 } |
|
51 } |
|
52 }, |
|
53 |
|
54 collapseOrExpand: function () { |
|
55 // this is <div class="extender"> |
|
56 // the following element is <div class="collapsible"> |
|
57 var content = $(this).next(); |
|
58 var icon = $(this).children('img'); |
|
59 if (content.is(':hidden')) { |
|
60 $(icon).attr('src', $('#collapseImg').attr('src')); |
|
61 content.slideDown(); |
|
62 } else { |
|
63 $(icon).attr('src', $('#expandImg').attr('src')); |
|
64 content.slideUp(); |
|
65 } |
|
66 }, |
|
67 |
|
68 hideItemsIfTooMany: function () { |
|
69 $('.items').each(function () { |
|
70 var expander = $(this).children('.expander')[0]; |
|
71 var content = $(this).children('.collapsible')[0]; |
|
72 // items are formatted using <br /> so the heuristic is very |
|
73 // approximate. |
|
74 if (content.childNodes.length > 100 && !$(content).is(':hidden')) { |
|
75 var icon = $(expander).children('img'); |
|
76 $(icon).attr('src', $('#expandImg').attr('src')); |
|
77 $(content).hide(); |
|
78 } |
|
79 }); |
|
80 }, |
|
81 |
|
82 showGoTo: function () { |
|
83 $('#path').hide(); |
|
84 $('#goto').show(); |
|
85 $('#gotoInput').focus(); |
|
86 }, |
|
87 |
|
88 hideGoTo: function () { |
|
89 $('#goto').hide(); |
|
90 $('#path').show(); |
|
91 // Don't hide #pathError right away, this blur event might have been the |
|
92 // result of the user clicking on a link inside the #pathError text and |
|
93 // hiding it will prevent that link from getting activated. |
|
94 setTimeout(function () { |
|
95 $('#pathError').slideUp(); |
|
96 }, 50); |
|
97 }, |
|
98 |
|
99 ajaxErrorHandler: function (XMLHttpRequest, textStatus, errorThrown) { |
|
100 errorMessage = ""; |
|
101 if (textStatus == "parsererror") { |
|
102 errorMessage = "Server returned malformed data"; |
|
103 } else if (textStatus == "error") { |
|
104 errorMessage = "Unknown error (maybe server is offline?)"; |
|
105 } else if (textStatus == "timeout") { |
|
106 errorMessage = "Server timeout"; |
|
107 } else if (textStatus == "notmodified") { |
|
108 errorMessage = "Server error (says resource not modified)"; |
|
109 } else { |
|
110 errorMessage = "Unknown error"; |
|
111 } |
|
112 |
|
113 errorMessage = '<span class="error"> ' + errorMessage + '</strong>'; |
|
114 $('#pathError').html(errorMessage); |
|
115 }, |
|
116 |
|
117 ajaxSuccessHandler: function (data, status) { |
|
118 if (data.url) { |
|
119 window.location = data.url; |
|
120 $('#pathError').text("Found.").slideDown().slideUp(); |
|
121 } else if (data.error) { |
|
122 $('#pathError').text(data.error).show(); |
|
123 if (data.partial_url) { |
|
124 $('#pathError').append(', would you like to ' + |
|
125 '<a href="' + data.partial_url + '">' + |
|
126 'go to ' + data.partial_path + |
|
127 '</a>' + |
|
128 ' instead?'); |
|
129 } |
|
130 } else { |
|
131 $('#pathError').text(status).show(); |
|
132 } |
|
133 }, |
|
134 |
|
135 activateGoTo: function () { |
|
136 var path = $('#gotoInput').val(); |
|
137 var api_url = 'zodbbrowser_path_to_oid'; |
|
138 $('#pathError').text("Loading...").slideDown(); |
|
139 $.ajax({ |
|
140 url: api_url, |
|
141 dataType: 'json', |
|
142 data: "path=" + path, |
|
143 timeout: 7000, |
|
144 success: PyAMS_zodbbrowser.ajaxSuccessHandler, |
|
145 error: PyAMS_zodbbrowser.ajaxErrorHandler |
|
146 }); |
|
147 }, |
|
148 |
|
149 cancelRollback: function (e) { |
|
150 $('#confirmation').remove(); |
|
151 $('div.transaction').removeClass('focus'); |
|
152 $('input.rollbackbtn').show(); |
|
153 }, |
|
154 |
|
155 pressRollback: function (e) { |
|
156 e.preventDefault(); |
|
157 PyAMS_zodbbrowser.cancelRollback(); |
|
158 $(e.target).hide(); |
|
159 var transaction_div = $(e.target).closest('div.transaction'); |
|
160 transaction_div.addClass('focus'); |
|
161 $('<div id="confirmation">' + |
|
162 '<form action="" method="post">' + |
|
163 '<div class="message">' + |
|
164 'This is a dangerous operation that may break data integrity.' + |
|
165 ' Are you really sure you want to do this?' + |
|
166 '</div>' + |
|
167 '<input type="BUTTON" value="Really revert to this state" onclick="PyAMS_zodbbrowser.doRollback()">' + |
|
168 '<input type="BUTTON" value="Cancel" onclick="PyAMS_zodbbrowser.cancelRollback()">' + |
|
169 '</form>' + |
|
170 '</div>').appendTo(transaction_div); |
|
171 }, |
|
172 |
|
173 doRollback: function () { |
|
174 var transaction_div = $('#confirmation').closest('div.transaction'); |
|
175 var rollback_form = transaction_div.find('form.rollback'); |
|
176 rollback_form.find('input[name="confirmed"]').val('1'); |
|
177 rollback_form.submit(); |
|
178 }, |
|
179 |
|
180 init: function(element) { |
|
181 $('.expander', element).click(PyAMS_zodbbrowser.collapseOrExpand); |
|
182 PyAMS_zodbbrowser.hideItemsIfTooMany(); |
|
183 $('#path a', element).click(function (event) { |
|
184 event.stopPropagation(); |
|
185 }); |
|
186 $('#path', element).click(PyAMS_zodbbrowser.showGoTo); |
|
187 $('#gotoInput', element).blur(PyAMS_zodbbrowser.hideGoTo); |
|
188 $('#gotoInput', element).keypress(function (event) { |
|
189 if (event.which == 13) { // enter |
|
190 PyAMS_zodbbrowser.activateGoTo(); |
|
191 } |
|
192 }); |
|
193 $('#gotoInput', element).keydown(function (event) { |
|
194 if (event.keyCode == 27) { // escape |
|
195 PyAMS_zodbbrowser.hideGoTo(); |
|
196 } |
|
197 }); |
|
198 $(document).keypress(function (event) { |
|
199 if (event.which == 103) { // lowercase g |
|
200 if ($('#goto', element).is(':hidden')) { |
|
201 PyAMS_zodbbrowser.showGoTo(); |
|
202 event.preventDefault(); |
|
203 } |
|
204 } |
|
205 }); |
|
206 $('input.rollbackbtn', element).click(PyAMS_zodbbrowser.pressRollback); |
|
207 $('span.truncated', element).click(function (event) { |
|
208 event.preventDefault(); |
|
209 var placeholder = $(this); |
|
210 var id = placeholder.attr('id'); |
|
211 $.ajax({ |
|
212 url: 'zodbbrowser_truncated', data: 'id=' + id, |
|
213 success: function (data, status) { |
|
214 placeholder.replaceWith(data); |
|
215 } |
|
216 }); |
|
217 }); |
|
218 } |
|
219 } |
|
220 |
|
221 })(jQuery); |