Thomas Bruederli
2013-01-14 2080feca9367c057590835df12f5ebe6da8c1e9c
commit | author | age
5f660c 1 /**
e019f2 2  * Roundcube functions for default skin interface
5f660c 3  */
A 4
5 /**
6  * Settings
7  */
8
9 function rcube_init_settings_tabs()
10 {
a3ed96 11   var el, cl, container = $('#tabsbar'),
A 12     last_tab = $('span:last', container),
13     tab = '#settingstabdefault',
14     action = window.rcmail && rcmail.env.action ? rcmail.env.action : null;
15
16   // move About tab to the end
17   if (last_tab && last_tab.attr('id') != 'settingstababout' && (el = $('#settingstababout'))) {
18     cl = el.clone(true);
19     el.remove();
20     last_tab.after(cl);
21   }
22
23   // get selected tab
24   if (action)
25     tab = '#settingstab' + (action == 'preferences' ? 'default' : (action.indexOf('identity')>0 ? 'identities' : action.replace(/\./g, '')));
cc97ea 26
T 27   $(tab).addClass('tablink-selected');
9489a2 28   $('a', tab).removeAttr('onclick').click(function() { return false; });
5f660c 29 }
A 30
6769ba 31 // Fieldsets-to-tabs converter
A 32 // Warning: don't place "caller" <script> inside page element (id)
33 function rcube_init_tabs(id, current)
34 {
0501b6 35   var content = $('#'+id),
T 36     fs = content.children('fieldset');
7403ab 37
A 38   if (!fs.length)
39     return;
6769ba 40
A 41   current = current ? current : 0;
42
43   // first hide not selected tabs
44   fs.each(function(idx) { if (idx != current) $(this).hide(); });
45
46   // create tabs container
5744bf 47   var tabs = $('<div>').addClass('tabsbar').appendTo(content);
6769ba 48
A 49   // convert fildsets into tabs
50   fs.each(function(idx) {
0501b6 51     var tab, a, elm = $(this), legend = elm.children('legend');
6769ba 52
A 53     // create a tab
54     a   = $('<a>').text(legend.text()).attr('href', '#');
55     tab = $('<span>').attr({'id': 'tab'+idx, 'class': 'tablink'})
361ce6 56         .click(function() { rcube_show_tab(id, idx); return false })
6769ba 57
A 58     // remove legend
59     legend.remove();
60     // style fieldset
61     elm.addClass('tabbed');
62     // style selected tab
63     if (idx == current)
64       tab.addClass('tablink-selected');
65
66     // add the tab to container
67     tab.append(a).appendTo(tabs);
68   });
69 }
70
71 function rcube_show_tab(id, index)
72 {
0501b6 73   var fs = $('#'+id).children('fieldset');
6769ba 74
A 75   fs.each(function(idx) {
76     // Show/hide fieldset (tab content)
77     $(this)[index==idx ? 'show' : 'hide']();
78     // Select/unselect tab
79     $('#tab'+idx).toggleClass('tablink-selected', idx==index);
80   });
81 }
82
5f660c 83 /**
3940ba 84  * Mail UI
5f660c 85  */
A 86
87 function rcube_mail_ui()
88 {
9e5550 89   this.popups = {
A 90     markmenu:       {id:'markmessagemenu'},
e25a35 91     replyallmenu:   {id:'replyallmenu'},
d145f7 92     forwardmenu:    {id:'forwardmenu', editable:1},
9e5550 93     searchmenu:     {id:'searchmenu', editable:1},
A 94     messagemenu:    {id:'messagemenu'},
95     listmenu:       {id:'listmenu', editable:1},
96     dragmessagemenu:{id:'dragmessagemenu', sticky:1},
97     groupmenu:      {id:'groupoptionsmenu', above:1},
98     mailboxmenu:    {id:'mailboxoptionsmenu', above:1},
d145f7 99     composemenu:    {id:'composeoptionsmenu', editable:1, overlap:1},
4be86f 100     spellmenu:      {id:'spellmenu'},
71f60c 101     // toggle: #1486823, #1486930
0501b6 102     uploadmenu:     {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux },
T 103     uploadform:     {id:'upload-form', editable:1, toggle:!bw.ie&&!bw.linux }
a61bbb 104   };
3940ba 105
a61bbb 106   var obj;
9e5550 107   for (var k in this.popups) {
A 108     obj = $('#'+this.popups[k].id)
a61bbb 109     if (obj.length)
9e5550 110       this.popups[k].obj = obj;
A 111     else {
112       delete this.popups[k];
113     }
a61bbb 114   }
5f660c 115 }
A 116
117 rcube_mail_ui.prototype = {
118
4b09fb 119 show_popup: function(popup, show, config)
5f660c 120 {
4b09fb 121   var obj;
A 122   // auto-register menu object
123   if (!this.popups[popup] && (obj = $('#'+popup)) && obj.length)
124     this.popups[popup] = $.extend(config, {id: popup, obj: obj});
125
9e5550 126   if (typeof this[popup] == 'function')
A 127     return this[popup](show);
128   else
129     return this.show_popupmenu(popup, show);
130 },
131
132 show_popupmenu: function(popup, show)
133 {
134   var obj = this.popups[popup].obj,
135     above = this.popups[popup].above,
136     ref = rcube_find_object(popup+'link');
137
5f660c 138   if (typeof show == 'undefined')
a61bbb 139     show = obj.is(':visible') ? false : true;
0e2ccb 140   else if (this.popups[popup].toggle && show && this.popups[popup].obj.is(':visible') )
T 141     show = false;
6c9d49 142
a61bbb 143   if (show && ref) {
8431a7 144     var parent = $(ref).parent(),
26e76d 145       win = $(window),
8431a7 146       pos = parent.hasClass('dropbutton') ? parent.offset() : $(ref).offset();
A 147
26e76d 148     if (!above && pos.top + ref.offsetHeight + obj.height() > win.height())
b218aa 149       above = true;
26e76d 150     if (pos.left + obj.width() > win.width())
T 151       pos.left = win.width() - obj.width() - 30;
8431a7 152
a61bbb 153     obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.offsetHeight)) });
T 154   }
3940ba 155
a61bbb 156   obj[show?'show':'hide']();
4b09fb 157
d145f7 158   if (bw.ie6 && this.popups[popup].overlap) {
T 159     $('select').css('visibility', show?'hidden':'inherit');
160     $('select', obj).css('visibility', 'inherit');
161   }
a61bbb 162 },
T 163
9e5550 164 dragmessagemenu: function(show)
a61bbb 165 {
9e5550 166   this.popups.dragmessagemenu.obj[show?'show':'hide']();
511420 167 },
A 168
a509bb 169 forwardmenu: function(show)
A 170 {
171   $("input[name='forwardtype'][value="+(rcmail.env.forward_attachment ? 1 : 0)+"]", this.popups.forwardmenu.obj)
172     .prop('checked', true);
173   this.show_popupmenu('forwardmenu', show);
174 },
175
9e5550 176 uploadmenu: function(show)
087c7d 177 {
A 178   if (typeof show == 'object') // called as event handler
179     show = false;
64fa95 180
T 181   // clear upload form
182   if (!show) {
183     try { $('#attachment-form form')[0].reset(); }
184     catch(e){}  // ignore errors
185   }
b218aa 186
9e5550 187   this.show_popupmenu('uploadmenu', show);
b218aa 188
9a4fd7 189   if (!document.all && this.popups.uploadmenu.obj.is(':visible'))
b218aa 190     $('#attachment-form input[type=file]').click();
5f660c 191 },
A 192
9e5550 193 searchmenu: function(show)
30b152 194 {
9e5550 195   var obj = this.popups.searchmenu.obj,
A 196     ref = rcube_find_object('searchmenulink');
30b152 197
9e5550 198   if (typeof show == 'undefined')
A 199     show = obj.is(':visible') ? false : true;
200
30b152 201   if (show && ref) {
A 202     var pos = $(ref).offset();
3e5c70 203     obj.css({left:pos.left, top:(pos.top + ref.offsetHeight + 2)});
30b152 204
A 205     if (rcmail.env.search_mods) {
3e5c70 206       var n, all,
A 207         list = $('input:checkbox[name="s_mods[]"]', obj),
208         mbox = rcmail.env.mailbox,
209         mods = rcmail.env.search_mods;
3cacf9 210
3e5c70 211       if (rcmail.env.task == 'mail') {
3cacf9 212         mods = mods[mbox] ? mods[mbox] : mods['*'];
3e5c70 213         all = 'text';
3cacf9 214       }
A 215       else {
3e5c70 216         all = '*';
A 217       }
218
219       if (mods[all])
220         list.map(function() {
221           this.checked = true;
222           this.disabled = this.value != all;
223         });
224       else {
225         list.prop('disabled', false).prop('checked', false);
226         for (n in mods)
227           $('#s_mod_' + n).prop('checked', true);
3cacf9 228       }
30b152 229     }
A 230   }
9e5550 231   obj[show?'show':'hide']();
30b152 232 },
3940ba 233
30b152 234 set_searchmod: function(elem)
A 235 {
3e5c70 236   var all, m, task = rcmail.env.task,
3cacf9 237     mods = rcmail.env.search_mods,
A 238     mbox = rcmail.env.mailbox;
3940ba 239
3cacf9 240   if (!mods)
A 241     mods = {};
3940ba 242
3cacf9 243   if (task == 'mail') {
A 244     if (!mods[mbox])
245       mods[mbox] = rcube_clone_object(mods['*']);
3e5c70 246     m = mods[mbox];
A 247     all = 'text';
3cacf9 248   }
A 249   else { //addressbook
3e5c70 250     m = mods;
A 251     all = '*';
3cacf9 252   }
A 253
3e5c70 254   if (!elem.checked)
A 255     delete(m[elem.value]);
256   else
257     m[elem.value] = 1;
258
259   // mark all fields
260   if (elem.value != all)
261     return;
262
263   $('input:checkbox[name="s_mods[]"]').map(function() {
264     if (this == elem)
265       return;
266
267     this.checked = true;
268     if (elem.checked) {
269       this.disabled = true;
270       delete m[this.value];
271     }
272     else {
273       this.disabled = false;
274       m[this.value] = 1;
275     }
276   });
30b152 277 },
A 278
9e5550 279 listmenu: function(show)
f52c93 280 {
9e5550 281   var obj = this.popups.listmenu.obj,
A 282     ref = rcube_find_object('listmenulink');
f52c93 283
9e5550 284   if (typeof show == 'undefined')
A 285     show = obj.is(':visible') ? false : true;
286
f52c93 287   if (show && ref) {
6c9d49 288     var pos = $(ref).offset(),
9e5550 289       menuwidth = obj.width(),
6c9d49 290       pagewidth = $(document).width();
A 291
292     if (pagewidth - pos.left < menuwidth && pos.left > menuwidth)
293       pos.left = pos.left - menuwidth;
294
9e5550 295     obj.css({ left:pos.left, top:(pos.top + ref.offsetHeight + 2)});
e0efd8 296
f52c93 297     // set form values
491133 298     $('input[name="sort_col"][value="'+rcmail.env.sort_col+'"]').prop('checked', true);
A 299     $('input[name="sort_ord"][value="DESC"]').prop('checked', rcmail.env.sort_order == 'DESC');
300     $('input[name="sort_ord"][value="ASC"]').prop('checked', rcmail.env.sort_order != 'DESC');
301     $('input[name="view"][value="thread"]').prop('checked', rcmail.env.threading ? true : false);
302     $('input[name="view"][value="list"]').prop('checked', rcmail.env.threading ? false : true);
e0efd8 303
AM 304     // set checkboxes
305     $('input[name="list_col[]"]').each(function() {
306       $(this).prop('checked', jQuery.inArray(this.value, rcmail.env.coltypes) != -1);
307     });
f52c93 308   }
T 309
9e5550 310   obj[show?'show':'hide']();
f52c93 311
T 312   if (show) {
313     var maxheight=0;
314     $('#listmenu fieldset').each(function() {
315       var height = $(this).height();
316       if (height > maxheight) {
317         maxheight = height;
318       }
319     });
320     $('#listmenu fieldset').css("min-height", maxheight+"px")
321     // IE6 complains if you set this attribute using either method:
322     //$('#listmenu fieldset').css({'height':'auto !important'});
323     //$('#listmenu fieldset').css("height","auto !important");
324       .height(maxheight);
325   };
326 },
327
328 open_listmenu: function(e)
329 {
9e5550 330   this.listmenu();
f52c93 331 },
T 332
333 save_listmenu: function()
334 {
9e5550 335   this.listmenu();
f52c93 336
a80405 337   var sort = $('input[name="sort_col"]:checked').val(),
A 338     ord = $('input[name="sort_ord"]:checked').val(),
339     thread = $('input[name="view"]:checked').val(),
340     cols = $('input[name="list_col[]"]:checked')
341       .map(function(){ return this.value; }).get();
f52c93 342
T 343   rcmail.set_list_options(cols, sort, ord, thread == 'thread' ? 1 : 0);
344 },
345
4be86f 346 spellmenu: function(show)
A 347 {
348   var link, li,
349     lang = rcmail.spellcheck_lang(),
350     menu = this.popups.spellmenu.obj,
351     ul = $('ul', menu);
352
353   if (!ul.length) {
354     ul = $('<ul>');
355
356     for (i in rcmail.env.spell_langs) {
357       li = $('<li>');
358       link = $('<a href="#">').text(rcmail.env.spell_langs[i])
359         .addClass('active').data('lang', i)
360         .click(function() {
361           rcmail.spellcheck_lang_set($(this).data('lang'));
362         });
363
364       link.appendTo(li);
365       li.appendTo(ul);
366     }
367
368     ul.appendTo(menu);
369   }
370
371   // select current language
372   $('li', ul).each(function() {
373     var el = $('a', this);
374     if (el.data('lang') == lang)
375       el.addClass('selected');
376     else if (el.hasClass('selected'))
377       el.removeClass('selected');
378   });
379
380   this.show_popupmenu('spellmenu', show);
381 },
382
ec581c 383 body_mouseup: function(evt, p)
5f660c 384 {
9e5550 385   var i, target = rcube_event.get_target(evt);
f52c93 386
9e5550 387   for (i in this.popups) {
A 388     if (this.popups[i].obj.is(':visible') && target != rcube_find_object(i+'link')
0e2ccb 389       && !this.popups[i].toggle
9e5550 390       && (!this.popups[i].editable || !this.target_overlaps(target, this.popups[i].id))
A 391       && (!this.popups[i].sticky || !rcube_mouse_is_over(evt, rcube_find_object(this.popups[i].id)))
392     ) {
d145f7 393       window.setTimeout('rcmail_ui.show_popup("'+i+'",false);', 50);
9e5550 394     }
30b152 395   }
087c7d 396 },
A 397
398 target_overlaps: function (target, elementid)
399 {
400   var element = rcube_find_object(elementid);
401   while (target.parentNode) {
402     if (target.parentNode == element)
403       return true;
404     target = target.parentNode;
405   }
406   return false;
5f660c 407 },
A 408
0a36c3 409 body_keydown: function(evt, p)
5f660c 410 {
30b152 411   if (rcube_event.get_keycode(evt) == 27) {
9e5550 412     for (var k in this.popups) {
A 413       if (this.popups[k].obj.is(':visible'))
414         this.show_popup(k, false);
a61bbb 415     }
30b152 416   }
ce06d3 417 },
A 418
419 switch_preview_pane: function(elem)
420 {
421   var uid, prev_frm = $('#mailpreviewframe');
422
423   if (elem.checked) {
424     rcmail.env.contentframe = 'messagecontframe';
425     if (mailviewsplit.layer) {
426       mailviewsplit.resize();
427       mailviewsplit.layer.elm.style.display = '';
129997 428     }
A 429     else
ce06d3 430       mailviewsplit.init();
129997 431
A 432     if (bw.opera) {
433       $('#messagelistcontainer').css({height: ''});
434     }
ce06d3 435     prev_frm.show();
129997 436
ce06d3 437     if (uid = rcmail.message_list.get_single_selection())
A 438       rcmail.show_message(uid, false, true);
129997 439   }
A 440   else {
ce06d3 441     prev_frm.hide();
A 442     if (bw.ie6 || bw.ie7) {
443       var fr = document.getElementById('mailcontframe');
444       fr.style.bottom = 0;
129997 445       fr.style.height = parseInt(fr.parentNode.offsetHeight)+'px';
ce06d3 446     }
129997 447     else {
ce06d3 448       $('#mailcontframe').css({height: 'auto', bottom: 0});
129997 449       if (bw.opera)
A 450         $('#messagelistcontainer').css({height: 'auto'});
451     }
ce06d3 452     if (mailviewsplit.layer)
A 453       mailviewsplit.layer.elm.style.display = 'none';
129997 454
ce06d3 455     rcmail.env.contentframe = null;
A 456     rcmail.show_contentframe(false);
457   }
9b6c82 458
A 459   rcmail.command('save-pref', {name: 'preview_pane', value: (elem.checked?1:0)});
3940ba 460 },
A 461
462 /* Message composing */
463 init_compose_form: function()
464 {
3ee5a7 465   var f, field, fields = ['cc', 'bcc', 'replyto', 'followupto'],
3940ba 466     div = document.getElementById('compose-div'),
A 467     headers_div = document.getElementById('compose-headers-div');
468
e25a35 469   // Show input elements with non-empty value
A 470   for (f=0; f<fields.length; f++) {
471     if ((field = $('#_'+fields[f])) && field.length && field.val() != '')
472       rcmail_ui.show_header_form(fields[f]);
473   }
3940ba 474
A 475   // prevent from form data loss when pressing ESC key in IE
476   if (bw.ie) {
477     var form = rcube_find_object('form');
478     form.onkeydown = function (e) {
479       if (rcube_event.get_keycode(e) == 27)
480         rcube_event.cancel(e);
481     };
482   }
483
484   $(window).resize(function() {
485     rcmail_ui.resize_compose_body();
486   });
487
488   $('#compose-container').resize(function() {
489     rcmail_ui.resize_compose_body();
490   });
491
b218aa 492   div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px';
3940ba 493   $(window).resize();
A 494 },
495
496 resize_compose_body: function()
497 {
b218aa 498   var div = $('#compose-div .boxlistcontent'), w = div.width(), h = div.height();
T 499   w -= 8;  // 2 x 3px padding + 2 x 1px border
500   h -= 4;
3940ba 501
269b14 502   $('#compose-body_tbl').width((w+6)+'px').height('');
R 503   $('#compose-body_ifr').width((w+6)+'px').height((h-54)+'px');
b218aa 504   $('#compose-body').width(w+'px').height(h+'px');
269b14 505   $('#googie_edit_layer').height(h+'px');
7534f6 506 },
A 507
508 resize_compose_body_ev: function()
509 {
510   window.setTimeout(function(){rcmail_ui.resize_compose_body();}, 100);
3940ba 511 },
A 512
513 show_header_form: function(id)
514 {
515   var row, s,
516     link = document.getElementById(id + '-link');
517
518   if ((s = this.next_sibling(link)))
519     s.style.display = 'none';
520   else if ((s = this.prev_sibling(link)))
521     s.style.display = 'none';
522
523   link.style.display = 'none';
524
525   if ((row = document.getElementById('compose-' + id))) {
526     var div = document.getElementById('compose-div'),
527       headers_div = document.getElementById('compose-headers-div');
88b301 528     $(row).show();
b218aa 529     div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px';
3940ba 530     this.resize_compose_body();
A 531   }
532
533   return false;
534 },
535
536 hide_header_form: function(id)
537 {
538   var row, ns,
539     link = document.getElementById(id + '-link'),
540     parent = link.parentNode,
541     links = parent.getElementsByTagName('a');
542
543   link.style.display = '';
544
545   for (var i=0; i<links.length; i++)
546     if (links[i].style.display != 'none')
547       for (var j=i+1; j<links.length; j++)
88b301 548         if (links[j].style.display != 'none')
3940ba 549           if ((ns = this.next_sibling(links[i]))) {
88b301 550             ns.style.display = '';
AM 551             break;
552           }
3940ba 553
A 554   document.getElementById('_' + id).value = '';
555
556   if ((row = document.getElementById('compose-' + id))) {
557     var div = document.getElementById('compose-div'),
558       headers_div = document.getElementById('compose-headers-div');
559     row.style.display = 'none';
560     div.style.top = (parseInt(headers_div.offsetHeight, 10) + 1) + 'px';
561     this.resize_compose_body();
562   }
563
564   return false;
565 },
566
567 next_sibling: function(elm)
568 {
569   var ns = elm.nextSibling;
570   while (ns && ns.nodeType == 3)
571     ns = ns.nextSibling;
572   return ns;
573 },
574
575 prev_sibling: function(elm)
576 {
577   var ps = elm.previousSibling;
578   while (ps && ps.nodeType == 3)
579     ps = ps.previousSibling;
580   return ps;
5f660c 581 }
A 582
583 };
3940ba 584
e97f01 585 /**
A 586  * Scroller
587  */
588
589 function rcmail_scroller(list, top, bottom)
590 {
591   var ref = this;
592
593   this.list = $(list);
594   this.top = $(top);
595   this.bottom = $(bottom);
596   this.step_size = 6;
597   this.step_time = 20;
598   this.delay = 500;
599
600   this.top
601     .mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('down'); }, ref.delay); })
602     .mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
603
604   this.bottom
605     .mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('up'); }, ref.delay); })
606     .mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
607
608   this.scroll = function(dir)
609   {
610     var ref = this, size = this.step_size;
611
612     if (!rcmail.drag_active)
613       return;
614
615     if (dir == 'down')
616       size *= -1;
617
618     this.list.get(0).scrollTop += size;
619     this.ts = window.setTimeout(function() { ref.scroll(dir); }, this.step_time);
620   };
621 };
622
5f660c 623
e2b0a0 624 // Events handling in iframes (eg. preview pane)
A 625 function iframe_events()
626 {
627   // this==iframe
628   var doc = this.contentDocument ? this.contentDocument : this.contentWindow ? this.contentWindow.document : null;
ec581c 629   rcube_event.add_listener({ element: doc, object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
e97f01 630 };
e2b0a0 631
9e1daa 632 // Abbreviate mailbox names to fit width of the container
T 633 function rcube_render_mailboxlist()
634 {
79db33 635   var list = $('#mailboxlist > li a, #mailboxlist ul:visible > li a');
A 636
637   // it's too slow with really big number of folders, especially on IE
9de86a 638   if (list.length > (bw.ie ? 25 : 100))
9e1daa 639     return;
T 640
79db33 641   list.each(function(){
A 642     var elem = $(this),
643       text = elem.data('text');
644
9e1daa 645     if (!text) {
T 646       text = elem.text().replace(/\s+\(.+$/, '');
647       elem.data('text', text);
648     }
649     if (text.length < 6)
650       return;
651
652     var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width());
653     if (abbrev != text)
654       elem.attr('title', text);
655     elem.contents().filter(function(){ return (this.nodeType == 3); }).get(0).data = abbrev;
656   });
e97f01 657 };
9e1daa 658
T 659 // inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5
660 function fit_string_to_size(str, elem, len)
661 {
79db33 662   var w, span, result = str, ellip = '...';
9e1daa 663
79db33 664   if (!rcmail.env.tmp_span) {
A 665     // it should be appended to elem to use the same css style
666     // but for performance reasons we'll append it to body (once)
667     span = $('<b>').css({visibility: 'hidden', padding: '0px'})
668       .appendTo($('body', document)).get(0);
669     rcmail.env.tmp_span = span;
670   }
671   else {
672     span = rcmail.env.tmp_span;
673   }
674   span.innerHTML = result;
9e1daa 675
79db33 676   // on first run, check if string fits into the length already.
A 677   w = span.offsetWidth;
678   if (w > len) {
679     var cut = Math.max(1, Math.floor(str.length * ((w - len) / w) / 2)),
680       mid = Math.floor(str.length / 2),
681       offLeft = mid,
682       offRight = mid;
9e1daa 683
79db33 684     while (true) {
A 685       offLeft = mid - cut;
686       offRight = mid + cut;
687       span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight);
9e1daa 688
79db33 689       // break loop if string fits size
A 690       if (offLeft < 3 || span.offsetWidth)
691         break;
692
693       cut++;
9e1daa 694     }
79db33 695
A 696     // build resulting string
697     result = str.substring(0,offLeft) + ellip + str.substring(offRight);
698   }
699
700   return result;
e97f01 701 };
90550b 702
2c1937 703 function update_quota(data)
A 704 {
705   percent_indicator(rcmail.gui_objects.quotadisplay, data);
e97f01 706 };
2c1937 707
A 708 // percent (quota) indicator
709 function percent_indicator(obj, data)
710 {
711   if (!data || !obj)
712     return false;
713
714   var limit_high = 80,
715     limit_mid  = 55,
716     width = data.width ? data.width : rcmail.env.indicator_width ? rcmail.env.indicator_width : 100,
717     height = data.height ? data.height : rcmail.env.indicator_height ? rcmail.env.indicator_height : 14,
718     quota = data.percent ? Math.abs(parseInt(data.percent)) : 0,
719     quota_width = parseInt(quota / 100 * width),
720     pos = $(obj).position();
721
722   // workarounds for Opera and Webkit bugs
723   pos.top = Math.max(0, pos.top);
724   pos.left = Math.max(0, pos.left);
725
726   rcmail.env.indicator_width = width;
727   rcmail.env.indicator_height = height;
728
729   // overlimit
730   if (quota_width > width) {
731     quota_width = width;
732     quota = 100;
733   }
734
735   if (data.title)
736     data.title = rcmail.get_label('quota') + ': ' +  data.title;
737
738   // main div
739   var main = $('<div>');
740   main.css({position: 'absolute', top: pos.top, left: pos.left,
741       width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'})
742     .attr('title', data.title).addClass('quota_text').html(quota + '%');
743   // used bar
744   var bar1 = $('<div>');
745   bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
746       width: quota_width + 'px', height: height + 'px', zIndex: 99});
747   // background
748   var bar2 = $('<div>');
749   bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
750       width: width + 'px', height: height + 'px', zIndex: 98})
751     .addClass('quota_bg');
752
753   if (quota >= limit_high) {
754     main.addClass(' quota_text_high');
755     bar1.addClass('quota_high');
756   }
757   else if(quota >= limit_mid) {
758     main.addClass(' quota_text_mid');
759     bar1.addClass('quota_mid');
760   }
761   else {
762     main.addClass(' quota_text_low');
763     bar1.addClass('quota_low');
764   }
765
766   // replace quota image
767   $(obj).html('').append(bar1).append(bar2).append(main);
768   // update #quotaimg title
769   $('#quotaimg').attr('title', data.title);
e97f01 770 };
2c1937 771
90550b 772 // Optional parameters used by TinyMCE
V 773 var rcmail_editor_settings = {
774   skin : "default", // "default", "o2k7"
775   skin_variant : "" // "", "silver", "black"
776 };
2c1937 777
A 778 var rcmail_ui;
779
780 function rcube_init_mail_ui()
781 {
782   rcmail_ui = new rcube_mail_ui();
783   rcube_event.add_listener({ object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
784   rcube_event.add_listener({ object:rcmail_ui, method:'body_keydown', event:'keydown' });
785
786   if (rcmail.env.quota_content)
787     update_quota(rcmail.env.quota_content);
788   rcmail.addEventListener('setquota', update_quota);
789
790   $('iframe').load(iframe_events)
791     .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});
792
793   if (rcmail.env.task == 'mail') {
794     rcmail.addEventListener('menu-open', 'open_listmenu', rcmail_ui);
795     rcmail.addEventListener('menu-save', 'save_listmenu', rcmail_ui);
796     rcmail.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui);
797     rcmail.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui);
798     rcmail.gui_object('message_dragmenu', 'dragmessagemenu');
799
800     if (rcmail.gui_objects.mailboxlist) {
801       rcmail.addEventListener('responseaftermark', rcube_render_mailboxlist);
802       rcmail.addEventListener('responseaftergetunread', rcube_render_mailboxlist);
803       rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist);
804       rcmail.addEventListener('aftercollapse-folder', rcube_render_mailboxlist);
e97f01 805
A 806       new rcmail_scroller('#mailboxlist-content', '#mailboxlist-title', '#mailboxlist-footer');
2c1937 807     }
A 808
809     if (rcmail.env.action == 'compose')
810       rcmail_ui.init_compose_form();
811   }
812   else if (rcmail.env.task == 'addressbook') {
813     rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); });
e97f01 814
A 815     if (rcmail.gui_objects.folderlist)
816       new rcmail_scroller('#directorylist-content', '#directorylist-title', '#directorylist-footer');
817   }
818   else if (rcmail.env.task == 'settings') {
819     if (rcmail.gui_objects.subscriptionlist)
820       new rcmail_scroller('#folderlist-content', '#folderlist-title', '#folderlist-footer');
2c1937 821   }
A 822 }