1 /* (Manage)Sieve Filters */
4 rcmail.addEventListener('init', function(evt) {
5 // add managesieve-create command to message_commands array,
6 // so it's state will be updated on message selection/unselection
7 if (rcmail.env.task == 'mail') {
8 if (rcmail.env.action != 'show')
9 rcmail.env.message_commands.push('managesieve-create');
11 rcmail.enable_command('managesieve-create', true);
14 var tab = $('<span>').attr('id', 'settingstabpluginmanagesieve').addClass('tablink'),
15 button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.managesieve')
16 .attr('title', rcmail.gettext('managesieve.managefilters'))
17 .html(rcmail.gettext('managesieve.filters'))
21 rcmail.add_element(tab, 'tabs');
24 if (rcmail.env.task == 'mail' || rcmail.env.action.indexOf('plugin.managesieve') != -1) {
25 // Create layer for form tips
26 if (!rcmail.env.framed) {
27 rcmail.env.ms_tip_layer = $('<div id="managesieve-tip" class="popupmenu"></div>');
28 rcmail.env.ms_tip_layer.appendTo(document.body);
33 rcmail.register_command('plugin.managesieve-save', function() { rcmail.managesieve_save() });
34 rcmail.register_command('plugin.managesieve-act', function() { rcmail.managesieve_act() });
35 rcmail.register_command('plugin.managesieve-add', function() { rcmail.managesieve_add() });
36 rcmail.register_command('plugin.managesieve-del', function() { rcmail.managesieve_del() });
37 rcmail.register_command('plugin.managesieve-move', function() { rcmail.managesieve_move() });
38 rcmail.register_command('plugin.managesieve-setadd', function() { rcmail.managesieve_setadd() });
39 rcmail.register_command('plugin.managesieve-setdel', function() { rcmail.managesieve_setdel() });
40 rcmail.register_command('plugin.managesieve-setact', function() { rcmail.managesieve_setact() });
41 rcmail.register_command('plugin.managesieve-setget', function() { rcmail.managesieve_setget() });
43 if (rcmail.env.action == 'plugin.managesieve' || rcmail.env.action == 'plugin.managesieve-save') {
44 if (rcmail.gui_objects.sieveform) {
45 rcmail.enable_command('plugin.managesieve-save', true);
47 // small resize for header element
48 $('select[name="_header[]"]', rcmail.gui_objects.sieveform).each(function() {
49 if (this.value == '...') this.style.width = '40px';
52 // resize dialog window
53 if (rcmail.env.action == 'plugin.managesieve' && rcmail.env.task == 'mail') {
54 parent.rcmail.managesieve_dialog_resize(rcmail.gui_objects.sieveform);
57 $('input[type="text"]:first', rcmail.gui_objects.sieveform).focus();
60 rcmail.enable_command('plugin.managesieve-add', 'plugin.managesieve-setadd', !rcmail.env.sieveconnerror);
63 var i, p = rcmail, setcnt, set = rcmail.env.currentset;
65 if (rcmail.gui_objects.filterslist) {
66 rcmail.filters_list = new rcube_list_widget(rcmail.gui_objects.filterslist,
67 {multiselect:false, draggable:true, keyboard:false});
68 rcmail.filters_list.addEventListener('select', function(e) { p.managesieve_select(e); });
69 rcmail.filters_list.addEventListener('dragstart', function(e) { p.managesieve_dragstart(e); });
70 rcmail.filters_list.addEventListener('dragend', function(e) { p.managesieve_dragend(e); });
71 rcmail.filters_list.row_init = function (row) {
72 row.obj.onmouseover = function() { p.managesieve_focus_filter(row); };
73 row.obj.onmouseout = function() { p.managesieve_unfocus_filter(row); };
75 rcmail.filters_list.init();
76 rcmail.filters_list.focus();
79 if (rcmail.gui_objects.filtersetslist) {
80 rcmail.filtersets_list = new rcube_list_widget(rcmail.gui_objects.filtersetslist, {multiselect:false, draggable:false, keyboard:false});
81 rcmail.filtersets_list.addEventListener('select', function(e) { p.managesieve_setselect(e); });
82 rcmail.filtersets_list.init();
83 rcmail.filtersets_list.focus();
86 set = rcmail.managesieve_setid(set);
87 rcmail.filtersets_list.shift_start = set;
88 rcmail.filtersets_list.highlight_row(set, false);
91 setcnt = rcmail.filtersets_list.rowcount;
92 rcmail.enable_command('plugin.managesieve-set', true);
93 rcmail.enable_command('plugin.managesieve-setact', 'plugin.managesieve-setget', setcnt);
94 rcmail.enable_command('plugin.managesieve-setdel', setcnt > 1);
96 // Fix dragging filters over sets list
97 $('tr', rcmail.gui_objects.filtersetslist).each(function (i, e) { p.managesieve_fixdragend(e); });
100 if (rcmail.gui_objects.sieveform && rcmail.env.rule_disabled)
101 $('#disabled').attr('checked', true);
105 /*********************************************************/
106 /********* Managesieve UI methods *********/
107 /*********************************************************/
109 rcube_webmail.prototype.managesieve_add = function()
111 this.load_managesieveframe();
112 this.filters_list.clear_selection();
115 rcube_webmail.prototype.managesieve_del = function()
117 var id = this.filters_list.get_single_selection();
118 if (confirm(this.get_label('managesieve.filterdeleteconfirm'))) {
119 var lock = this.set_busy(true, 'loading');
120 this.http_post('plugin.managesieve',
121 '_act=delete&_fid='+this.filters_list.rows[id].uid, lock);
125 rcube_webmail.prototype.managesieve_act = function()
127 var id = this.filters_list.get_single_selection(),
128 lock = this.set_busy(true, 'loading');
130 this.http_post('plugin.managesieve',
131 '_act=act&_fid='+this.filters_list.rows[id].uid, lock);
135 rcube_webmail.prototype.managesieve_select = function(list)
137 var id = list.get_single_selection();
139 this.load_managesieveframe(list.rows[id].uid);
143 rcube_webmail.prototype.managesieve_setselect = function(list)
145 this.show_contentframe(false);
146 this.filters_list.clear(true);
147 this.enable_command('plugin.managesieve-setdel', list.rowcount > 1);
148 this.enable_command( 'plugin.managesieve-setact', 'plugin.managesieve-setget', true);
150 var id = list.get_single_selection();
152 this.managesieve_list(this.env.filtersets[id]);
155 rcube_webmail.prototype.managesieve_rowid = function(id)
157 var i, rows = this.filters_list.rows;
159 for (i=0; i<rows.length; i++)
160 if (rows[i] != null && rows[i].uid == id)
164 // Returns set's identifier
165 rcube_webmail.prototype.managesieve_setid = function(name)
167 for (var i in this.env.filtersets)
168 if (this.env.filtersets[i] == name)
172 // Filters listing request
173 rcube_webmail.prototype.managesieve_list = function(script)
175 var lock = this.set_busy(true, 'loading');
177 this.http_post('plugin.managesieve', '_act=list&_set='+urlencode(script), lock);
180 // Script download request
181 rcube_webmail.prototype.managesieve_setget = function()
183 var id = this.filtersets_list.get_single_selection(),
184 script = this.env.filtersets[id];
186 location.href = this.env.comm_path+'&_action=plugin.managesieve&_act=setget&_set='+urlencode(script);
189 // Set activate/deactivate request
190 rcube_webmail.prototype.managesieve_setact = function()
192 var id = this.filtersets_list.get_single_selection(),
193 lock = this.set_busy(true, 'loading'),
194 script = this.env.filtersets[id],
195 action = $('#rcmrow'+id).hasClass('disabled') ? 'setact' : 'deact';
197 this.http_post('plugin.managesieve', '_act='+action+'&_set='+urlencode(script), lock);
200 // Set delete request
201 rcube_webmail.prototype.managesieve_setdel = function()
203 if (!confirm(this.get_label('managesieve.setdeleteconfirm')))
206 var id = this.filtersets_list.get_single_selection(),
207 lock = this.set_busy(true, 'loading'),
208 script = this.env.filtersets[id];
210 this.http_post('plugin.managesieve', '_act=setdel&_set='+urlencode(script), lock);
214 rcube_webmail.prototype.managesieve_setadd = function()
216 this.filters_list.clear_selection();
217 this.enable_command('plugin.managesieve-act', 'plugin.managesieve-del', false);
219 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) {
220 var lock = this.set_busy(true, 'loading');
221 target = window.frames[this.env.contentframe];
222 target.location.href = this.env.comm_path+'&_action=plugin.managesieve&_framed=1&_newset=1&_unlock='+lock;
226 rcube_webmail.prototype.managesieve_updatelist = function(action, o)
234 var i, list = this.filters_list, rows = list.rows;
236 list.remove_row(this.managesieve_rowid(o.id));
237 list.clear_selection();
238 this.show_contentframe(false);
239 this.enable_command('plugin.managesieve-del', 'plugin.managesieve-act', false);
241 // re-numbering filters
242 for (i=0; i<rows.length; i++) {
243 if (rows[i] != null && rows[i].uid > o.id)
244 rows[i].uid = rows[i].uid-1;
251 var i, row = $('#rcmrow'+o.id);
254 $('td', row).html(o.name);
256 row.addClass('disabled');
258 row.removeClass('disabled');
260 $('#disabled', $('iframe').contents()).prop('checked', o.disabled);
264 // Add filter row to the list
266 var list = this.filters_list,
267 row = $('<tr><td class="name"></td></tr>');
269 $('td', row).html(o.name);
270 row.attr('id', 'rcmrow'+o.id);
272 row.addClass('disabled');
274 list.insert_row(row.get(0));
275 list.highlight_row(o.id);
277 this.enable_command('plugin.managesieve-del', 'plugin.managesieve-act', true);
281 // Filling rules list
283 var i, tr, td, el, list = this.filters_list;
290 tr = document.createElement('TR');
291 td = document.createElement('TD');
293 td.innerHTML = el.name;
294 td.className = 'name';
295 tr.id = 'rcmrow' + el.id;
297 tr.className = el['class'];
304 list.highlight_row(o.set);
306 this.enable_command('plugin.managesieve-del', 'plugin.managesieve-act', false);
310 // Sactivate/deactivate set
312 var id = this.managesieve_setid(o.name), row = $('#rcmrow' + id);
315 $('tr', this.gui_objects.filtersetslist).addClass('disabled');
316 row.removeClass('disabled');
319 row.addClass('disabled');
325 var id = this.managesieve_setid(o.name);
327 this.filtersets_list.remove_row(id);
328 this.filters_list.clear();
329 this.show_contentframe(false);
330 this.enable_command('plugin.managesieve-setdel', 'plugin.managesieve-setact', 'plugin.managesieve-setget', false);
332 delete this.env.filtersets[id];
338 var id = 'S' + new Date().getTime(),
339 list = this.filtersets_list,
340 row = $('<tr class="disabled"><td class="name"></td></tr>');
342 $('td', row).html(o.name);
343 row.attr('id', 'rcmrow'+id);
345 this.env.filtersets[id] = o.name;
346 list.insert_row(row.get(0));
348 // move row into its position on the list
349 if (o.index != list.rowcount-1) {
351 var elem = $('tr:visible', list.list).get(o.index);
352 row.insertBefore(elem);
357 // Fix dragging filters over sets list
358 this.managesieve_fixdragend(row);
363 this.set_busy(false);
367 rcube_webmail.prototype.load_managesieveframe = function(id)
369 var has_id = typeof(id) != 'undefined' && id != null;
370 this.enable_command('plugin.managesieve-act', 'plugin.managesieve-del', has_id);
372 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) {
373 target = window.frames[this.env.contentframe];
374 var msgid = this.set_busy(true, 'loading');
375 target.location.href = this.env.comm_path+'&_action=plugin.managesieve&_framed=1'
376 +(id ? '&_fid='+id : '')+'&_unlock='+msgid;
381 rcube_webmail.prototype.managesieve_dragstart = function(list)
383 var id = this.filters_list.get_single_selection();
385 this.drag_active = true;
386 this.drag_filter = id;
389 rcube_webmail.prototype.managesieve_dragend = function(e)
391 if (this.drag_active) {
392 if (this.drag_filter_target) {
393 var lock = this.set_busy(true, 'loading');
395 this.show_contentframe(false);
396 this.http_post('plugin.managesieve', '_act=move&_fid='+this.drag_filter
397 +'&_to='+this.drag_filter_target, lock);
399 this.drag_active = false;
403 // Fixes filters dragging over sets list
404 // @TODO: to be removed after implementing copying filters
405 rcube_webmail.prototype.managesieve_fixdragend = function(elem)
408 $(elem).bind('mouseup' + ((bw.iphone || bw.ipad) ? ' touchend' : ''), function(e) {
410 p.filters_list.drag_mouse_up(e);
414 rcube_webmail.prototype.managesieve_focus_filter = function(row)
416 var id = row.id.replace(/^rcmrow/, '');
417 if (this.drag_active && id != this.drag_filter) {
418 this.drag_filter_target = id;
419 $(row.obj).addClass(id < this.drag_filter ? 'filtermoveup' : 'filtermovedown');
423 rcube_webmail.prototype.managesieve_unfocus_filter = function(row)
425 if (this.drag_active) {
426 $(row.obj).removeClass('filtermoveup filtermovedown');
427 this.drag_filter_target = null;
431 /*********************************************************/
432 /********* Filter Form methods *********/
433 /*********************************************************/
436 rcube_webmail.prototype.managesieve_save = function()
438 if (parent.rcmail && parent.rcmail.filters_list && this.gui_objects.sieveform.name != 'filtersetform') {
439 var id = parent.rcmail.filters_list.get_single_selection();
441 this.gui_objects.sieveform.elements['_fid'].value = parent.rcmail.filters_list.rows[id].uid;
443 this.gui_objects.sieveform.submit();
446 // Operations on filters form
447 rcube_webmail.prototype.managesieve_ruleadd = function(id)
449 this.http_post('plugin.managesieve', '_act=ruleadd&_rid='+id);
452 rcube_webmail.prototype.managesieve_rulefill = function(content, id, after)
455 // create new element
456 var div = document.getElementById('rules'),
457 row = document.createElement('div');
459 this.managesieve_insertrow(div, row, after);
460 // fill row after inserting (for IE)
461 row.setAttribute('id', 'rulerow'+id);
462 row.className = 'rulerow';
463 row.innerHTML = content;
465 this.managesieve_formbuttons(div);
469 rcube_webmail.prototype.managesieve_ruledel = function(id)
471 if ($('#ruledel'+id).hasClass('disabled'))
474 if (confirm(this.get_label('managesieve.ruledeleteconfirm'))) {
475 var row = document.getElementById('rulerow'+id);
476 row.parentNode.removeChild(row);
477 this.managesieve_formbuttons(document.getElementById('rules'));
481 rcube_webmail.prototype.managesieve_actionadd = function(id)
483 this.http_post('plugin.managesieve', '_act=actionadd&_aid='+id);
486 rcube_webmail.prototype.managesieve_actionfill = function(content, id, after)
489 var div = document.getElementById('actions'),
490 row = document.createElement('div');
492 this.managesieve_insertrow(div, row, after);
493 // fill row after inserting (for IE)
494 row.className = 'actionrow';
495 row.setAttribute('id', 'actionrow'+id);
496 row.innerHTML = content;
498 this.managesieve_formbuttons(div);
502 rcube_webmail.prototype.managesieve_actiondel = function(id)
504 if ($('#actiondel'+id).hasClass('disabled'))
507 if (confirm(this.get_label('managesieve.actiondeleteconfirm'))) {
508 var row = document.getElementById('actionrow'+id);
509 row.parentNode.removeChild(row);
510 this.managesieve_formbuttons(document.getElementById('actions'));
514 // insert rule/action row in specified place on the list
515 rcube_webmail.prototype.managesieve_insertrow = function(div, row, after)
517 for (var i=0; i<div.childNodes.length; i++) {
518 if (div.childNodes[i].id == (div.id == 'rules' ? 'rulerow' : 'actionrow') + after)
522 if (div.childNodes[i+1])
523 div.insertBefore(row, div.childNodes[i+1]);
525 div.appendChild(row);
528 // update Delete buttons status
529 rcube_webmail.prototype.managesieve_formbuttons = function(div)
531 var i, button, buttons = [];
533 // count and get buttons
534 for (i=0; i<div.childNodes.length; i++) {
535 if (div.id == 'rules' && div.childNodes[i].id) {
536 if (/rulerow/.test(div.childNodes[i].id))
537 buttons.push('ruledel' + div.childNodes[i].id.replace(/rulerow/, ''));
539 else if (div.childNodes[i].id) {
540 if (/actionrow/.test(div.childNodes[i].id))
541 buttons.push( 'actiondel' + div.childNodes[i].id.replace(/actionrow/, ''));
545 for (i=0; i<buttons.length; i++) {
546 button = document.getElementById(buttons[i]);
547 if (i>0 || buttons.length>1) {
548 $(button).removeClass('disabled');
551 $(button).addClass('disabled');
556 function rule_header_select(id)
558 var obj = document.getElementById('header' + id),
559 size = document.getElementById('rule_size' + id),
560 op = document.getElementById('rule_op' + id),
561 target = document.getElementById('rule_target' + id),
562 header = document.getElementById('custom_header' + id),
563 mod = document.getElementById('rule_mod' + id),
564 trans = document.getElementById('rule_trans' + id),
565 comp = document.getElementById('rule_comp' + id);
567 if (obj.value == 'size') {
568 size.style.display = 'inline';
569 op.style.display = 'none';
570 target.style.display = 'none';
571 header.style.display = 'none';
572 mod.style.display = 'none';
573 trans.style.display = 'none';
574 comp.style.display = 'none';
577 header.style.display = obj.value != '...' ? 'none' : 'inline';
578 size.style.display = 'none';
579 op.style.display = 'inline';
580 comp.style.display = '';
582 mod.style.display = obj.value == 'body' ? 'none' : 'block';
583 trans.style.display = obj.value == 'body' ? 'block' : 'none';
586 obj.style.width = obj.value == '...' ? '40px' : '';
589 function rule_op_select(id)
591 var obj = document.getElementById('rule_op' + id),
592 target = document.getElementById('rule_target' + id);
594 target.style.display = obj.value == 'exists' || obj.value == 'notexists' ? 'none' : 'inline';
597 function rule_trans_select(id)
599 var obj = document.getElementById('rule_trans_op' + id),
600 target = document.getElementById('rule_trans_type' + id);
602 target.style.display = obj.value != 'content' ? 'none' : 'inline';
605 function rule_mod_select(id)
607 var obj = document.getElementById('rule_mod_op' + id),
608 target = document.getElementById('rule_mod_type' + id);
610 target.style.display = obj.value != 'address' && obj.value != 'envelope' ? 'none' : 'inline';
613 function rule_join_radio(value)
615 $('#rules').css('display', value == 'any' ? 'none' : 'block');
618 function rule_adv_switch(id, elem)
620 var elem = $(elem), enabled = elem.hasClass('hide'), adv = $('#rule_advanced'+id);
624 elem.removeClass('hide').addClass('show');
628 elem.removeClass('show').addClass('hide');
632 function action_type_select(id)
634 var obj = document.getElementById('action_type' + id),
637 mailbox: document.getElementById('action_mailbox' + id),
638 target: document.getElementById('action_target' + id),
639 target_area: document.getElementById('action_target_area' + id),
640 flags: document.getElementById('action_flags' + id),
641 vacation: document.getElementById('action_vacation' + id)
644 if (obj.value == 'fileinto' || obj.value == 'fileinto_copy') {
647 else if (obj.value == 'redirect' || obj.value == 'redirect_copy') {
650 else if (obj.value.match(/^reject|ereject$/)) {
651 enabled.target_area = 1;
653 else if (obj.value.match(/^(add|set|remove)flag$/)) {
656 else if (obj.value == 'vacation') {
657 enabled.vacation = 1;
660 for (var x in elems) {
661 elems[x].style.display = !enabled[x] ? 'none' : 'inline';
665 // Register onmouse(leave/enter) events for tips on specified form element
666 rcube_webmail.prototype.managesieve_tip_register = function(tips)
668 var n, framed = parent.rcmail,
669 tip = framed ? parent.rcmail.env.ms_tip_layer : rcmail.env.ms_tip_layer;
671 for (var n in tips) {
673 .bind('mouseenter', {str: tips[n][1]},
675 var offset = $(this).offset(),
677 top = offset.top - 12;
680 offset = $((rcmail.env.task == 'mail' ? '#sievefilterform > iframe' : '#filter-box'), parent.document).offset();
688 tip.css({left: left, top: top}).show();
690 .bind('mouseleave', function(e) { tip.hide(); });
694 /*********************************************************/
695 /********* Mail UI methods *********/
696 /*********************************************************/
698 rcube_webmail.prototype.managesieve_create = function()
700 if (!rcmail.env.sieve_headers || !rcmail.env.sieve_headers.length)
703 var i, html, buttons = {}, dialog = $("#sievefilterform");
705 // create dialog window
706 if (!dialog.length) {
707 dialog = $('<div id="sievefilterform"></div>');
708 $('body').append(dialog);
711 // build dialog window content
712 html = '<fieldset><legend>'+this.gettext('managesieve.usedata')+'</legend><ul>';
713 for (i in rcmail.env.sieve_headers)
714 html += '<li><input type="checkbox" name="headers[]" id="sievehdr'+i+'" value="'+i+'" checked="checked" />'
715 +'<label for="sievehdr'+i+'">'+rcmail.env.sieve_headers[i][0]+':</label> '+rcmail.env.sieve_headers[i][1]+'</li>';
716 html += '</ul></fieldset>';
720 // [Next Step] button action
721 buttons[this.gettext('managesieve.nextstep')] = function () {
722 // check if there's at least one checkbox checked
723 var hdrs = $('input[name="headers[]"]:checked', dialog);
725 alert(rcmail.gettext('managesieve.nodata'));
730 var url = rcmail.get_task_url('mail');
731 url = rcmail.add_url(url, '_action', 'plugin.managesieve');
732 url = rcmail.add_url(url, '_framed', 1);
734 hdrs.map(function() {
735 var val = rcmail.env.sieve_headers[this.value];
736 url = rcmail.add_url(url, 'r['+this.value+']', val[0]+':'+val[1]);
739 // load form in the iframe
740 var frame = $('<iframe>').attr({src: url, frameborder: 0})
741 dialog.empty().append(frame).dialog('dialog').resize();
743 // Change [Next Step] button with [Save] button
745 buttons[rcmail.gettext('save')] = function() {
746 var win = $('iframe', dialog).get(0).contentWindow;
747 win.rcmail.managesieve_save();
749 dialog.dialog('option', 'buttons', buttons);
752 // show dialog window
756 closeOnEscape: (!bw.ie6 && !bw.ie7), // disable for performance reasons
757 title: this.gettext('managesieve.newfilter'),
758 close: function() { rcmail.managesieve_dialog_close(); },
765 this.env.managesieve_dialog = dialog;
768 rcube_webmail.prototype.managesieve_dialog_close = function()
770 var dialog = this.env.managesieve_dialog;
772 // BUG(?): if we don't remove the iframe first, it will be reloaded
774 dialog.dialog('destroy').hide();
777 rcube_webmail.prototype.managesieve_dialog_resize = function(o)
779 var dialog = this.env.managesieve_dialog,
780 win = $(window), form = $(o);
781 width = form.width(), height = form.height(),
782 w = win.width(), h = win.height();
784 dialog.dialog('option', { height: Math.min(h-20, height+120), width: Math.min(w-20, width+65) })
785 .dialog('option', 'position', ['center', 'center']); // only works in a separate call (!?)