diff options
author | Aleksander Machniak <alec@alec.pl> | 2013-06-15 15:35:55 +0200 |
---|---|---|
committer | Aleksander Machniak <alec@alec.pl> | 2013-06-15 15:35:55 +0200 |
commit | 0185a2790767caab93f2c504ad38d7edca70d043 (patch) | |
tree | 2a78d62245a9a254015f97f23135d3de109edb20 /plugins | |
parent | 5c6e74b176705b595aed3f33c89c9632bb49c587 (diff) |
Implemented date, currentdate and index - RFC5260 (#1488120)
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/managesieve/Changelog | 1 | ||||
-rw-r--r-- | plugins/managesieve/localization/en_US.inc | 23 | ||||
-rw-r--r-- | plugins/managesieve/managesieve.js | 56 | ||||
-rw-r--r-- | plugins/managesieve/managesieve.php | 247 | ||||
-rw-r--r-- | plugins/managesieve/skins/classic/managesieve.css | 8 | ||||
-rw-r--r-- | plugins/managesieve/skins/larry/managesieve.css | 11 |
6 files changed, 280 insertions, 66 deletions
diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog index a5f325008..a2bdf684e 100644 --- a/plugins/managesieve/Changelog +++ b/plugins/managesieve/Changelog @@ -1,6 +1,7 @@ - Add vacation-seconds extension support (RFC 6131) - Several script parser code improvements - Support string list arguments in filter form (#1489018) +- Support date, currendate and index tests - RFC5260 (#1488120) * version 6.2 [2013-02-17] ----------------------------------------------------------- diff --git a/plugins/managesieve/localization/en_US.inc b/plugins/managesieve/localization/en_US.inc index 9fe943446..72bbf9d41 100644 --- a/plugins/managesieve/localization/en_US.inc +++ b/plugins/managesieve/localization/en_US.inc @@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'count is greater than or equal to'; $labels['countislessthan'] = 'count is less than'; $labels['countislessthanequal'] = 'count is less than or equal to'; $labels['countequals'] = 'count is equal to'; -$labels['countnotequals'] = 'count does not equal'; +$labels['countnotequals'] = 'count is not equal to'; $labels['valueisgreaterthan'] = 'value is greater than'; $labels['valueisgreaterthanequal'] = 'value is greater than or equal to'; $labels['valueislessthan'] = 'value is less than'; $labels['valueislessthanequal'] = 'value is less than or equal to'; $labels['valueequals'] = 'value is equal to'; -$labels['valuenotequals'] = 'value does not equal'; +$labels['valuenotequals'] = 'value is not equal to'; $labels['setflags'] = 'Set flags to the message'; $labels['addflags'] = 'Add flags to the message'; $labels['removeflags'] = 'Remove flags from the message'; @@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Create filter'; $labels['usedata'] = 'Use following data in the filter:'; $labels['nextstep'] = 'Next Step'; $labels['...'] = '...'; +$labels['currdate'] = 'Current date'; +$labels['datetest'] = 'Date'; +$labels['dateheader'] = 'header:'; +$labels['year'] = 'year'; +$labels['month'] = 'month'; +$labels['day'] = 'day'; +$labels['date'] = 'date (yyyy-mm-dd)'; +$labels['julian'] = 'date (julian)'; +$labels['hour'] = 'hour'; +$labels['minute'] = 'minute'; +$labels['second'] = 'second'; +$labels['time'] = 'time (hh:mm:ss)'; +$labels['iso8601'] = 'date (ISO8601)'; +$labels['std11'] = 'date (RFC2822)'; +$labels['zone'] = 'time-zone'; +$labels['weekday'] = 'weekday (0-6)'; $labels['advancedopts'] = 'Advanced options'; $labels['body'] = 'Body'; $labels['address'] = 'address'; @@ -140,6 +156,8 @@ $labels['default'] = 'default'; $labels['octet'] = 'strict (octet)'; $labels['asciicasemap'] = 'case insensitive (ascii-casemap)'; $labels['asciinumeric'] = 'numeric (ascii-numeric)'; +$labels['index'] = 'index:'; +$labels['indexlast'] = 'backwards'; $messages = array(); $messages['filterunknownerror'] = 'Unknown server error.'; @@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Name too long.'; $messages['namereserved'] = 'Reserved name.'; $messages['setexist'] = 'Set already exists.'; $messages['nodata'] = 'At least one position must be selected!'; +$messages['invaliddateformat'] = 'Invalid date or date part format'; ?> diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js index 3a87a9f43..f6bf4b47c 100644 --- a/plugins/managesieve/managesieve.js +++ b/plugins/managesieve/managesieve.js @@ -578,27 +578,32 @@ function rule_header_select(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'; - 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-block'; + header.style.display = h != '...' ? 'none' : 'inline-block'; size.style.display = 'none'; op.style.display = 'inline'; comp.style.display = ''; - 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'; } - rule_op_select(op, id, obj.value); - 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(obj, id, header) @@ -619,12 +624,19 @@ function rule_trans_select(id) 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) @@ -649,7 +661,7 @@ function rule_adv_switch(id, elem) 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), @@ -660,25 +672,25 @@ function action_type_select(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 (obj.value == 'set') { + else if (v == 'set') { enabled.set = 1; } - else if (obj.value == 'notify') { + else if (v == 'notify') { enabled.notify = 1; } diff --git a/plugins/managesieve/managesieve.php b/plugins/managesieve/managesieve.php index 0dfe05a6f..d514c28d5 100644 --- a/plugins/managesieve/managesieve.php +++ b/plugins/managesieve/managesieve.php @@ -12,8 +12,8 @@ * * Configuration (see config.inc.php.dist) * - * Copyright (C) 2008-2012, The Roundcube Dev Team - * Copyright (C) 2011-2012, Kolab Systems AG + * Copyright (C) 2008-2013, The Roundcube Dev Team + * Copyright (C) 2011-2013, Kolab Systems AG * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -662,6 +662,10 @@ class managesieve extends rcube_plugin $body_trans = rcube_utils::get_input_value('_rule_trans', rcube_utils::INPUT_POST); $body_types = rcube_utils::get_input_value('_rule_trans_type', rcube_utils::INPUT_POST, true); $comparators = rcube_utils::get_input_value('_rule_comp', rcube_utils::INPUT_POST); + $indexes = rcube_utils::get_input_value('_rule_index', rcube_utils::INPUT_POST); + $lastindexes = rcube_utils::get_input_value('_rule_index_last', rcube_utils::INPUT_POST); + $dateheaders = rcube_utils::get_input_value('_rule_date_header', rcube_utils::INPUT_POST); + $dateparts = rcube_utils::get_input_value('_rule_date_part', rcube_utils::INPUT_POST); $act_types = rcube_utils::get_input_value('_action_type', rcube_utils::INPUT_POST, true); $mailboxes = rcube_utils::get_input_value('_action_mailbox', rcube_utils::INPUT_POST, true); $act_targets = rcube_utils::get_input_value('_action_target', rcube_utils::INPUT_POST, true); @@ -732,6 +736,82 @@ class managesieve extends rcube_plugin else $this->form['tests'][$i]['arg'] .= $m[1]; } + else if ($header == 'currentdate') { + $datepart = $this->strip_value($dateparts[$idx]); + + if (preg_match('/^not/', $operator)) + $this->form['tests'][$i]['not'] = true; + $type = preg_replace('/^not/', '', $operator); + + if ($type == 'exists') { + $this->errors['tests'][$i]['op'] = true; + } + + $this->form['tests'][$i]['test'] = 'currentdate'; + $this->form['tests'][$i]['type'] = $type; + $this->form['tests'][$i]['part'] = $datepart; + $this->form['tests'][$i]['arg'] = $target; + + if ($type != 'exists') { + if (!count($target)) { + $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty'); + } + else if ($type != 'regex' && $type != 'matches') { + foreach ($target as $arg) { + if (!$this->validate_date_part($datepart, $arg)) { + $this->errors['tests'][$i]['target'] = $this->gettext('invaliddateformat'); + break; + } + } + } + } + } + else if ($header == 'date') { + $datepart = $this->strip_value($dateparts[$idx]); + $dateheader = $this->strip_value($dateheaders[$idx]); + $index = $this->strip_value($indexes[$idx]); + $indexlast = $this->strip_value($lastindexes[$idx]); + + if (preg_match('/^not/', $operator)) + $this->form['tests'][$i]['not'] = true; + $type = preg_replace('/^not/', '', $operator); + + if ($type == 'exists') { + $this->errors['tests'][$i]['op'] = true; + } + + if (!empty($index) && $mod != 'envelope') { + $this->form['tests'][$i]['index'] = intval($index); + $this->form['tests'][$i]['last'] = !empty($indexlast); + } + + if (empty($dateheader)) { + $dateheader = 'Date'; + } + else if (!preg_match('/^[\x21-\x39\x41-\x7E]+$/i', $dateheader)) { + $this->errors['tests'][$i]['dateheader'] = $this->gettext('forbiddenchars'); + } + + $this->form['tests'][$i]['test'] = 'date'; + $this->form['tests'][$i]['type'] = $type; + $this->form['tests'][$i]['part'] = $datepart; + $this->form['tests'][$i]['arg'] = $target; + $this->form['tests'][$i]['header'] = $dateheader; + + if ($type != 'exists') { + if (!count($target)) { + $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty'); + } + else if ($type != 'regex' && $type != 'matches') { + foreach ($target as $arg) { + if (!$this->validate_date_part($datepart, $arg)) { + $this->errors['tests'][$i]['target'] = $this->gettext('invaliddateformat'); + break; + } + } + } + } + } else if ($header == 'body') { $trans = $this->strip_value($body_trans[$idx]); $trans_type = $this->strip_value($body_types[$idx], true); @@ -766,13 +846,20 @@ class managesieve extends rcube_plugin } else { $cust_header = $headers = $this->strip_value(array_shift($cust_headers)); - $mod = $this->strip_value($mods[$idx]); - $mod_type = $this->strip_value($mod_types[$idx]); + $mod = $this->strip_value($mods[$idx]); + $mod_type = $this->strip_value($mod_types[$idx]); + $index = $this->strip_value($indexes[$idx]); + $indexlast = $this->strip_value($lastindexes[$idx]); if (preg_match('/^not/', $operator)) $this->form['tests'][$i]['not'] = true; $type = preg_replace('/^not/', '', $operator); + if (!empty($index) && $mod != 'envelope') { + $this->form['tests'][$i]['index'] = intval($index); + $this->form['tests'][$i]['last'] = !empty($indexlast); + } + if ($header == '...') { if (!count($headers)) $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty'); @@ -1304,35 +1391,40 @@ class managesieve extends rcube_plugin // headers select $select_header = new html_select(array('name' => "_header[]", 'id' => 'header'.$id, 'onchange' => 'rule_header_select(' .$id .')')); - foreach($this->headers as $name => $val) + + foreach ($this->headers as $name => $val) $select_header->add(rcube::Q($this->gettext($name)), Q($val)); + $select_header->add(rcube::Q($this->gettext('...')), '...'); if (in_array('body', $this->exts)) $select_header->add(rcube::Q($this->gettext('body')), 'body'); $select_header->add(rcube::Q($this->gettext('size')), 'size'); - $select_header->add(rcube::Q($this->gettext('...')), '...'); - - // TODO: list arguments - $aout = ''; + if (in_array('date', $this->exts)) { + $select_header->add(rcube::Q($this->gettext('datetest')), 'date'); + $select_header->add(rcube::Q($this->gettext('currdate')), 'currentdate'); + } - if ((isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope'))) - && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers) - ) { - $aout .= $select_header->show($rule['arg1']); + if (isset($rule['test'])) { + if (in_array($rule['test'], array('header', 'address', 'envelope')) + && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers) + ) { + $test = $rule['arg1']; + } + else if ($rule['test'] == 'exists' + && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers) + ) { + $test = $rule['arg']; + } + else if (in_array($rule['test'], array('size', 'body', 'date', 'currentdate'))) { + $test = $rule['test']; + } + else if ($rule['test'] != 'true') { + $test = '...'; + } } - else if ((isset($rule['test']) && $rule['test'] == 'exists') - && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers) - ) { - $aout .= $select_header->show($rule['arg']); - } - else if (isset($rule['test']) && $rule['test'] == 'size') - $aout .= $select_header->show('size'); - else if (isset($rule['test']) && $rule['test'] == 'body') - $aout .= $select_header->show('body'); - else if (isset($rule['test']) && $rule['test'] != 'true') - $aout .= $select_header->show('...'); - else - $aout .= $select_header->show(); + $aout = $select_header->show($test); + + // custom headers input if (isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope'))) { $custom = (array) $rule['arg1']; if (count($custom) == 1 && isset($this->headers[strtolower($custom[0])])) { @@ -1381,13 +1473,28 @@ class managesieve extends rcube_plugin $select_op->add(rcube::Q($this->gettext('valuenotequals')), 'value-ne'); } - // target input (TODO: lists) + // (current)date part select + if (in_array('date', $this->exts) || in_array('currentdate', $this->exts)) { + $date_parts = array('date', 'iso8601', 'std11', 'julian', 'time', + 'year', 'month', 'day', 'hour', 'minute', 'second', 'weekday', 'zone'); + $select_dp = new html_select(array('name' => "_rule_date_part[]", 'id' => 'rule_date_part'.$id, + 'style' => $rule['test'] == 'currentdate' || $rule['test'] == 'date' ? '' : 'display:none', + 'class' => 'datepart_selector', + )); + + foreach ($date_parts as $part) { + $select_dp->add(rcube::Q($this->gettext($part)), $part); + } + + $tout .= $select_dp->show($rule['test'] == 'currentdate' || $rule['test'] == 'date' ? $rule['part'] : ''); + } + // target(s) input if (in_array($rule['test'], array('header', 'address', 'envelope'))) { $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is'); $target = $rule['arg2']; } - else if ($rule['test'] == 'body') { + else if (in_array($rule['test'], array('body', 'date', 'currentdate'))) { $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is'); $target = $rule['arg']; } @@ -1449,11 +1556,9 @@ class managesieve extends rcube_plugin } $need_mod = $rule['test'] != 'size' && $rule['test'] != 'body'; - $mout = '<div id="rule_mod' .$id. '" class="adv" style="display:' . ($need_mod ? 'block' : 'none') .'">'; - $mout .= ' <span>'; - $mout .= rcube::Q($this->gettext('modifier')) . ' '; + $mout = '<div id="rule_mod' .$id. '" class="adv"' . (!$need_mod ? ' style="display:none"' : '') . '>'; + $mout .= ' <span class="label">' . rcube::Q($this->gettext('modifier')) . ' </span>'; $mout .= $select_mod->show($rule['test']); - $mout .= '</span>'; $mout .= ' <span id="rule_mod_type' . $id . '"'; $mout .= ' style="display:' . (in_array($rule['test'], array('address', 'envelope')) ? 'inline' : 'none') .'">'; $mout .= rcube::Q($this->gettext('modtype')) . ' '; @@ -1468,15 +1573,13 @@ class managesieve extends rcube_plugin $select_mod->add(rcube::Q($this->gettext('undecoded')), 'raw'); $select_mod->add(rcube::Q($this->gettext('contenttype')), 'content'); - $mout .= '<div id="rule_trans' .$id. '" class="adv" style="display:' . ($rule['test'] == 'body' ? 'block' : 'none') .'">'; - $mout .= ' <span>'; - $mout .= rcube::Q($this->gettext('modifier')) . ' '; + $mout .= '<div id="rule_trans' .$id. '" class="adv"' . ($rule['test'] != 'body' ? ' style="display:none"' : '') . '>'; + $mout .= '<span class="label">' . rcube::Q($this->gettext('modifier')) . '</span>'; $mout .= $select_mod->show($rule['part']); $mout .= '<input type="text" name="_rule_trans_type[]" id="rule_trans_type'.$id . '" value="'.(is_array($rule['content']) ? implode(',', $rule['content']) : $rule['content']) - .'" size="20" style="display:' . ($rule['part'] == 'content' ? 'inline' : 'none') .'"' + .'" size="20"' . ($rule['part'] != 'content' ? ' style="display:none"' : '') . $this->error_class($id, 'test', 'part', 'rule_trans_type') .' />'; - $mout .= '</span>'; $mout .= '</div>'; // Advanced modifiers (body transformations) @@ -1488,13 +1591,36 @@ class managesieve extends rcube_plugin $select_comp->add(rcube::Q($this->gettext('asciinumeric')), 'i;ascii-numeric'); } - $mout .= '<div id="rule_comp' .$id. '" class="adv" style="display:' . ($rule['test'] != 'size' ? 'block' : 'none') .'">'; - $mout .= ' <span>'; - $mout .= rcube::Q($this->gettext('comparator')) . ' '; + // Comparators + $mout .= '<div id="rule_comp' .$id. '" class="adv"' . ($rule['test'] == 'size' ? ' style="display:none"' : '') . '>'; + $mout .= '<span class="label">' . rcube::Q($this->gettext('comparator')) . '</span>'; $mout .= $select_comp->show($rule['comparator']); - $mout .= '</span>'; $mout .= '</div>'; + // Date header + if (in_array('date', $this->exts)) { + $mout .= '<div id="rule_date_header_div' .$id. '" class="adv"'. ($rule['test'] != 'date' ? ' style="display:none"' : '') .'>'; + $mout .= '<span class="label">' . rcube::Q($this->gettext('dateheader')) . '</span>'; + $mout .= '<input type="text" name="_rule_date_header[]" id="rule_date_header'.$id + . '" value="'. Q($rule['test'] == 'date' ? $rule['header'] : '') + . '" size="15"' . $this->error_class($id, 'test', 'dateheader', 'rule_date_header') .' />'; + $mout .= '</div>'; + } + + // Index + if (in_array('index', $this->exts)) { + $need_index = in_array($rule['test'], array('header', ', address', 'date')); + $mout .= '<div id="rule_index_div' .$id. '" class="adv"'. (!$need_index ? ' style="display:none"' : '') .'>'; + $mout .= '<span class="label">' . rcube::Q($this->gettext('index')) . '</span>'; + $mout .= '<input type="text" name="_rule_index[]" id="rule_index'.$id + . '" value="'. ($rule['index'] ? intval($rule['index']) : '') + . '" size="3"' . $this->error_class($id, 'test', 'index', 'rule_index') .' />'; + $mout .= ' <input type="checkbox" name="_rule_index_last[]" id="rule_index_last'.$id + . '" value="1"' . (!empty($rule['last']) ? ' checked="checked"' : '') . ' />' + . '<label for="rule_index_last'.$id.'">'.rcube::Q($this->gettext('indexlast')).'</label>'; + $mout .= '</div>'; + } + // Build output table $out = $div ? '<div class="rulerow" id="rulerow' .$id .'">'."\n" : ''; $out .= '<table><tr>'; @@ -1792,6 +1918,45 @@ class managesieve extends rcube_plugin } /** + * Validate input for date part elements + */ + private function validate_date_part($type, $value) + { + // we do simple validation of date/part format + switch ($type) { + case 'date': // yyyy-mm-dd + return preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $value); + case 'iso8601': + return preg_match('/^[0-9: .,ZWT+-]+$/', $value); + case 'std11': + return preg_match('/^((Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?[0-9]{1,2}\s+' + . '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+[0-9]{2,4}\s+' + . '[0-9]{2}:[0-9]{2}(:[0-9]{2})?\s+([+-]*[0-9]{4}|[A-Z]{1,3})$', $value); + case 'julian': + return preg_match('/^[0-9]+$/', $value); + case 'time': // hh:mm:ss + return preg_match('/^[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $value); + case 'year': + return preg_match('/^[0-9]{4}$/', $value); + case 'month': + return preg_match('/^[0-9]{2}$/', $value) && $value > 0 && $value < 13; + case 'day': + return preg_match('/^[0-9]{2}$/', $value) && $value > 0 && $value < 32; + case 'hour': + return preg_match('/^[0-9]{2}$/', $value) && $value < 24; + case 'minute': + return preg_match('/^[0-9]{2}$/', $value) && $value < 60; + case 'second': + // According to RFC5260, seconds can be from 00 to 60 + return preg_match('/^[0-9]{2}$/', $value) && $value < 61; + case 'weekday': + return preg_match('/^[0-9]$/', $value) && $value < 7; + case 'zone': + return preg_match('/^[+-][0-9]{4}$/', $value); + } + } + + /** * Converts mailbox name from/to UTF7-IMAP from/to internal Sieve encoding * with delimiter replacement. * diff --git a/plugins/managesieve/skins/classic/managesieve.css b/plugins/managesieve/skins/classic/managesieve.css index 1f112b956..59d88cb46 100644 --- a/plugins/managesieve/skins/classic/managesieve.css +++ b/plugins/managesieve/skins/classic/managesieve.css @@ -212,6 +212,13 @@ td.rowtargets div.adv padding-top: 3px; } +td.rowtargets div.adv span.label +{ + display: inline-block; + padding-right: 10px; + min-width: 65px; +} + html.mozilla #filter-form select { padding-top: 3px; @@ -319,6 +326,7 @@ a.button.disabled #filter-form textarea { font-size: 11px; + vertical-align: middle; } /* smart multi-row input field */ diff --git a/plugins/managesieve/skins/larry/managesieve.css b/plugins/managesieve/skins/larry/managesieve.css index a618502d2..2144fe13f 100644 --- a/plugins/managesieve/skins/larry/managesieve.css +++ b/plugins/managesieve/skins/larry/managesieve.css @@ -43,7 +43,7 @@ #filtersetslist { width: 100%; - table-layout: fixed; + table-layout: fixed; } #filterslist tbody td, @@ -184,6 +184,14 @@ td.rowtargets > div td.rowtargets div.adv { padding-top: 3px; + font-size: 10px; +} + +td.rowtargets div.adv span.label +{ + display: inline-block; + padding-right: 5px; + min-width: 70px; } input.disabled, input.disabled:hover @@ -297,6 +305,7 @@ a.button.disabled { font-size: 11px; padding: 1px; + vertical-align: middle; } html.mozilla #filter-form select |