]> git.donarmstrong.com Git - roundcube.git/blob - skins/default/functions.js
Imported Upstream version 0.5.1
[roundcube.git] / skins / default / functions.js
1 /**
2  * Roundcube functions for default skin interface
3  */
4
5 /**
6  * Settings
7  */
8
9 function rcube_init_settings_tabs()
10 {
11   var tab = '#settingstabdefault';
12   if (window.rcmail && rcmail.env.action)
13     tab = '#settingstab' + (rcmail.env.action=='preferences' ? 'default' : (rcmail.env.action.indexOf('identity')>0 ? 'identities' : rcmail.env.action.replace(/\./g, '')));
14
15   $(tab).addClass('tablink-selected');
16   $(tab + '> a').removeAttr('onclick').unbind('click').bind('click', function(){return false;});
17 }
18
19 function rcube_show_advanced(visible)
20 {
21   $('tr.advanced').css('display', (visible ? (bw.ie ? 'block' : 'table-row') : 'none'));
22 }
23
24 // Fieldsets-to-tabs converter
25 // Warning: don't place "caller" <script> inside page element (id)
26 function rcube_init_tabs(id, current)
27 {
28   var content = document.getElementById(id),
29     // get fieldsets of the higher-level (skip nested fieldsets)
30     fs = $('fieldset', content).not('fieldset > fieldset');
31
32   if (!fs.length)
33     return;
34
35   current = current ? current : 0;
36
37   // first hide not selected tabs
38   fs.each(function(idx) { if (idx != current) $(this).hide(); });
39
40   // create tabs container
41   var tabs = $('<div>').addClass('tabsbar').appendTo($(content));
42
43   // convert fildsets into tabs
44   fs.each(function(idx) {
45     var tab, a, elm = $(this),
46       // get first legend element
47       legend = $(elm).children('legend');
48
49     // create a tab
50     a   = $('<a>').text(legend.text()).attr('href', '#');
51     tab = $('<span>').attr({'id': 'tab'+idx, 'class': 'tablink'})
52         .click(function() { rcube_show_tab(id, idx); return false })
53
54     // remove legend
55     legend.remove();
56     // style fieldset
57     elm.addClass('tabbed');
58     // style selected tab
59     if (idx == current)
60       tab.addClass('tablink-selected');
61
62     // add the tab to container
63     tab.append(a).appendTo(tabs);
64   });
65 }
66
67 function rcube_show_tab(id, index)
68 {
69   var content = document.getElementById(id),
70     fs = $('fieldset', content).not('fieldset > fieldset');
71
72   fs.each(function(idx) {
73     // Show/hide fieldset (tab content)
74     $(this)[index==idx ? 'show' : 'hide']();
75     // Select/unselect tab
76     $('#tab'+idx).toggleClass('tablink-selected', idx==index);
77   });
78 }
79
80 /**
81  * Mail UI
82  */
83
84 function rcube_mail_ui()
85 {
86   this.popups = {
87     markmenu:       {id:'markmessagemenu'},
88     replyallmenu:   {id:'replyallmenu'},
89     searchmenu:     {id:'searchmenu', editable:1},
90     messagemenu:    {id:'messagemenu'},
91     listmenu:       {id:'listmenu', editable:1},
92     dragmessagemenu:{id:'dragmessagemenu', sticky:1},
93     groupmenu:      {id:'groupoptionsmenu', above:1},
94     mailboxmenu:    {id:'mailboxoptionsmenu', above:1},
95     composemenu:    {id:'composeoptionsmenu', editable:1},
96     // toggle: #1486823, #1486930
97     uploadmenu:     {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux }
98   };
99
100   var obj;
101   for (var k in this.popups) {
102     obj = $('#'+this.popups[k].id)
103     if (obj.length)
104       this.popups[k].obj = obj;
105     else {
106       delete this.popups[k];
107     }
108   }
109 }
110
111 rcube_mail_ui.prototype = {
112
113 show_popup: function(popup, show)
114 {
115   if (typeof this[popup] == 'function')
116     return this[popup](show);
117   else
118     return this.show_popupmenu(popup, show);
119 },
120
121 show_popupmenu: function(popup, show)
122 {
123   var obj = this.popups[popup].obj,
124     above = this.popups[popup].above,
125     ref = rcube_find_object(popup+'link');
126
127   if (typeof show == 'undefined')
128     show = obj.is(':visible') ? false : true;
129   else if (this.popups[popup].toggle && show && this.popups[popup].obj.is(':visible') )
130     show = false;
131
132   if (show && ref) {
133     var parent = $(ref).parent(),
134       pos = parent.hasClass('dropbutton') ? parent.offset() : $(ref).offset();
135
136     if (!above && pos.top + ref.offsetHeight + obj.height() > window.innerHeight)
137       above = true;
138
139     obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.offsetHeight)) });
140   }
141
142   obj[show?'show':'hide']();
143 },
144
145 dragmessagemenu: function(show)
146 {
147   this.popups.dragmessagemenu.obj[show?'show':'hide']();
148 },
149
150 uploadmenu: function(show)
151 {
152   if (typeof show == 'object') // called as event handler
153     show = false;
154
155   // clear upload form
156   if (!show) {
157     try { $('#attachment-form form')[0].reset(); }
158     catch(e){}  // ignore errors
159   }
160
161   this.show_popupmenu('uploadmenu', show);
162
163   if (!document.all && this.popups.uploadmenu.obj.is(':visible'))
164     $('#attachment-form input[type=file]').click();
165 },
166
167 searchmenu: function(show)
168 {
169   var obj = this.popups.searchmenu.obj,
170     ref = rcube_find_object('searchmenulink');
171
172   if (typeof show == 'undefined')
173     show = obj.is(':visible') ? false : true;
174
175   if (show && ref) {
176     var pos = $(ref).offset();
177     obj.css({ left:pos.left, top:(pos.top + ref.offsetHeight + 2)})
178         .find(':checked').attr('checked', false);
179
180     if (rcmail.env.search_mods) {
181       var search_mods = rcmail.env.search_mods[rcmail.env.mailbox] ? rcmail.env.search_mods[rcmail.env.mailbox] : rcmail.env.search_mods['*'];
182       for (var n in search_mods)
183         $('#s_mod_' + n).attr('checked', true);
184     }
185   }
186   obj[show?'show':'hide']();
187 },
188
189 set_searchmod: function(elem)
190 {
191   if (!rcmail.env.search_mods)
192     rcmail.env.search_mods = {};
193
194   if (!rcmail.env.search_mods[rcmail.env.mailbox])
195     rcmail.env.search_mods[rcmail.env.mailbox] = rcube_clone_object(rcmail.env.search_mods['*']);
196
197   if (!elem.checked)
198     delete(rcmail.env.search_mods[rcmail.env.mailbox][elem.value]);
199   else
200     rcmail.env.search_mods[rcmail.env.mailbox][elem.value] = elem.value;
201 },
202
203 listmenu: function(show)
204 {
205   var obj = this.popups.listmenu.obj,
206     ref = rcube_find_object('listmenulink');
207
208   if (typeof show == 'undefined')
209     show = obj.is(':visible') ? false : true;
210
211   if (show && ref) {
212     var pos = $(ref).offset(),
213       menuwidth = obj.width(),
214       pagewidth = $(document).width();
215
216     if (pagewidth - pos.left < menuwidth && pos.left > menuwidth)
217       pos.left = pos.left - menuwidth;
218
219     obj.css({ left:pos.left, top:(pos.top + ref.offsetHeight + 2)});
220     // set form values
221     $('input[name="sort_col"][value="'+rcmail.env.sort_col+'"]').attr('checked', 1);
222     $('input[name="sort_ord"][value="DESC"]').attr('checked', rcmail.env.sort_order=='DESC' ? 1 : 0);
223     $('input[name="sort_ord"][value="ASC"]').attr('checked', rcmail.env.sort_order=='DESC' ? 0 : 1);
224     $('input[name="view"][value="thread"]').attr('checked', rcmail.env.threading ? 1 : 0);
225     $('input[name="view"][value="list"]').attr('checked', rcmail.env.threading ? 0 : 1);
226     // list columns
227     var cols = $('input[name="list_col[]"]');
228     for (var i=0; i<cols.length; i++) {
229       var found = 0;
230       if (cols[i].value != 'from')
231         found = jQuery.inArray(cols[i].value, rcmail.env.coltypes) != -1;
232       else
233         found = (jQuery.inArray('from', rcmail.env.coltypes) != -1
234             || jQuery.inArray('to', rcmail.env.coltypes) != -1);
235       $(cols[i]).attr('checked',found ? 1 : 0);
236     }
237   }
238
239   obj[show?'show':'hide']();
240
241   if (show) {
242     var maxheight=0;
243     $('#listmenu fieldset').each(function() {
244       var height = $(this).height();
245       if (height > maxheight) {
246         maxheight = height;
247       }
248     });
249     $('#listmenu fieldset').css("min-height", maxheight+"px")
250     // IE6 complains if you set this attribute using either method:
251     //$('#listmenu fieldset').css({'height':'auto !important'});
252     //$('#listmenu fieldset').css("height","auto !important");
253       .height(maxheight);
254   };
255 },
256
257 open_listmenu: function(e)
258 {
259   this.listmenu();
260 },
261
262 save_listmenu: function()
263 {
264   this.listmenu();
265
266   var sort = $('input[name="sort_col"]:checked').val(),
267     ord = $('input[name="sort_ord"]:checked').val(),
268     thread = $('input[name="view"]:checked').val(),
269     cols = $('input[name="list_col[]"]:checked')
270       .map(function(){ return this.value; }).get();
271
272   rcmail.set_list_options(cols, sort, ord, thread == 'thread' ? 1 : 0);
273 },
274
275 body_mouseup: function(evt, p)
276 {
277   var i, target = rcube_event.get_target(evt);
278
279   for (i in this.popups) {
280     if (this.popups[i].obj.is(':visible') && target != rcube_find_object(i+'link')
281       && !this.popups[i].toggle
282       && (!this.popups[i].editable || !this.target_overlaps(target, this.popups[i].id))
283       && (!this.popups[i].sticky || !rcube_mouse_is_over(evt, rcube_find_object(this.popups[i].id)))
284     ) {
285       window.setTimeout('$("#'+this.popups[i].id+'").hide()', 50);
286     }
287   }
288 },
289
290 target_overlaps: function (target, elementid)
291 {
292   var element = rcube_find_object(elementid);
293   while (target.parentNode) {
294     if (target.parentNode == element)
295       return true;
296     target = target.parentNode;
297   }
298   return false;
299 },
300
301 body_keydown: function(evt, p)
302 {
303   if (rcube_event.get_keycode(evt) == 27) {
304     for (var k in this.popups) {
305       if (this.popups[k].obj.is(':visible'))
306         this.show_popup(k, false);
307     }
308   }
309 },
310
311 switch_preview_pane: function(elem)
312 {
313   var uid, prev_frm = $('#mailpreviewframe');
314
315   if (elem.checked) {
316     rcmail.env.contentframe = 'messagecontframe';
317     if (mailviewsplit.layer) {
318       mailviewsplit.resize();
319       mailviewsplit.layer.elm.style.display = '';
320     }
321     else
322       mailviewsplit.init();
323
324     if (bw.opera) {
325       $('#messagelistcontainer').css({height: ''});
326     }
327     prev_frm.show();
328
329     if (uid = rcmail.message_list.get_single_selection())
330       rcmail.show_message(uid, false, true);
331   }
332   else {
333     prev_frm.hide();
334     if (bw.ie6 || bw.ie7) {
335       var fr = document.getElementById('mailcontframe');
336       fr.style.bottom = 0;
337       fr.style.height = parseInt(fr.parentNode.offsetHeight)+'px';
338     }
339     else {
340       $('#mailcontframe').css({height: 'auto', bottom: 0});
341       if (bw.opera)
342         $('#messagelistcontainer').css({height: 'auto'});
343     }
344     if (mailviewsplit.layer)
345       mailviewsplit.layer.elm.style.display = 'none';
346
347     rcmail.env.contentframe = null;
348     rcmail.show_contentframe(false);
349   }
350   rcmail.http_post('save-pref', '_name=preview_pane&_value='+(elem.checked?1:0));
351 },
352
353 /* Message composing */
354 init_compose_form: function()
355 {
356   var f, field, fields = ['cc', 'bcc', 'replyto', 'followupto'],
357     div = document.getElementById('compose-div'),
358     headers_div = document.getElementById('compose-headers-div');
359
360   // Show input elements with non-empty value
361   for (f=0; f<fields.length; f++) {
362     if ((field = $('#_'+fields[f])) && field.length && field.val() != '')
363       rcmail_ui.show_header_form(fields[f]);
364   }
365
366   // prevent from form data loss when pressing ESC key in IE
367   if (bw.ie) {
368     var form = rcube_find_object('form');
369     form.onkeydown = function (e) {
370       if (rcube_event.get_keycode(e) == 27)
371         rcube_event.cancel(e);
372     };
373   }
374
375   $(window).resize(function() {
376     rcmail_ui.resize_compose_body();
377   });
378
379   $('#compose-container').resize(function() {
380     rcmail_ui.resize_compose_body();
381   });
382
383   div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px';
384   $(window).resize();
385 },
386
387 resize_compose_body: function()
388 {
389   var div = $('#compose-div .boxlistcontent'), w = div.width(), h = div.height();
390   w -= 8;  // 2 x 3px padding + 2 x 1px border
391   h -= 4;
392
393   $('#compose-body').width(w+'px').height(h+'px');
394
395   if (window.tinyMCE && tinyMCE.get('compose-body')) {
396     $('#compose-body_tbl').width((w+6)+'px').height('');
397     $('#compose-body_ifr').width((w+6)+'px').height((h-54)+'px');
398   }
399   else {
400     $('#googie_edit_layer').height(h+'px');
401   }
402 },
403
404 resize_compose_body_ev: function()
405 {
406   window.setTimeout(function(){rcmail_ui.resize_compose_body();}, 100);
407 },
408
409 show_header_form: function(id)
410 {
411   var row, s,
412     link = document.getElementById(id + '-link');
413
414   if ((s = this.next_sibling(link)))
415     s.style.display = 'none';
416   else if ((s = this.prev_sibling(link)))
417     s.style.display = 'none';
418
419   link.style.display = 'none';
420
421   if ((row = document.getElementById('compose-' + id))) {
422     var div = document.getElementById('compose-div'),
423       headers_div = document.getElementById('compose-headers-div');
424     row.style.display = (document.all && !window.opera) ? 'block' : 'table-row';
425     div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px';
426     this.resize_compose_body();
427   }
428
429   return false;
430 },
431
432 hide_header_form: function(id)
433 {
434   var row, ns,
435     link = document.getElementById(id + '-link'),
436     parent = link.parentNode,
437     links = parent.getElementsByTagName('a');
438
439   link.style.display = '';
440
441   for (var i=0; i<links.length; i++)
442     if (links[i].style.display != 'none')
443       for (var j=i+1; j<links.length; j++)
444             if (links[j].style.display != 'none')
445           if ((ns = this.next_sibling(links[i]))) {
446                 ns.style.display = '';
447                 break;
448               }
449
450   document.getElementById('_' + id).value = '';
451
452   if ((row = document.getElementById('compose-' + id))) {
453     var div = document.getElementById('compose-div'),
454       headers_div = document.getElementById('compose-headers-div');
455     row.style.display = 'none';
456     div.style.top = (parseInt(headers_div.offsetHeight, 10) + 1) + 'px';
457     this.resize_compose_body();
458   }
459
460   return false;
461 },
462
463 next_sibling: function(elm)
464 {
465   var ns = elm.nextSibling;
466   while (ns && ns.nodeType == 3)
467     ns = ns.nextSibling;
468   return ns;
469 },
470
471 prev_sibling: function(elm)
472 {
473   var ps = elm.previousSibling;
474   while (ps && ps.nodeType == 3)
475     ps = ps.previousSibling;
476   return ps;
477 }
478
479 };
480
481
482 var rcmail_ui;
483
484 function rcube_init_mail_ui()
485 {
486   rcmail_ui = new rcube_mail_ui();
487   rcube_event.add_listener({ object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
488   rcube_event.add_listener({ object:rcmail_ui, method:'body_keydown', event:'keydown' });
489
490   $('iframe').load(iframe_events)
491     .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});
492
493   if (rcmail.env.task == 'mail') {
494     rcmail.addEventListener('menu-open', 'open_listmenu', rcmail_ui);
495     rcmail.addEventListener('menu-save', 'save_listmenu', rcmail_ui);
496     rcmail.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui);
497     rcmail.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui);
498     rcmail.gui_object('message_dragmenu', 'dragmessagemenu');
499
500     if (rcmail.env.action == 'compose')
501       rcmail_ui.init_compose_form();
502   }
503 }
504
505 // Events handling in iframes (eg. preview pane)
506 function iframe_events()
507 {
508   // this==iframe
509   var doc = this.contentDocument ? this.contentDocument : this.contentWindow ? this.contentWindow.document : null;
510   rcube_event.add_listener({ element: doc, object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
511 }
512