From 27f0c2723bf8a5efb5a588c2603fbb0a65f0453d Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Mon, 09 Dec 2013 05:40:03 -0500 Subject: [PATCH] Nicely handle server-side modification of script names (#1489412) --- plugins/managesieve/managesieve.js | 249 +++++++++++++++++++++++++++++++++++-------------- 1 files changed, 177 insertions(+), 72 deletions(-) diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js index be65c44..4e810b1 100644 --- a/plugins/managesieve/managesieve.js +++ b/plugins/managesieve/managesieve.js @@ -21,7 +21,7 @@ rcmail.add_element(tab, 'tabs'); } - if (rcmail.env.task == 'mail' || rcmail.env.action.indexOf('plugin.managesieve') != -1) { + if (rcmail.env.task == 'mail' || rcmail.env.action.startsWith('plugin.managesieve')) { // Create layer for form tips if (!rcmail.env.framed) { rcmail.env.ms_tip_layer = $('<div id="managesieve-tip" class="popupmenu"></div>'); @@ -40,7 +40,7 @@ rcmail.register_command('plugin.managesieve-setact', function() { rcmail.managesieve_setact() }); rcmail.register_command('plugin.managesieve-setget', function() { rcmail.managesieve_setget() }); - if (rcmail.env.action == 'plugin.managesieve' || rcmail.env.action == 'plugin.managesieve-save') { + if (rcmail.env.action.startsWith('plugin.managesieve')) { if (rcmail.gui_objects.sieveform) { rcmail.enable_command('plugin.managesieve-save', true); @@ -55,6 +55,11 @@ } $('input[type="text"]:first', rcmail.gui_objects.sieveform).focus(); + + // initialize smart list inputs + $('textarea[data-type="list"]', rcmail.gui_objects.sieveform).each(function() { + smart_field_init(this); + }); } else { rcmail.enable_command('plugin.managesieve-add', 'plugin.managesieve-setadd', !rcmail.env.sieveconnerror); @@ -117,7 +122,7 @@ var id = this.filters_list.get_single_selection(); if (confirm(this.get_label('managesieve.filterdeleteconfirm'))) { var lock = this.set_busy(true, 'loading'); - this.http_post('plugin.managesieve', + this.http_post('plugin.managesieve-action', '_act=delete&_fid='+this.filters_list.rows[id].uid, lock); } }; @@ -127,7 +132,7 @@ var id = this.filters_list.get_single_selection(), lock = this.set_busy(true, 'loading'); - this.http_post('plugin.managesieve', + this.http_post('plugin.managesieve-action', '_act=act&_fid='+this.filters_list.rows[id].uid, lock); }; @@ -145,7 +150,7 @@ this.show_contentframe(false); this.filters_list.clear(true); this.enable_command('plugin.managesieve-setdel', list.rowcount > 1); - this.enable_command( 'plugin.managesieve-setact', 'plugin.managesieve-setget', true); + this.enable_command('plugin.managesieve-setact', 'plugin.managesieve-setget', true); var id = list.get_single_selection(); if (id != null) @@ -156,7 +161,7 @@ { var i, rows = this.filters_list.rows; - for (i=0; i<rows.length; i++) + for (i in rows) if (rows[i] != null && rows[i].uid == id) return i; }; @@ -174,7 +179,7 @@ { var lock = this.set_busy(true, 'loading'); - this.http_post('plugin.managesieve', '_act=list&_set='+urlencode(script), lock); + this.http_post('plugin.managesieve-action', '_act=list&_set='+urlencode(script), lock); }; // Script download request @@ -183,7 +188,7 @@ var id = this.filtersets_list.get_single_selection(), script = this.env.filtersets[id]; - location.href = this.env.comm_path+'&_action=plugin.managesieve&_act=setget&_set='+urlencode(script); + location.href = this.env.comm_path+'&_action=plugin.managesieve-action&_act=setget&_set='+urlencode(script); }; // Set activate/deactivate request @@ -194,7 +199,7 @@ script = this.env.filtersets[id], action = $('#rcmrow'+id).hasClass('disabled') ? 'setact' : 'deact'; - this.http_post('plugin.managesieve', '_act='+action+'&_set='+urlencode(script), lock); + this.http_post('plugin.managesieve-action', '_act='+action+'&_set='+urlencode(script), lock); }; // Set delete request @@ -207,7 +212,7 @@ lock = this.set_busy(true, 'loading'), script = this.env.filtersets[id]; - this.http_post('plugin.managesieve', '_act=setdel&_set='+urlencode(script), lock); + this.http_post('plugin.managesieve-action', '_act=setdel&_set='+urlencode(script), lock); }; // Set add request @@ -219,7 +224,7 @@ if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { var lock = this.set_busy(true, 'loading'); target = window.frames[this.env.contentframe]; - target.location.href = this.env.comm_path+'&_action=plugin.managesieve&_framed=1&_newset=1&_unlock='+lock; + target.location.href = this.env.comm_path+'&_action=plugin.managesieve-action&_framed=1&_newset=1&_unlock='+lock; } }; @@ -231,27 +236,34 @@ // Delete filter row case 'del': - var i, list = this.filters_list, rows = list.rows; + var i = 0, list = this.filters_list; list.remove_row(this.managesieve_rowid(o.id)); list.clear_selection(); this.show_contentframe(false); this.enable_command('plugin.managesieve-del', 'plugin.managesieve-act', false); - // re-numbering filters - for (i=0; i<rows.length; i++) { - if (rows[i] != null && rows[i].uid > o.id) - rows[i].uid = rows[i].uid-1; - } + // filter identifiers changed, fix the list + $('tr', this.filters_list.list).each(function() { + // remove hidden (deleted) rows + if (this.style.display == 'none') { + $(this).detach(); + return; + } + + // modify ID and remove all attached events + $(this).attr('id', 'rcmrow'+(i++)).unbind(); + }); + list.init(); break; // Update filter row case 'update': - var i, row = $('#rcmrow'+o.id); + var i, row = $('#rcmrow'+this.managesieve_rowid(o.id)); if (o.name) - $('td', row).html(o.name); + $('td', row).text(o.name); if (o.disabled) row.addClass('disabled'); else @@ -266,7 +278,7 @@ var list = this.filters_list, row = $('<tr><td class="name"></td></tr>'); - $('td', row).html(o.name); + $('td', row).text(o.name); row.attr('id', 'rcmrow'+o.id); if (o.disabled) row.addClass('disabled'); @@ -290,7 +302,7 @@ tr = document.createElement('TR'); td = document.createElement('TD'); - td.innerHTML = el.name; + $(td).text(el.name); td.className = 'name'; tr.id = 'rcmrow' + el.id; if (el['class']) @@ -339,7 +351,7 @@ list = this.filtersets_list, row = $('<tr class="disabled"><td class="name"></td></tr>'); - $('td', row).html(o.name); + $('td', row).text(o.name); row.attr('id', 'rcmrow'+id); this.env.filtersets[id] = o.name; @@ -372,8 +384,8 @@ if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { target = window.frames[this.env.contentframe]; var msgid = this.set_busy(true, 'loading'); - target.location.href = this.env.comm_path+'&_action=plugin.managesieve&_framed=1' - +(id ? '&_fid='+id : '')+'&_unlock='+msgid; + target.location.href = this.env.comm_path+'&_action=plugin.managesieve-action&_framed=1' + +(has_id ? '&_fid='+id : '')+'&_unlock='+msgid; } }; @@ -393,7 +405,7 @@ var lock = this.set_busy(true, 'loading'); this.show_contentframe(false); - this.http_post('plugin.managesieve', '_act=move&_fid='+this.drag_filter + this.http_post('plugin.managesieve-action', '_act=move&_fid='+this.drag_filter +'&_to='+this.drag_filter_target, lock); } this.drag_active = false; @@ -446,7 +458,7 @@ // Operations on filters form rcube_webmail.prototype.managesieve_ruleadd = function(id) { - this.http_post('plugin.managesieve', '_act=ruleadd&_rid='+id); + this.http_post('plugin.managesieve-action', '_act=ruleadd&_rid='+id); }; rcube_webmail.prototype.managesieve_rulefill = function(content, id, after) @@ -461,6 +473,11 @@ row.setAttribute('id', 'rulerow'+id); row.className = 'rulerow'; row.innerHTML = content; + + // initialize smart list inputs + $('textarea[data-type="list"]', row).each(function() { + smart_field_init(this); + }); this.managesieve_formbuttons(div); } @@ -480,7 +497,7 @@ rcube_webmail.prototype.managesieve_actionadd = function(id) { - this.http_post('plugin.managesieve', '_act=actionadd&_aid='+id); + this.http_post('plugin.managesieve-action', '_act=actionadd&_aid='+id); }; rcube_webmail.prototype.managesieve_actionfill = function(content, id, after) @@ -558,40 +575,45 @@ var obj = document.getElementById('header' + id), size = document.getElementById('rule_size' + id), op = document.getElementById('rule_op' + id), - target = document.getElementById('rule_target' + id), - header = document.getElementById('custom_header' + id), + header = document.getElementById('custom_header' + id + '_list'), mod = document.getElementById('rule_mod' + id), trans = document.getElementById('rule_trans' + id), - comp = document.getElementById('rule_comp' + id); + comp = document.getElementById('rule_comp' + id), + datepart = document.getElementById('rule_date_part' + id), + dateheader = document.getElementById('rule_date_header_div' + id), + h = obj.value; - if (obj.value == 'size') { + if (h == 'size') { size.style.display = 'inline'; - op.style.display = 'none'; - target.style.display = 'none'; - header.style.display = 'none'; - mod.style.display = 'none'; - trans.style.display = 'none'; - comp.style.display = 'none'; + $.each([op, header, mod, trans, comp], function() { this.style.display = 'none'; }); } else { - header.style.display = obj.value != '...' ? 'none' : 'inline'; + header.style.display = h != '...' ? 'none' : 'inline-block'; size.style.display = 'none'; op.style.display = 'inline'; comp.style.display = ''; - rule_op_select(id); - mod.style.display = obj.value == 'body' ? 'none' : 'block'; - trans.style.display = obj.value == 'body' ? 'block' : 'none'; + mod.style.display = h == 'body' || h == 'currentdate' || h == 'date' ? 'none' : 'block'; + trans.style.display = h == 'body' ? 'block' : 'none'; } - obj.style.width = obj.value == '...' ? '40px' : ''; + if (datepart) + datepart.style.display = h == 'currentdate' || h == 'date' ? 'inline' : 'none'; + if (dateheader) + dateheader.style.display = h == 'date' ? '' : 'none'; + + rule_op_select(op, id, h); + rule_mod_select(id, h); + obj.style.width = h == '...' ? '40px' : ''; }; -function rule_op_select(id) +function rule_op_select(obj, id, header) { - var obj = document.getElementById('rule_op' + id), - target = document.getElementById('rule_target' + id); + var target = document.getElementById('rule_target' + id + '_list'); - target.style.display = obj.value == 'exists' || obj.value == 'notexists' ? 'none' : 'inline'; + if (!header) + header = document.getElementById('header' + id).value; + + target.style.display = obj.value == 'exists' || obj.value == 'notexists' || header == 'size' ? 'none' : 'inline-block'; }; function rule_trans_select(id) @@ -602,12 +624,19 @@ target.style.display = obj.value != 'content' ? 'none' : 'inline'; }; -function rule_mod_select(id) +function rule_mod_select(id, header) { var obj = document.getElementById('rule_mod_op' + id), - target = document.getElementById('rule_mod_type' + id); + target = document.getElementById('rule_mod_type' + id), + index = document.getElementById('rule_index_div' + id); + + if (!header) + header = document.getElementById('header' + id).value; target.style.display = obj.value != 'address' && obj.value != 'envelope' ? 'none' : 'inline'; + + if (index) + index.style.display = header != 'body' && header != 'currentdate' && header != 'size' && obj.value != 'envelope' ? '' : 'none'; }; function rule_join_radio(value) @@ -632,35 +661,109 @@ function action_type_select(id) { var obj = document.getElementById('action_type' + id), - enabled = {}, + v = obj.value, enabled = {}, elems = { mailbox: document.getElementById('action_mailbox' + id), - target: document.getElementById('action_target' + id), + target: document.getElementById('redirect_target' + id), target_area: document.getElementById('action_target_area' + id), flags: document.getElementById('action_flags' + id), - vacation: document.getElementById('action_vacation' + id) + vacation: document.getElementById('action_vacation' + id), + set: document.getElementById('action_set' + id), + notify: document.getElementById('action_notify' + id) }; - if (obj.value == 'fileinto' || obj.value == 'fileinto_copy') { + if (v == 'fileinto' || v == 'fileinto_copy') { enabled.mailbox = 1; } - else if (obj.value == 'redirect' || obj.value == 'redirect_copy') { + else if (v == 'redirect' || v == 'redirect_copy') { enabled.target = 1; } - else if (obj.value.match(/^reject|ereject$/)) { + else if (v.match(/^reject|ereject$/)) { enabled.target_area = 1; } - else if (obj.value.match(/^(add|set|remove)flag$/)) { + else if (v.match(/^(add|set|remove)flag$/)) { enabled.flags = 1; } - else if (obj.value == 'vacation') { + else if (v == 'vacation') { enabled.vacation = 1; + } + else if (v == 'set') { + enabled.set = 1; + } + else if (v == 'notify') { + enabled.notify = 1; } for (var x in elems) { elems[x].style.display = !enabled[x] ? 'none' : 'inline'; } }; + +// Inititalizes smart list input +function smart_field_init(field) +{ + var id = field.id + '_list', + area = $('<span class="listarea"></span>'), + list = field.value ? field.value.split("\n") : ['']; + + if ($('#'+id).length) + return; + + // add input rows + $.each(list, function(i, v) { + area.append(smart_field_row(v, field.name, i, $(field).data('size'))); + }); + + area.attr('id', id); + field = $(field); + + if (field.attr('disabled')) + area.hide(); + + field.after(area); + + if (field.hasClass('error')) { + area.addClass('error'); + rcmail.managesieve_tip_register([[id, field.data('tip')]]); + } +}; + +function smart_field_row(value, name, idx, size) +{ + // build row element content + var input, content = '<span class="listelement">' + + '<span class="reset"></span><input type="text"></span>', + elem = $(content), + attrs = {value: value, name: name + '[]'}; + + if (size) + attrs.size = size; + + input = $('input', elem).attr(attrs).keydown(function(e) { + var input = $(this); + // element creation event (on Enter) + if (e.which == 13) { + var name = input.attr('name').replace(/\[\]$/, ''), + dt = (new Date()).getTime(), + elem = smart_field_row('', name, dt, size); + + input.parent().after(elem); + $('input', elem).focus(); + } + }); + + // element deletion event + $('span[class="reset"]', elem).click(function() { + var span = $(this.parentNode); + + if (span.parent().children().length > 1) + span.remove(); + else + $('input', span).val('').focus(); + }); + + return elem; +} // Register onmouse(leave/enter) events for tips on specified form element rcube_webmail.prototype.managesieve_tip_register = function(tips) @@ -670,24 +773,26 @@ for (var n in tips) { $('#'+tips[n][0]) - .bind('mouseenter', {str: tips[n][1]}, - function(e) { - var offset = $(this).offset(), - left = offset.left, - top = offset.top - 12; + .data('tip', tips[n][1]) + .bind('mouseenter', function(e) { + var elem = $(this), + offset = elem.offset(), + left = offset.left, + top = offset.top - 12, + minwidth = elem.width(); - if (framed) { - offset = $((rcmail.env.task == 'mail' ? '#sievefilterform > iframe' : '#filter-box'), parent.document).offset(); - top += offset.top; - left += offset.left; - } + if (framed) { + offset = $((rcmail.env.task == 'mail' ? '#sievefilterform > iframe' : '#filter-box'), parent.document).offset(); + top += offset.top; + left += offset.left; + } - tip.html(e.data.str) - top -= tip.height(); + tip.html(elem.data('tip')); + top -= tip.height(); - tip.css({left: left, top: top}).show(); - }) - .bind('mouseleave', function(e) { tip.hide(); }); + tip.css({left: left, top: top, minWidth: (minwidth-2) + 'px'}).show(); + }) + .bind('mouseleave', function(e) { tip.hide(); }); } }; @@ -738,7 +843,7 @@ // load form in the iframe var frame = $('<iframe>').attr({src: url, frameborder: 0}) - dialog.empty().append(frame).dialog('dialog').resize(); + dialog.empty().append(frame).dialog('widget').resize(); // Change [Next Step] button with [Save] button buttons = {}; -- Gitblit v1.9.1