comparison .svn/pristine/2d/2de3a87e3fe026c2ba56948a00c54c7c54909e85.svn-base @ 909:cbb26bc654de redmine-1.3

Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author Chris Cannam
date Fri, 24 Feb 2012 19:09:32 +0000
parents
children
comparison
equal deleted inserted replaced
908:c6c2cbd0afee 909:cbb26bc654de
1 /* redMine - project management software
2 Copyright (C) 2006-2008 Jean-Philippe Lang */
3
4 function checkAll (id, checked) {
5 var els = Element.descendants(id);
6 for (var i = 0; i < els.length; i++) {
7 if (els[i].disabled==false) {
8 els[i].checked = checked;
9 }
10 }
11 }
12
13 function toggleCheckboxesBySelector(selector) {
14 boxes = $$(selector);
15 var all_checked = true;
16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
18 }
19
20 function setCheckboxesBySelector(checked, selector) {
21 var boxes = $$(selector);
22 boxes.each(function(ele) {
23 ele.checked = checked;
24 });
25 }
26
27 function showAndScrollTo(id, focus) {
28 Element.show(id);
29 if (focus!=null) { Form.Element.focus(focus); }
30 Element.scrollTo(id);
31 }
32
33 function toggleRowGroup(el) {
34 var tr = Element.up(el, 'tr');
35 var n = Element.next(tr);
36 tr.toggleClassName('open');
37 while (n != undefined && !n.hasClassName('group')) {
38 Element.toggle(n);
39 n = Element.next(n);
40 }
41 }
42
43 function collapseAllRowGroups(el) {
44 var tbody = Element.up(el, 'tbody');
45 tbody.childElements('tr').each(function(tr) {
46 if (tr.hasClassName('group')) {
47 tr.removeClassName('open');
48 } else {
49 tr.hide();
50 }
51 })
52 }
53
54 function expandAllRowGroups(el) {
55 var tbody = Element.up(el, 'tbody');
56 tbody.childElements('tr').each(function(tr) {
57 if (tr.hasClassName('group')) {
58 tr.addClassName('open');
59 } else {
60 tr.show();
61 }
62 })
63 }
64
65 function toggleAllRowGroups(el) {
66 var tr = Element.up(el, 'tr');
67 if (tr.hasClassName('open')) {
68 collapseAllRowGroups(el);
69 } else {
70 expandAllRowGroups(el);
71 }
72 }
73
74 function toggleFieldset(el) {
75 var fieldset = Element.up(el, 'fieldset');
76 fieldset.toggleClassName('collapsed');
77 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
78 }
79
80 function hideFieldset(el) {
81 var fieldset = Element.up(el, 'fieldset');
82 fieldset.toggleClassName('collapsed');
83 fieldset.down('div').hide();
84 }
85
86 var fileFieldCount = 1;
87
88 function addFileField() {
89 var fields = $('attachments_fields');
90 if (fields.childElements().length >= 10) return false;
91 fileFieldCount++;
92 var s = new Element('span');
93 s.update(fields.down('span').innerHTML);
94 s.down('input.file').name = "attachments[" + fileFieldCount + "][file]";
95 s.down('input.description').name = "attachments[" + fileFieldCount + "][description]";
96 fields.appendChild(s);
97 }
98
99 function removeFileField(el) {
100 var fields = $('attachments_fields');
101 var s = Element.up(el, 'span');
102 if (fields.childElements().length > 1) {
103 s.remove();
104 } else {
105 s.update(s.innerHTML);
106 }
107 }
108
109 function checkFileSize(el, maxSize, message) {
110 var files = el.files;
111 if (files) {
112 for (var i=0; i<files.length; i++) {
113 if (files[i].size > maxSize) {
114 alert(message);
115 el.value = "";
116 }
117 }
118 }
119 }
120
121 function showTab(name) {
122 var f = $$('div#content .tab-content');
123 for(var i=0; i<f.length; i++){
124 Element.hide(f[i]);
125 }
126 var f = $$('div.tabs a');
127 for(var i=0; i<f.length; i++){
128 Element.removeClassName(f[i], "selected");
129 }
130 Element.show('tab-content-' + name);
131 Element.addClassName('tab-' + name, "selected");
132 return false;
133 }
134
135 function moveTabRight(el) {
136 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
137 var tabsWidth = 0;
138 var i;
139 for (i=0; i<lis.length; i++) {
140 if (lis[i].visible()) {
141 tabsWidth += lis[i].getWidth() + 6;
142 }
143 }
144 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
145 return;
146 }
147 i=0;
148 while (i<lis.length && !lis[i].visible()) {
149 i++;
150 }
151 lis[i].hide();
152 }
153
154 function moveTabLeft(el) {
155 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
156 var i = 0;
157 while (i<lis.length && !lis[i].visible()) {
158 i++;
159 }
160 if (i>0) {
161 lis[i-1].show();
162 }
163 }
164
165 function displayTabsButtons() {
166 var lis;
167 var tabsWidth = 0;
168 var i;
169 $$('div.tabs').each(function(el) {
170 lis = el.down('ul').childElements();
171 for (i=0; i<lis.length; i++) {
172 if (lis[i].visible()) {
173 tabsWidth += lis[i].getWidth() + 6;
174 }
175 }
176 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
177 el.down('div.tabs-buttons').hide();
178 } else {
179 el.down('div.tabs-buttons').show();
180 }
181 });
182 }
183
184 function setPredecessorFieldsVisibility() {
185 relationType = $('relation_relation_type');
186 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
187 Element.show('predecessor_fields');
188 } else {
189 Element.hide('predecessor_fields');
190 }
191 }
192
193 function promptToRemote(text, param, url) {
194 value = prompt(text + ':');
195 if (value) {
196 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
197 return false;
198 }
199 }
200
201 function showModal(id, width) {
202 el = $(id);
203 if (el == undefined || el.visible()) {return;}
204 var h = $$('body')[0].getHeight();
205 var d = document.createElement("div");
206 d.id = 'modalbg';
207 $('main').appendChild(d);
208 $('modalbg').setStyle({ width: '100%', height: h + 'px' });
209 $('modalbg').show();
210
211 var pageWidth = document.viewport.getWidth();
212 el.setStyle({'width': width});
213 el.setStyle({'left': (((pageWidth - el.getWidth())/2 *100) / pageWidth) + '%'});
214 el.addClassName('modal');
215 el.show();
216
217 var submit = el.down("input[type=submit]");
218 if (submit) {
219 submit.focus();
220 }
221 }
222
223 function hideModal(el) {
224 var modal = Element.up(el, 'div.modal');
225 if (modal) {
226 modal.hide();
227 }
228 var bg = $('modalbg');
229 if (bg) {
230 bg.remove();
231 }
232 }
233
234 function collapseScmEntry(id) {
235 var els = document.getElementsByClassName(id, 'browser');
236 for (var i = 0; i < els.length; i++) {
237 if (els[i].hasClassName('open')) {
238 collapseScmEntry(els[i].id);
239 }
240 Element.hide(els[i]);
241 }
242 $(id).removeClassName('open');
243 }
244
245 function expandScmEntry(id) {
246 var els = document.getElementsByClassName(id, 'browser');
247 for (var i = 0; i < els.length; i++) {
248 Element.show(els[i]);
249 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
250 expandScmEntry(els[i].id);
251 }
252 }
253 $(id).addClassName('open');
254 }
255
256 function scmEntryClick(id) {
257 el = $(id);
258 if (el.hasClassName('open')) {
259 collapseScmEntry(id);
260 el.addClassName('collapsed');
261 return false;
262 } else if (el.hasClassName('loaded')) {
263 expandScmEntry(id);
264 el.removeClassName('collapsed');
265 return false;
266 }
267 if (el.hasClassName('loading')) {
268 return false;
269 }
270 el.addClassName('loading');
271 return true;
272 }
273
274 function scmEntryLoaded(id) {
275 Element.addClassName(id, 'open');
276 Element.addClassName(id, 'loaded');
277 Element.removeClassName(id, 'loading');
278 }
279
280 function randomKey(size) {
281 var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
282 var key = '';
283 for (i = 0; i < size; i++) {
284 key += chars[Math.floor(Math.random() * chars.length)];
285 }
286 return key;
287 }
288
289 function observeParentIssueField(url) {
290 new Ajax.Autocompleter('issue_parent_issue_id',
291 'parent_issue_candidates',
292 url,
293 { minChars: 3,
294 frequency: 0.5,
295 paramName: 'q',
296 method: 'get',
297 updateElement: function(value) {
298 document.getElementById('issue_parent_issue_id').value = value.id;
299 }});
300 }
301
302 function observeRelatedIssueField(url) {
303 new Ajax.Autocompleter('relation_issue_to_id',
304 'related_issue_candidates',
305 url,
306 { minChars: 3,
307 frequency: 0.5,
308 paramName: 'q',
309 method: 'get',
310 updateElement: function(value) {
311 document.getElementById('relation_issue_to_id').value = value.id;
312 },
313 parameters: 'scope=all'
314 });
315 }
316
317 function setVisible(id, visible) {
318 var el = $(id);
319 if (el) {if (visible) {el.show();} else {el.hide();}}
320 }
321
322 function observeProjectModules() {
323 var f = function() {
324 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
325 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
326 setVisible('project_trackers', c);
327 setVisible('project_issue_custom_fields', c);
328 };
329
330 Event.observe(window, 'load', f);
331 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
332 }
333
334 /*
335 * Class used to warn user when leaving a page with unsaved textarea
336 * Author: mathias.fischer@berlinonline.de
337 */
338
339 var WarnLeavingUnsaved = Class.create({
340 observedForms: false,
341 observedElements: false,
342 changedForms: false,
343 message: null,
344
345 initialize: function(message){
346 this.observedForms = $$('form');
347 this.observedElements = $$('textarea');
348 this.message = message;
349
350 this.observedElements.each(this.observeChange.bind(this));
351 this.observedForms.each(this.submitAction.bind(this));
352
353 window.onbeforeunload = this.unload.bind(this);
354 },
355
356 unload: function(){
357 this.observedElements.each(function(el) {el.blur();})
358 if(this.changedForms)
359 return this.message;
360 },
361
362 setChanged: function(){
363 this.changedForms = true;
364 },
365
366 setUnchanged: function(){
367 this.changedForms = false;
368 },
369
370 observeChange: function(element){
371 element.observe('change',this.setChanged.bindAsEventListener(this));
372 },
373
374 submitAction: function(element){
375 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
376 }
377 });
378
379 /*
380 * 1 - registers a callback which copies the csrf token into the
381 * X-CSRF-Token header with each ajax request. Necessary to
382 * work with rails applications which have fixed
383 * CVE-2011-0447
384 * 2 - shows and hides ajax indicator
385 */
386 Ajax.Responders.register({
387 onCreate: function(request){
388 var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
389
390 if (csrf_meta_tag) {
391 var header = 'X-CSRF-Token',
392 token = csrf_meta_tag.readAttribute('content');
393
394 if (!request.options.requestHeaders) {
395 request.options.requestHeaders = {};
396 }
397 request.options.requestHeaders[header] = token;
398 }
399
400 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
401 Element.show('ajax-indicator');
402 }
403 },
404 onComplete: function(){
405 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
406 Element.hide('ajax-indicator');
407 }
408 }
409 });
410
411 function hideOnLoad() {
412 $$('.hol').each(function(el) {
413 el.hide();
414 });
415 }
416
417 Event.observe(window, 'load', hideOnLoad);