Mercurial > hg > rc1
comparison skins/classic/functions.js @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:50:29 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e000243b222 |
---|---|
1 /** | |
2 * Roundcube functions for default skin interface | |
3 * | |
4 * @licstart The following is the entire license notice for the | |
5 * JavaScript code in this file. | |
6 * | |
7 * Copyright (c) 2006-2014, The Roundcube Dev Team | |
8 * | |
9 * The JavaScript code in this page is free software: you can redistribute it | |
10 * and/or modify it under the terms of the GNU General Public License | |
11 * as published by the Free Software Foundation, either version 3 of | |
12 * the License, or (at your option) any later version. | |
13 * | |
14 * @licend The above is the entire license notice | |
15 * for the JavaScript code in this file. | |
16 */ | |
17 | |
18 /** | |
19 * Settings | |
20 */ | |
21 | |
22 function rcube_init_settings_tabs() | |
23 { | |
24 var el, cl, container = $('#tabsbar'), | |
25 last_tab = $('span:last', container), | |
26 tab = '#settingstabpreferences', | |
27 action = window.rcmail && rcmail.env.action ? rcmail.env.action : null; | |
28 | |
29 // move About tab to the end | |
30 if (last_tab && last_tab.attr('id') != 'settingstababout' && (el = $('#settingstababout'))) { | |
31 cl = el.clone(true); | |
32 el.remove(); | |
33 last_tab.after(cl); | |
34 } | |
35 | |
36 // get selected tab | |
37 if (action) | |
38 tab = '#settingstab' + (action.indexOf('identity')>0 ? 'identities' : action.replace(/\./g, '')); | |
39 | |
40 $(tab).addClass('tablink-selected'); | |
41 $('a', tab).removeAttr('onclick').click(function() { return false; }); | |
42 } | |
43 | |
44 // Fieldsets-to-tabs converter | |
45 // Warning: don't place "caller" <script> inside page element (id) | |
46 function rcube_init_tabs(id, current) | |
47 { | |
48 var content = $('#'+id), | |
49 fs = content.children('fieldset'); | |
50 | |
51 if (!fs.length) | |
52 return; | |
53 | |
54 current = current ? current : 0; | |
55 | |
56 // first hide not selected tabs | |
57 fs.each(function(idx) { if (idx != current) $(this).hide(); }); | |
58 | |
59 // create tabs container | |
60 var tabs = $('<div>').addClass('tabsbar').appendTo(content); | |
61 | |
62 // convert fildsets into tabs | |
63 fs.each(function(idx) { | |
64 var tab, a, elm = $(this), legend = elm.children('legend'); | |
65 | |
66 // create a tab | |
67 a = $('<a>').text(legend.text()).attr('href', '#'); | |
68 tab = $('<span>').attr({'id': 'tab'+idx, 'class': 'tablink'}) | |
69 .click(function() { rcube_show_tab(id, idx); return false }) | |
70 | |
71 // remove legend | |
72 legend.remove(); | |
73 // style fieldset | |
74 elm.addClass('tabbed'); | |
75 // style selected tab | |
76 if (idx == current) | |
77 tab.addClass('tablink-selected'); | |
78 | |
79 // add the tab to container | |
80 tab.append(a).appendTo(tabs); | |
81 }); | |
82 } | |
83 | |
84 function rcube_show_tab(id, index) | |
85 { | |
86 var fs = $('#'+id).children('fieldset'); | |
87 | |
88 fs.each(function(idx) { | |
89 // Show/hide fieldset (tab content) | |
90 $(this)[index==idx ? 'show' : 'hide'](); | |
91 // Select/unselect tab | |
92 $('#tab'+idx).toggleClass('tablink-selected', idx==index); | |
93 }); | |
94 } | |
95 | |
96 /** | |
97 * Mail UI | |
98 */ | |
99 | |
100 function rcube_mail_ui() | |
101 { | |
102 this.popups = { | |
103 markmenu: {id:'markmessagemenu'}, | |
104 replyallmenu: {id:'replyallmenu'}, | |
105 forwardmenu: {id:'forwardmenu', editable:1}, | |
106 searchmenu: {id:'searchmenu', editable:1}, | |
107 messagemenu: {id:'messagemenu'}, | |
108 attachmentmenu: {id:'attachmentmenu'}, | |
109 dragmenu: {id:'dragmenu', sticky:1}, | |
110 groupmenu: {id:'groupoptionsmenu', above:1}, | |
111 mailboxmenu: {id:'mailboxoptionsmenu', above:1}, | |
112 composemenu: {id:'composeoptionsmenu', editable:1, overlap:1}, | |
113 spellmenu: {id:'spellmenu'}, | |
114 responsesmenu: {id:'responsesmenu'}, | |
115 // toggle: #1486823, #1486930 | |
116 uploadmenu: {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux }, | |
117 uploadform: {id:'upload-form', editable:1, toggle:!bw.ie&&!bw.linux } | |
118 }; | |
119 | |
120 var obj; | |
121 for (var k in this.popups) { | |
122 obj = $('#'+this.popups[k].id) | |
123 if (obj.length) | |
124 this.popups[k].obj = obj; | |
125 else { | |
126 delete this.popups[k]; | |
127 } | |
128 } | |
129 } | |
130 | |
131 rcube_mail_ui.prototype = { | |
132 | |
133 show_popup: function(popup, show, config) | |
134 { | |
135 var obj; | |
136 // auto-register menu object | |
137 if (!this.popups[popup] && (obj = $('#'+popup)) && obj.length) | |
138 this.popups[popup] = $.extend(config, {id: popup, obj: obj}); | |
139 | |
140 if (typeof this[popup] == 'function') | |
141 return this[popup](show); | |
142 else | |
143 return this.show_popupmenu(popup, show); | |
144 }, | |
145 | |
146 show_popupmenu: function(popup, show) | |
147 { | |
148 var obj = this.popups[popup].obj, | |
149 above = this.popups[popup].above, | |
150 ref = $(this.popups[popup].link ? this.popups[popup].link : rcube_find_object(popup+'link')); | |
151 | |
152 if (typeof show == 'undefined') | |
153 show = obj.is(':visible') ? false : true; | |
154 else if (this.popups[popup].toggle && show && this.popups[popup].obj.is(':visible') ) | |
155 show = false; | |
156 | |
157 if (show && ref.length) { | |
158 var parent = ref.parent(), | |
159 win = $(window), | |
160 pos = parent.hasClass('dropbutton') ? parent.offset() : ref.offset(); | |
161 | |
162 if (!above && pos.top + ref.height() + obj.height() > win.height()) | |
163 above = true; | |
164 if (pos.left + obj.width() > win.width()) | |
165 pos.left = win.width() - obj.width() - 30; | |
166 | |
167 obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.height())) }); | |
168 } | |
169 | |
170 obj[show?'show':'hide'](); | |
171 }, | |
172 | |
173 dragmenu: function(show) | |
174 { | |
175 this.popups.dragmenu.obj[show?'show':'hide'](); | |
176 }, | |
177 | |
178 forwardmenu: function(show) | |
179 { | |
180 $("input[name='forwardtype'][value="+(rcmail.env.forward_attachment ? 1 : 0)+"]", this.popups.forwardmenu.obj) | |
181 .prop('checked', true); | |
182 this.show_popupmenu('forwardmenu', show); | |
183 }, | |
184 | |
185 uploadmenu: function(show) | |
186 { | |
187 if (typeof show == 'object') // called as event handler | |
188 show = false; | |
189 | |
190 // clear upload form | |
191 if (!show) { | |
192 try { $('#attachment-form form')[0].reset(); } | |
193 catch(e){} // ignore errors | |
194 } | |
195 | |
196 if (rcmail.mailvelope_editor) | |
197 return; | |
198 | |
199 this.show_popupmenu('uploadmenu', show); | |
200 | |
201 if (!document.all && this.popups.uploadmenu.obj.is(':visible')) | |
202 $('#attachment-form input[type=file]').click(); | |
203 }, | |
204 | |
205 searchmenu: function(show) | |
206 { | |
207 var obj = this.popups.searchmenu.obj, | |
208 ref = rcube_find_object('searchmenulink'); | |
209 | |
210 if (typeof show == 'undefined') | |
211 show = obj.is(':visible') ? false : true; | |
212 | |
213 if (show && ref) { | |
214 var pos = $(ref).offset(); | |
215 obj.css({left:pos.left, top:(pos.top + ref.offsetHeight + 2)}); | |
216 | |
217 if (rcmail.env.search_mods) { | |
218 var n, all, | |
219 list = $('input:checkbox[name="s_mods[]"]', obj), | |
220 mbox = rcmail.env.mailbox, | |
221 mods = rcmail.env.search_mods, | |
222 scope = rcmail.env.search_scope || 'base'; | |
223 | |
224 if (rcmail.env.task == 'mail') { | |
225 mods = mods[mbox] ? mods[mbox] : mods['*']; | |
226 all = 'text'; | |
227 $('input:radio[name="s_scope"]').prop('checked', false).filter('#s_scope_'+scope).prop('checked', true); | |
228 } | |
229 else { | |
230 all = '*'; | |
231 } | |
232 | |
233 if (mods[all]) | |
234 list.map(function() { | |
235 this.checked = true; | |
236 this.disabled = this.value != all; | |
237 }); | |
238 else { | |
239 list.prop('disabled', false).prop('checked', false); | |
240 for (n in mods) | |
241 $('#s_mod_' + n).prop('checked', true); | |
242 } | |
243 } | |
244 } | |
245 obj[show?'show':'hide'](); | |
246 }, | |
247 | |
248 set_searchmod: function(elem) | |
249 { | |
250 var all, m, task = rcmail.env.task, | |
251 mods = rcmail.env.search_mods, | |
252 mbox = rcmail.env.mailbox, | |
253 scope = $('input[name="s_scope"]:checked').val(); | |
254 | |
255 if (scope == 'all') | |
256 mbox = '*'; | |
257 | |
258 if (!mods) | |
259 mods = {}; | |
260 | |
261 if (task == 'mail') { | |
262 if (!mods[mbox]) | |
263 mods[mbox] = rcube_clone_object(mods['*']); | |
264 m = mods[mbox]; | |
265 all = 'text'; | |
266 } | |
267 else { //addressbook | |
268 m = mods; | |
269 all = '*'; | |
270 } | |
271 | |
272 if (!elem.checked) | |
273 delete(m[elem.value]); | |
274 else | |
275 m[elem.value] = 1; | |
276 | |
277 // mark all fields | |
278 if (elem.value == all) { | |
279 $('input:checkbox[name="s_mods[]"]').map(function() { | |
280 if (this == elem) | |
281 return; | |
282 | |
283 this.checked = true; | |
284 if (elem.checked) { | |
285 this.disabled = true; | |
286 delete m[this.value]; | |
287 } | |
288 else { | |
289 this.disabled = false; | |
290 m[this.value] = 1; | |
291 } | |
292 }); | |
293 } | |
294 | |
295 rcmail.set_searchmods(m); | |
296 }, | |
297 | |
298 show_listmenu: function(p) | |
299 { | |
300 var self = this, buttons = {}, $dialog = $('#listmenu'); | |
301 | |
302 // close the dialog | |
303 if ($dialog.is(':visible')) { | |
304 $dialog.dialog('close', p.originalEvent); | |
305 return; | |
306 } | |
307 | |
308 // set form values | |
309 $('input[name="sort_col"][value="'+rcmail.env.sort_col+'"]').prop('checked', true); | |
310 $('input[name="sort_ord"][value="DESC"]').prop('checked', rcmail.env.sort_order == 'DESC'); | |
311 $('input[name="sort_ord"][value="ASC"]').prop('checked', rcmail.env.sort_order != 'DESC'); | |
312 $('input[name="view"][value="thread"]').prop('checked', rcmail.env.threading ? true : false); | |
313 $('input[name="view"][value="list"]').prop('checked', rcmail.env.threading ? false : true); | |
314 | |
315 // set checkboxes | |
316 $('input[name="list_col[]"]').each(function() { | |
317 $(this).prop('checked', $.inArray(this.value, rcmail.env.listcols) != -1); | |
318 }); | |
319 | |
320 $.each(['widescreen', 'desktop', 'list'], function() { | |
321 $('input[name="layout"][value="' + this + '"]').prop('checked', rcmail.env.layout == this); | |
322 }); | |
323 $('#listoptions-columns', $dialog)[rcmail.env.layout == 'widescreen' ? 'hide' : 'show'](); | |
324 | |
325 buttons[rcmail.gettext('save')] = function(e) { | |
326 $dialog.dialog('close', e); | |
327 self.save_listmenu(); | |
328 }; | |
329 | |
330 $dialog.dialog({ | |
331 modal: true, | |
332 resizable: false, | |
333 closeOnEscape: true, | |
334 title: null, | |
335 open: function(e) { | |
336 var maxheight = 0; | |
337 $('#listmenu fieldset').each(function() { | |
338 var height = $(this).height(); | |
339 if (height > maxheight) { | |
340 maxheight = height; | |
341 } | |
342 }).css("min-height", maxheight+"px").height(maxheight); | |
343 | |
344 setTimeout(function() { $dialog.find('a, input:not(:disabled)').not('[aria-disabled=true]').first().focus(); }, 100); | |
345 }, | |
346 close: function(e) { | |
347 $dialog.dialog('destroy').hide(); | |
348 if (e.originalEvent && rcube_event.is_keyboard(e.originalEvent)) | |
349 $('#listmenulink').focus(); | |
350 }, | |
351 buttons: buttons, | |
352 minWidth: 500, | |
353 width: $dialog.width()+20 | |
354 }).show(); | |
355 }, | |
356 | |
357 save_listmenu: function() | |
358 { | |
359 var sort = $('input[name="sort_col"]:checked').val(), | |
360 ord = $('input[name="sort_ord"]:checked').val(), | |
361 thread = $('input[name="view"]:checked').val(), | |
362 layout = $('input[name="layout"]:checked').val(), | |
363 cols = $('input[name="list_col[]"]:checked') | |
364 .map(function(){ return this.value; }).get(); | |
365 | |
366 rcmail.set_list_options(cols, sort, ord, thread == 'thread' ? 1 : 0, layout); | |
367 }, | |
368 | |
369 spellmenu: function(show) | |
370 { | |
371 var link, li, | |
372 lang = rcmail.spellcheck_lang(), | |
373 menu = this.popups.spellmenu.obj, | |
374 ul = $('ul', menu); | |
375 | |
376 if (!ul.length) { | |
377 ul = $('<ul>'); | |
378 | |
379 for (i in rcmail.env.spell_langs) { | |
380 li = $('<li>'); | |
381 link = $('<a href="#"></a>').text(rcmail.env.spell_langs[i]) | |
382 .addClass('active').data('lang', i) | |
383 .click(function() { | |
384 rcmail.spellcheck_lang_set($(this).data('lang')); | |
385 }); | |
386 | |
387 link.appendTo(li); | |
388 li.appendTo(ul); | |
389 } | |
390 | |
391 ul.appendTo(menu); | |
392 } | |
393 | |
394 // select current language | |
395 $('li', ul).each(function() { | |
396 var el = $('a', this); | |
397 if (el.data('lang') == lang) | |
398 el.addClass('selected'); | |
399 else if (el.hasClass('selected')) | |
400 el.removeClass('selected'); | |
401 }); | |
402 | |
403 this.show_popupmenu('spellmenu', show); | |
404 }, | |
405 | |
406 show_attachmentmenu: function(elem, event) | |
407 { | |
408 var id = elem.parentNode.id.replace(/^attach/, ''); | |
409 | |
410 $.each(['open', 'download', 'rename'], function() { | |
411 var action = this; | |
412 $('#attachmenu' + action).off('click').attr('onclick', '').click(function(e) { | |
413 return rcmail.command(action + '-attachment', id, this); | |
414 }); | |
415 }); | |
416 | |
417 this.popups.attachmentmenu.link = elem; | |
418 rcmail.command('menu-open', {menu: 'attachmentmenu', id: id}, elem, event); | |
419 }, | |
420 | |
421 menu_open: function(p) | |
422 { | |
423 if (p && p.name == 'messagelistmenu') | |
424 this.show_listmenu(); | |
425 }, | |
426 | |
427 body_mouseup: function(e) | |
428 { | |
429 var target = e.target; ref = this; | |
430 | |
431 $.each(this.popups, function(i, popup) { | |
432 if (popup.obj.is(':visible') && target != rcube_find_object(i + 'link') | |
433 && !popup.toggle | |
434 && target != popup.obj.get(0) // check if scroll bar was clicked (#1489832) | |
435 && (!popup.editable || !ref.target_overlaps(target, popup.id)) | |
436 && (!popup.sticky || !rcube_mouse_is_over(e, rcube_find_object(popup.id))) | |
437 && !$(target).is('.folder-selector-link') && !$(target).children('.folder-selector-link').length | |
438 ) { | |
439 window.setTimeout('rcmail_ui.show_popup("'+i+'",false);', 50); | |
440 } | |
441 }); | |
442 }, | |
443 | |
444 target_overlaps: function (target, elementid) | |
445 { | |
446 var element = rcube_find_object(elementid); | |
447 while (target.parentNode) { | |
448 if (target.parentNode == element) | |
449 return true; | |
450 target = target.parentNode; | |
451 } | |
452 return false; | |
453 }, | |
454 | |
455 body_keydown: function(e) | |
456 { | |
457 if (e.keyCode == 27) { | |
458 for (var k in this.popups) { | |
459 if (this.popups[k].obj.is(':visible')) | |
460 this.show_popup(k, false); | |
461 } | |
462 } | |
463 }, | |
464 | |
465 // Mail view layout initialization and change handler | |
466 set_layout: function(p) | |
467 { | |
468 var layout = p ? p.new_layout : rcmail.env.layout, | |
469 top = $('#mailcontframe'), | |
470 bottom = $('#mailpreviewframe'); | |
471 | |
472 if (p) | |
473 $('#mailrightcontainer').removeClass().addClass(layout); | |
474 | |
475 if (!this.mailviewsplitv) { | |
476 this.mailviewsplitv = new rcube_splitter({id:'mailviewsplitterv', p1: 'mailleftcontainer', p2: 'mailrightcontainer', | |
477 orientation: 'v', relative: true, start: 165, callback: rcube_render_mailboxlist }); | |
478 this.mailviewsplitv.init(); | |
479 } | |
480 | |
481 $('#mailviewsplitter')[layout == 'desktop' ? 'show' : 'hide'](); | |
482 $('#mailviewsplitter2')[layout == 'widescreen' ? 'show' : 'hide'](); | |
483 $('#mailpreviewframe')[layout != 'list' ? 'show' : 'hide'](); | |
484 rcmail.env.contentframe = layout == 'list' ? null : 'messagecontframe'; | |
485 | |
486 if (layout == 'widescreen') { | |
487 $('#countcontrols').detach().appendTo($('#messagelistheader')); | |
488 top.css({height: 'auto', width: 400}); | |
489 bottom.css({top: 0, left: 410, height: 'auto'}).show(); | |
490 if (!this.mailviewsplit2) { | |
491 this.mailviewsplit2 = new rcube_splitter({id:'mailviewsplitter2', p1: 'mailcontframe', p2: 'mailpreviewframe', | |
492 orientation: 'v', relative: true, start: 405}); | |
493 this.mailviewsplit2.init(); | |
494 } | |
495 else | |
496 this.mailviewsplit2.resize(); | |
497 } | |
498 else if (layout == 'desktop') { | |
499 top.css({height: 200, width: '100%'}); | |
500 bottom.css({left: 0, top: 210, height: 'auto'}).show(); | |
501 if (!this.mailviewsplit) { | |
502 this.mailviewsplit = new rcube_splitter({id:'mailviewsplitter', p1: 'mailcontframe', p2: 'mailpreviewframe', | |
503 orientation: 'h', relative: true, start: 205}); | |
504 this.mailviewsplit.init(); | |
505 } | |
506 else | |
507 this.mailviewsplit.resize(); | |
508 } | |
509 else { // layout == 'list' | |
510 top.css({height: 'auto', width: '100%'}); | |
511 bottom.hide(); | |
512 } | |
513 | |
514 if (p && p.old_layout == 'widescreen') { | |
515 $('#countcontrols').detach().appendTo($('#messagelistfooter')); | |
516 } | |
517 }, | |
518 | |
519 | |
520 /* Message composing */ | |
521 init_compose_form: function() | |
522 { | |
523 var f, v, field, fields = ['cc', 'bcc', 'replyto', 'followupto'], | |
524 div = document.getElementById('compose-div'), | |
525 headers_div = document.getElementById('compose-headers-div'); | |
526 | |
527 // Show input elements with non-empty value | |
528 for (f=0; f<fields.length; f++) { | |
529 v = fields[f]; field = $('#_'+v); | |
530 if (field.length) { | |
531 field.on('change', {v:v}, function(e) { if (this.value) rcmail_ui.show_header_form(e.data.v); }); | |
532 if (field.val() != '') | |
533 rcmail_ui.show_header_form(v); | |
534 } | |
535 } | |
536 | |
537 // prevent from form data loss when pressing ESC key in IE | |
538 if (bw.ie) { | |
539 var form = rcube_find_object('form'); | |
540 form.onkeydown = function (e) { | |
541 if (rcube_event.get_keycode(e) == 27) | |
542 rcube_event.cancel(e); | |
543 }; | |
544 } | |
545 | |
546 $(window).resize(function() { | |
547 rcmail_ui.resize_compose_body(); | |
548 }); | |
549 | |
550 $('#compose-container').resize(function() { | |
551 rcmail_ui.resize_compose_body(); | |
552 }); | |
553 | |
554 div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px'; | |
555 $(window).resize(); | |
556 | |
557 // fixes contacts-table position when there's more than one addressbook | |
558 $('#contacts-table').css('top', $('#directorylist').height() + 24 + 'px'); | |
559 | |
560 // contacts search submit | |
561 $('#quicksearchbox').keydown(function(e) { | |
562 if (rcube_event.get_keycode(e) == 13) | |
563 rcmail.command('search'); | |
564 }); | |
565 }, | |
566 | |
567 resize_compose_body: function() | |
568 { | |
569 var div = $('#compose-div .boxlistcontent'), | |
570 w = div.width() - 6, | |
571 h = div.height() - 2, | |
572 x = bw.ie || bw.opera ? 4 : 0; | |
573 | |
574 $('#compose-body_ifr').width(w + 6).height(h - 1 - $('div.mce-toolbar').height()); | |
575 $('#compose-body').width(w-x).height(h); | |
576 $('#googie_edit_layer').width(w).height(h); | |
577 }, | |
578 | |
579 resize_compose_body_ev: function() | |
580 { | |
581 window.setTimeout(function(){rcmail_ui.resize_compose_body();}, 100); | |
582 }, | |
583 | |
584 show_header_form: function(id) | |
585 { | |
586 var row, s, | |
587 link = document.getElementById(id + '-link'); | |
588 | |
589 if ((s = this.next_sibling(link))) | |
590 s.style.display = 'none'; | |
591 else if ((s = this.prev_sibling(link))) | |
592 s.style.display = 'none'; | |
593 | |
594 link.style.display = 'none'; | |
595 | |
596 if ((row = document.getElementById('compose-' + id))) { | |
597 var div = document.getElementById('compose-div'), | |
598 headers_div = document.getElementById('compose-headers-div'); | |
599 $(row).show(); | |
600 div.style.top = (parseInt(headers_div.offsetHeight, 10) + 3) + 'px'; | |
601 this.resize_compose_body(); | |
602 } | |
603 | |
604 return false; | |
605 }, | |
606 | |
607 hide_header_form: function(id) | |
608 { | |
609 var row, ns, | |
610 link = document.getElementById(id + '-link'), | |
611 parent = link.parentNode, | |
612 links = parent.getElementsByTagName('a'); | |
613 | |
614 link.style.display = ''; | |
615 | |
616 for (var i=0; i<links.length; i++) | |
617 if (links[i].style.display != 'none') | |
618 for (var j=i+1; j<links.length; j++) | |
619 if (links[j].style.display != 'none') | |
620 if ((ns = this.next_sibling(links[i]))) { | |
621 ns.style.display = ''; | |
622 break; | |
623 } | |
624 | |
625 document.getElementById('_' + id).value = ''; | |
626 | |
627 if ((row = document.getElementById('compose-' + id))) { | |
628 var div = document.getElementById('compose-div'), | |
629 headers_div = document.getElementById('compose-headers-div'); | |
630 row.style.display = 'none'; | |
631 div.style.top = (parseInt(headers_div.offsetHeight, 10) + 1) + 'px'; | |
632 this.resize_compose_body(); | |
633 } | |
634 | |
635 return false; | |
636 }, | |
637 | |
638 next_sibling: function(elm) | |
639 { | |
640 var ns = elm.nextSibling; | |
641 while (ns && ns.nodeType == 3) | |
642 ns = ns.nextSibling; | |
643 return ns; | |
644 }, | |
645 | |
646 prev_sibling: function(elm) | |
647 { | |
648 var ps = elm.previousSibling; | |
649 while (ps && ps.nodeType == 3) | |
650 ps = ps.previousSibling; | |
651 return ps; | |
652 }, | |
653 | |
654 enable_command: function(p) | |
655 { | |
656 if (p.command == 'reply-list' && rcmail.env.reply_all_mode == 1) { | |
657 var label = rcmail.gettext(p.status ? 'replylist' : 'replyall'); | |
658 $('a.button.replyAll').attr('title', label); | |
659 } | |
660 else if (p.command == 'compose-encrypted') { | |
661 // show the toolbar button for Mailvelope | |
662 $('#messagetoolbar > a.encrypt').show(); | |
663 } | |
664 }, | |
665 | |
666 folder_search_init: function(container) | |
667 { | |
668 // animation to unfold list search box | |
669 $('.boxtitle a.search', container).click(function(e) { | |
670 var title = $('.boxtitle', container), | |
671 box = $('.listsearchbox', container), | |
672 dir = box.is(':visible') ? -1 : 1, | |
673 height = 24 + ($('select', box).length ? 24 : 0); | |
674 | |
675 box.slideToggle({ | |
676 duration: 160, | |
677 progress: function(animation, progress) { | |
678 if (dir < 0) progress = 1 - progress; | |
679 $('.boxlistcontent', container).css('top', (title.outerHeight() + height * progress) + 'px'); | |
680 }, | |
681 complete: function() { | |
682 box.toggleClass('expanded'); | |
683 if (box.is(':visible')) { | |
684 box.find('input[type=text]').focus(); | |
685 } | |
686 else { | |
687 $('a.reset', box).click(); | |
688 } | |
689 // TODO: save state in cookie | |
690 } | |
691 }); | |
692 | |
693 return false; | |
694 }); | |
695 } | |
696 | |
697 }; | |
698 | |
699 /** | |
700 * Roundcube generic layer (floating box) class | |
701 * | |
702 * @constructor | |
703 */ | |
704 function rcube_layer(id, attributes) | |
705 { | |
706 this.name = id; | |
707 | |
708 // create a new layer in the current document | |
709 this.create = function(arg) | |
710 { | |
711 var l = (arg.x) ? arg.x : 0, | |
712 t = (arg.y) ? arg.y : 0, | |
713 w = arg.width, | |
714 h = arg.height, | |
715 z = arg.zindex, | |
716 vis = arg.vis, | |
717 parent = arg.parent, | |
718 obj = document.createElement('DIV'); | |
719 | |
720 obj.id = this.name; | |
721 obj.style.position = 'absolute'; | |
722 obj.style.visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden'; | |
723 obj.style.left = l+'px'; | |
724 obj.style.top = t+'px'; | |
725 if (w) | |
726 obj.style.width = w.toString().match(/\%$/) ? w : w+'px'; | |
727 if (h) | |
728 obj.style.height = h.toString().match(/\%$/) ? h : h+'px'; | |
729 if (z) | |
730 obj.style.zIndex = z; | |
731 | |
732 if (parent) | |
733 parent.appendChild(obj); | |
734 else | |
735 document.body.appendChild(obj); | |
736 | |
737 this.elm = obj; | |
738 }; | |
739 | |
740 // create new layer | |
741 if (attributes != null) { | |
742 this.create(attributes); | |
743 this.name = this.elm.id; | |
744 } | |
745 else // just refer to the object | |
746 this.elm = document.getElementById(id); | |
747 | |
748 if (!this.elm) | |
749 return false; | |
750 | |
751 | |
752 // ********* layer object properties ********* | |
753 | |
754 this.css = this.elm.style; | |
755 this.event = this.elm; | |
756 this.width = this.elm.offsetWidth; | |
757 this.height = this.elm.offsetHeight; | |
758 this.x = parseInt(this.elm.offsetLeft); | |
759 this.y = parseInt(this.elm.offsetTop); | |
760 this.visible = (this.css.visibility=='visible' || this.css.visibility=='show' || this.css.visibility=='inherit') ? true : false; | |
761 | |
762 | |
763 // ********* layer object methods ********* | |
764 | |
765 // move the layer to a specific position | |
766 this.move = function(x, y) | |
767 { | |
768 this.x = x; | |
769 this.y = y; | |
770 this.css.left = Math.round(this.x)+'px'; | |
771 this.css.top = Math.round(this.y)+'px'; | |
772 }; | |
773 | |
774 // change the layers width and height | |
775 this.resize = function(w,h) | |
776 { | |
777 this.css.width = w+'px'; | |
778 this.css.height = h+'px'; | |
779 this.width = w; | |
780 this.height = h; | |
781 }; | |
782 | |
783 // show or hide the layer | |
784 this.show = function(a) | |
785 { | |
786 if(a == 1) { | |
787 this.css.visibility = 'visible'; | |
788 this.visible = true; | |
789 } | |
790 else if(a == 2) { | |
791 this.css.visibility = 'inherit'; | |
792 this.visible = true; | |
793 } | |
794 else { | |
795 this.css.visibility = 'hidden'; | |
796 this.visible = false; | |
797 } | |
798 }; | |
799 | |
800 // write new content into a Layer | |
801 this.write = function(cont) | |
802 { | |
803 this.elm.innerHTML = cont; | |
804 }; | |
805 | |
806 }; | |
807 | |
808 /** | |
809 * Scroller | |
810 * | |
811 * @deprecated Use treelist widget | |
812 */ | |
813 function rcmail_scroller(list, top, bottom) | |
814 { | |
815 var ref = this; | |
816 | |
817 this.list = $(list); | |
818 this.top = $(top); | |
819 this.bottom = $(bottom); | |
820 this.step_size = 6; | |
821 this.step_time = 20; | |
822 this.delay = 500; | |
823 | |
824 this.top | |
825 .mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('down'); }, ref.delay); }) | |
826 .mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); }); | |
827 | |
828 this.bottom | |
829 .mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('up'); }, ref.delay); }) | |
830 .mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); }); | |
831 | |
832 this.scroll = function(dir) | |
833 { | |
834 var ref = this, size = this.step_size; | |
835 | |
836 if (!rcmail.drag_active) | |
837 return; | |
838 | |
839 if (dir == 'down') | |
840 size *= -1; | |
841 | |
842 this.list.get(0).scrollTop += size; | |
843 this.ts = window.setTimeout(function() { ref.scroll(dir); }, this.step_time); | |
844 }; | |
845 }; | |
846 | |
847 // Abbreviate mailbox names to fit width of the container | |
848 function rcube_render_mailboxlist() | |
849 { | |
850 var list = $('#mailboxlist > li > a, #mailboxlist ul:visible > li > a'); | |
851 | |
852 // it's too slow with really big number of folders | |
853 if (list.length > 100) | |
854 return; | |
855 | |
856 list.each(function() { | |
857 var elem = $(this), | |
858 text = elem.data('text'); | |
859 | |
860 if (!text) { | |
861 text = elem.text().replace(/\s+\([0-9]+\)$/, ''); | |
862 elem.data('text', text); | |
863 } | |
864 | |
865 if (text.length < 6) | |
866 return; | |
867 | |
868 var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width() - 16); | |
869 if (abbrev != text) | |
870 elem.attr('title', text); | |
871 elem.contents().filter(function(){ return (this.nodeType == 3); }).get(0).data = abbrev; | |
872 }); | |
873 }; | |
874 | |
875 // inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5 | |
876 function fit_string_to_size(str, elem, len) | |
877 { | |
878 var w, span, $span, result = str, ellip = '...'; | |
879 | |
880 if (!rcmail.env.tmp_span) { | |
881 // it should be appended to elem to use the same css style | |
882 // but for performance reasons we'll append it to body (once) | |
883 span = $('<b>').css({visibility: 'hidden', padding: '0px', | |
884 'font-family': elem.css('font-family'), | |
885 'font-size': elem.css('font-size')}) | |
886 .appendTo($('body', document)).get(0); | |
887 rcmail.env.tmp_span = span; | |
888 } | |
889 else { | |
890 span = rcmail.env.tmp_span; | |
891 } | |
892 | |
893 $span = $(span); | |
894 $span.text(result); | |
895 | |
896 // on first run, check if string fits into the length already. | |
897 w = span.offsetWidth; | |
898 if (w > len) { | |
899 var cut = Math.max(1, Math.floor(str.length * ((w - len) / w) / 2)), | |
900 mid = Math.floor(str.length / 2), | |
901 offLeft = mid, | |
902 offRight = mid; | |
903 | |
904 while (true) { | |
905 offLeft = mid - cut; | |
906 offRight = mid + cut; | |
907 $span.text(str.substring(0,offLeft) + ellip + str.substring(offRight)); | |
908 | |
909 // break loop if string fits size | |
910 if (offLeft < 3 || span.offsetWidth) | |
911 break; | |
912 | |
913 cut++; | |
914 } | |
915 | |
916 // build resulting string | |
917 result = str.substring(0,offLeft) + ellip + str.substring(offRight); | |
918 } | |
919 | |
920 return result; | |
921 }; | |
922 | |
923 function update_quota(data) | |
924 { | |
925 percent_indicator(rcmail.gui_objects.quotadisplay, data); | |
926 | |
927 if (data.table) { | |
928 var menu = $('#quotamenu'); | |
929 | |
930 if (!menu.length) | |
931 menu = $('<div id="quotamenu" class="popupmenu">').appendTo($('body')); | |
932 | |
933 menu.html(data.table); | |
934 $('#quotaimg').css('cursor', 'pointer').off('click').on('click', function(e) { | |
935 return rcmail.command('menu-open', 'quotamenu', e.target, e); | |
936 }); | |
937 } | |
938 }; | |
939 | |
940 // percent (quota) indicator | |
941 function percent_indicator(obj, data) | |
942 { | |
943 if (!data || !obj) | |
944 return false; | |
945 | |
946 var limit_high = 80, | |
947 limit_mid = 55, | |
948 width = data.width ? data.width : rcmail.env.indicator_width ? rcmail.env.indicator_width : 100, | |
949 height = data.height ? data.height : rcmail.env.indicator_height ? rcmail.env.indicator_height : 14, | |
950 quota = data.percent ? Math.abs(parseInt(data.percent)) : 0, | |
951 quota_width = parseInt(quota / 100 * width), | |
952 pos = $(obj).position(); | |
953 | |
954 // workarounds for Opera and Webkit bugs | |
955 pos.top = Math.max(0, pos.top); | |
956 pos.left = Math.max(0, pos.left); | |
957 | |
958 rcmail.env.indicator_width = width; | |
959 rcmail.env.indicator_height = height; | |
960 | |
961 // overlimit | |
962 if (quota_width > width) { | |
963 quota_width = width; | |
964 quota = 100; | |
965 } | |
966 | |
967 if (data.title) | |
968 data.title = rcmail.get_label('quota') + ': ' + data.title; | |
969 | |
970 // main div | |
971 var main = $('<div>'); | |
972 main.css({position: 'absolute', top: pos.top, left: pos.left, | |
973 width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'}) | |
974 .attr('title', data.title).addClass('quota_text').html(quota + '%'); | |
975 // used bar | |
976 var bar1 = $('<div>'); | |
977 bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1, | |
978 width: quota_width + 'px', height: height + 'px', zIndex: 99}); | |
979 // background | |
980 var bar2 = $('<div>'); | |
981 bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1, | |
982 width: width + 'px', height: height + 'px', zIndex: 98}) | |
983 .addClass('quota_bg'); | |
984 | |
985 if (quota >= limit_high) { | |
986 main.addClass(' quota_text_high'); | |
987 bar1.addClass('quota_high'); | |
988 } | |
989 else if(quota >= limit_mid) { | |
990 main.addClass(' quota_text_mid'); | |
991 bar1.addClass('quota_mid'); | |
992 } | |
993 else { | |
994 main.addClass(' quota_text_low'); | |
995 bar1.addClass('quota_low'); | |
996 } | |
997 | |
998 // replace quota image | |
999 $(obj).html('').append(bar1).append(bar2).append(main); | |
1000 // update #quotaimg title | |
1001 $('#quotaimg').attr('title', data.title); | |
1002 }; | |
1003 | |
1004 function attachment_menu_append(item) | |
1005 { | |
1006 $(item).append( | |
1007 $('<a class="drop"></a>').on('click keypress', function(e) { | |
1008 if (e.type != 'keypress' || e.which == 13) { | |
1009 rcmail_ui.show_attachmentmenu(this, e); | |
1010 return false; | |
1011 } | |
1012 }) | |
1013 ); | |
1014 }; | |
1015 | |
1016 // Optional parameters used by TinyMCE | |
1017 var rcmail_editor_settings = {}; | |
1018 | |
1019 var rcmail_ui; | |
1020 | |
1021 function rcube_init_mail_ui() | |
1022 { | |
1023 rcmail_ui = new rcube_mail_ui(); | |
1024 | |
1025 $(document.body).mouseup(function(e) { rcmail_ui.body_mouseup(e); }) | |
1026 .mousedown(function(e) { rcmail_ui.body_keydown(e); }); | |
1027 | |
1028 rcmail.addEventListener('init', function() { | |
1029 if (rcmail.env.quota_content) | |
1030 update_quota(rcmail.env.quota_content); | |
1031 rcmail.addEventListener('setquota', update_quota); | |
1032 | |
1033 rcube_webmail.set_iframe_events({mouseup: function(e) { return rcmail_ui.body_mouseup(e); }}); | |
1034 | |
1035 if (rcmail.env.task == 'mail') { | |
1036 rcmail.addEventListener('enable-command', 'enable_command', rcmail_ui) | |
1037 .addEventListener('menu-open', 'menu_open', rcmail_ui) | |
1038 .addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui) | |
1039 .addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui) | |
1040 .gui_object('dragmenu', 'dragmenu'); | |
1041 | |
1042 if (rcmail.gui_objects.mailboxlist) { | |
1043 rcmail.treelist.addEventListener('expand', rcube_render_mailboxlist); | |
1044 rcmail.addEventListener('responseaftermark', rcube_render_mailboxlist) | |
1045 .addEventListener('responseaftergetunread', rcube_render_mailboxlist) | |
1046 .addEventListener('responseaftercheck-recent', rcube_render_mailboxlist) | |
1047 .addEventListener('responseafterrefresh', rcube_render_mailboxlist) | |
1048 .addEventListener('afterimport-messages', function(){ rcmail_ui.show_popup('uploadform', false); }); | |
1049 } | |
1050 | |
1051 rcmail.init_pagejumper('#pagejumper'); | |
1052 | |
1053 // fix message list header on window resize (#1490213) | |
1054 if (bw.ie && rcmail.message_list) | |
1055 $(window).resize(function() { | |
1056 setTimeout(function() { rcmail.message_list.resize(); }, 10); | |
1057 }); | |
1058 | |
1059 if (rcmail.env.action == 'list' || !rcmail.env.action) { | |
1060 rcmail.addEventListener('layout-change', 'set_layout', rcmail_ui); | |
1061 rcmail_ui.set_layout(); | |
1062 } | |
1063 else if (rcmail.env.action == 'compose') { | |
1064 rcmail_ui.init_compose_form(); | |
1065 rcmail.addEventListener('compose-encrypted', function(e) { | |
1066 $("a.button.encrypt")[(e.active ? 'addClass' : 'removeClass')]('selected'); | |
1067 $("select[name='editorSelector']").prop('disabled', e.active); | |
1068 $('a.button.attach, a.button.responses, a.button.attach, #uploadmenulink')[(e.active ? 'addClass' : 'removeClass')]('buttonPas disabled'); | |
1069 $('#responseslist a.insertresponse')[(e.active ? 'removeClass' : 'addClass')]('active'); | |
1070 }); | |
1071 rcmail.addEventListener('fileappended', function(e) { | |
1072 if (e.attachment.complete) | |
1073 attachment_menu_append(e.item); | |
1074 }); | |
1075 | |
1076 // add menu link for each attachment | |
1077 $('#attachmentslist > li').each(function() { | |
1078 attachment_menu_append(this); | |
1079 }); | |
1080 } | |
1081 else if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') { | |
1082 // add menu link for each attachment | |
1083 $('#attachment-list > li[id^="attach"]').each(function() { | |
1084 attachment_menu_append(this); | |
1085 }); | |
1086 | |
1087 $(window).resize(function() { | |
1088 if (!$('#attachment-list > li[id^="attach"]').length) | |
1089 $('#attachment-list').hide(); | |
1090 | |
1091 var mvlpe = $('#messagebody.mailvelope'); | |
1092 if (mvlpe.length) { | |
1093 var content = $('#messageframe'), | |
1094 h = (content.length ? content.height() + content.offset().top - 25 : $(this).height()) - mvlpe.offset().top - 20; | |
1095 mvlpe.height(h); | |
1096 } | |
1097 }); | |
1098 } | |
1099 } | |
1100 else if (rcmail.env.task == 'addressbook') { | |
1101 rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); }) | |
1102 .gui_object('dragmenu', 'dragmenu'); | |
1103 } | |
1104 else if (rcmail.env.task == 'settings') { | |
1105 if (rcmail.env.action == 'folders') { | |
1106 rcmail_ui.folder_search_init($('#folder-manager')); | |
1107 } | |
1108 } | |
1109 }); | |
1110 } |