From c5c8e73351c38ece1b3814a8c82a0439e7424fc4 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 25 Feb 2015 08:07:11 -0500 Subject: Improved handling of storage errors after message is sent After sending a message it is stored in Sent folder, this operation may fail, e.g. because of "over quota" error. In such a case we'll not close the compose window, but display the error and, if user clicks Send/Save button, we'll display a dialog informing about the situation and providing an option to try the save operation again. --- program/localization/en_US/messages.inc | 1 + 1 file changed, 1 insertion(+) (limited to 'program/localization/en_US') diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc index e5b368f22..e0de3654e 100644 --- a/program/localization/en_US/messages.inc +++ b/program/localization/en_US/messages.inc @@ -179,5 +179,6 @@ $messages['parentnotwritable'] = 'Unable to create/move folder into selected par $messages['messagetoobig'] = 'The message part is too big to process it.'; $messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.

Expected: $expected; found: $detected'; $messages['noscriptwarning'] = 'Warning: This webmail service requires Javascript! In order to use it please enable Javascript in your browser\'s settings.'; +$messages['messageissent'] = 'The message was already sent, but not saved yet. Do you want to save it now?'; ?> -- cgit v1.2.3 From 0bd99db08d1660e02e3b7589c78785ab6be0794d Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Mon, 23 Mar 2015 18:33:40 +0100 Subject: Localize common error messages; improve explanation for CSRF check failures --- program/include/rcmail_output_html.php | 2 +- program/localization/en_US/messages.inc | 9 +++++++ program/steps/utils/error.inc | 46 ++++++++++++++++++++------------- 3 files changed, 38 insertions(+), 19 deletions(-) (limited to 'program/localization/en_US') diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index c6c43b532..365c403e4 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -584,7 +584,7 @@ EOF; // read template file if (!$path || ($templ = @file_get_contents($path)) === false) { rcube::raise_error(array( - 'code' => 501, + 'code' => 404, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__, diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc index e0de3654e..bcf89a441 100644 --- a/program/localization/en_US/messages.inc +++ b/program/localization/en_US/messages.inc @@ -180,5 +180,14 @@ $messages['messagetoobig'] = 'The message part is too big to process it.'; $messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.

Expected: $expected; found: $detected'; $messages['noscriptwarning'] = 'Warning: This webmail service requires Javascript! In order to use it please enable Javascript in your browser\'s settings.'; $messages['messageissent'] = 'The message was already sent, but not saved yet. Do you want to save it now?'; +$messages['errnotfound'] = 'File Not Found'; +$messages['errnotfoundexplain'] = 'The requested resource was not found!'; +$messages['errfailedrequest'] = 'Failed request'; +$messages['errauthorizationfailed'] = 'Authorization Failed'; +$messages['errunauthorizedexplain'] = 'Could not verify that you are authorized to access this service!'; +$messages['errrequestcheckfailed'] = 'Request Check Failed'; +$messages['errcsrfprotectionexplain'] = "For your protection, access to this resource is secured against CSRF.\nYou probably didn't log out before leaving the web application.\n\nHuman interaction is now required to continue."; +$messages['errcontactserveradmin'] = 'Please contact your server-administrator.'; +$messages['clicktoresumesession'] = 'Click here to resume your previous session'; ?> diff --git a/program/steps/utils/error.inc b/program/steps/utils/error.inc index 6bbc57fda..16fbb03d9 100644 --- a/program/steps/utils/error.inc +++ b/program/steps/utils/error.inc @@ -5,7 +5,7 @@ | program/steps/utils/error.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2013, The Roundcube Dev Team | + | Copyright (C) 2005-2015, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -43,37 +43,33 @@ EOF; // authorization error else if ($ERROR_CODE == 401) { - $__error_title = "AUTHORIZATION FAILED"; - $__error_text = "Could not verify that you are authorized to access this service!
\n" - . "Please contact your server-administrator."; + $__error_title = strtoupper($rcmail->gettext('errauthorizationfailed')); + $__error_text = nl2br($rcmail->gettext('errunauthorizedexplain') . "\n" . + $rcmail->gettext('errcontactserveradmin')); } // forbidden due to request check else if ($ERROR_CODE == 403) { if ($_SERVER['REQUEST_METHOD'] == 'GET' && $rcmail->request_status == rcube::REQUEST_ERROR_URL) { - parse_str($_SERVER['QUERY_STRING'], $url); - $url = $rcmail->url($url, true, false, true); - $add = "
Click here to try again."; + $url = $rcmail->url($_GET, true, false, true); + $add = html::a($url, $rcmail->gettext('clicktoresumesession')); } else { - $add = "Please contact your server-administrator."; + $add = $rcmail->gettext('errcontactserveradmin'); } - $__error_title = "REQUEST CHECK FAILED"; - $__error_text = "Access to this service was denied due to failing security checks!
\n$add"; + $__error_title = strtoupper($rcmail->gettext('errrequestcheckfailed')); + $__error_text = nl2br($rcmail->gettext('errcsrfprotectionexplain')) . '

' . $add . '

'; } // failed request (wrong step in URL) else if ($ERROR_CODE == 404) { $request_url = htmlentities($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); - $__error_title = "REQUEST FAILED/FILE NOT FOUND"; - $__error_text = << -Please contact your server-administrator. + $__error_title = strtoupper($rcmail->gettext('errnotfound')); + $__error_text = nl2br($rcmail->gettext('errnotfoundexplain') . "\n" . + $rcmail->gettext('errcontactserveradmin')); -

Failed request:
-http://$request_url

-EOF; + $__error_text .= '

' . $rcmail->gettext('errfailedrequest') . ":
\n//$request_url

"; } // database connection error @@ -101,6 +97,20 @@ else { } } +// inform plugins +if ($rcmail && $rcmail->plugins) { + $plugin = $rcmail->plugins->exec_hook('error_page', array( + 'code' => $ERROR_CODE, + 'title' => $__error_title, + 'text' => $__error_text, + )); + + if (!empty($plugin['title'])) + $__error_title = $plugin['title']; + if (!empty($plugin['text'])) + $__error_text = $plugin['text']; +} + $HTTP_ERR_CODE = $ERROR_CODE && $ERROR_CODE < 600 ? $ERROR_CODE : 500; // Ajax request @@ -113,7 +123,7 @@ if ($rcmail->output && $rcmail->output->type == 'js') { $__page_content = <<

$__error_title

-

$__error_text

+
$__error_text
EOF; -- cgit v1.2.3 From 4d9627c36a49918dbb5fe084173a01c6550ea790 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Mon, 23 Mar 2015 18:41:23 +0100 Subject: Wording --- program/localization/en_US/messages.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'program/localization/en_US') diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc index bcf89a441..a23bfd645 100644 --- a/program/localization/en_US/messages.inc +++ b/program/localization/en_US/messages.inc @@ -186,7 +186,7 @@ $messages['errfailedrequest'] = 'Failed request'; $messages['errauthorizationfailed'] = 'Authorization Failed'; $messages['errunauthorizedexplain'] = 'Could not verify that you are authorized to access this service!'; $messages['errrequestcheckfailed'] = 'Request Check Failed'; -$messages['errcsrfprotectionexplain'] = "For your protection, access to this resource is secured against CSRF.\nYou probably didn't log out before leaving the web application.\n\nHuman interaction is now required to continue."; +$messages['errcsrfprotectionexplain'] = "For your protection, access to this resource is secured against CSRF.\nIf you see this, you probably didn't log out before leaving the web application.\n\nHuman interaction is now required to continue."; $messages['errcontactserveradmin'] = 'Please contact your server-administrator.'; $messages['clicktoresumesession'] = 'Click here to resume your previous session'; -- cgit v1.2.3 From 09225a41ec7135031a4c0304b8dcdccd45904939 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Thu, 16 Apr 2015 10:55:32 +0200 Subject: Add option to place signature at bottom of the quoted text even in top-posting mode [sig_below] --- CHANGELOG | 1 + config/defaults.inc.php | 5 ++++ program/js/app.js | 6 +++-- program/js/editor.js | 51 +++++++++++++++++------------------ program/localization/en_US/labels.inc | 1 + program/steps/mail/compose.inc | 7 +++-- program/steps/settings/func.inc | 14 ++++++++++ program/steps/settings/save_prefs.inc | 1 + 8 files changed, 56 insertions(+), 30 deletions(-) (limited to 'program/localization/en_US') diff --git a/CHANGELOG b/CHANGELOG index 6c584fce1..c3049eb73 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ CHANGELOG Roundcube Webmail - Plugin API: Added message_part_body hook - Plugin API: Added message_ready hook - Plugin API: Add special onload() method to execute plugin actions before startup (session and GUI initialization) +- Add option to place signature at bottom of the quoted text even in top-posting mode [sig_below] - Fix handling of %-encoded entities in mailto: URLs (#1490346) - Fix zipped messages downloads after selecting all messages in a folder (#1490339) - Fix vpopmaild driver of password plugin diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 50ae71ed9..df8b612ea 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -1086,6 +1086,11 @@ $config['strip_existing_sig'] = true; // 3 - Forwards and Replies only $config['show_sig'] = 1; +// By default the signature is placed depending on cursor position (reply_mode). +// Sometimes it might be convenient to start the reply on top but keep +// the signature below the quoted text (sig_below = true). +$config['sig_below'] = false; + // Use MIME encoding (quoted-printable) for 8bit characters in message body $config['force_7bit'] = false; diff --git a/program/js/app.js b/program/js/app.js index 64fd548c9..b6b4d319c 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -3384,14 +3384,16 @@ function rcube_webmail() if (!html_mode) { pos = this.env.top_posting ? 0 : input_message.value.length; - this.set_caret_pos(input_message, pos); // add signature according to selected identity - // if we have HTML editor, signature is added in callback + // if we have HTML editor, signature is added in a callback if (input_from.prop('type') == 'select-one') { this.change_identity(input_from[0]); } + // set initial cursor position + this.set_caret_pos(input_message, pos); + // scroll to the bottom of the textarea (#1490114) if (pos) { $(input_message).scrollTop(input_message.scrollHeight); diff --git a/program/js/editor.js b/program/js/editor.js index 296a161ca..abd800ca3 100644 --- a/program/js/editor.js +++ b/program/js/editor.js @@ -485,32 +485,37 @@ function rcube_text_editor(config, id) sig = rcmail.env.signatures[id].text; sig = sig.replace(/\r\n/g, '\n'); - if (rcmail.env.top_posting) { - if (p >= 0) { // in place of removed signature - message = message.substring(0, p) + sig + message.substring(p, message.length); - cursor_pos = p - 1; - } - else if (!message) { // empty message - cursor_pos = 0; - message = '\n\n' + sig; - } - else if (pos = rcmail.get_caret_pos(input_message.get(0))) { // at cursor position + // in place of removed signature + if (p >= 0) { + message = message.substring(0, p) + sig + message.substring(p, message.length); + cursor_pos = p - 1; + } + // empty message + else if (!message) { + message = '\n\n' + sig; + cursor_pos = 0; + } + else if (rcmail.env.top_posting && !rcmail.env.sig_below) { + // at cursor position + if (pos = rcmail.get_caret_pos(input_message.get(0))) { message = message.substring(0, pos) + '\n' + sig + '\n\n' + message.substring(pos, message.length); cursor_pos = pos; } - else { // on top - cursor_pos = 0; + // on top + else { message = '\n\n' + sig + '\n\n' + message.replace(/^[\r\n]+/, ''); + cursor_pos = 0; } } else { message = message.replace(/[\r\n]+$/, ''); - cursor_pos = !rcmail.env.top_posting && message.length ? message.length+1 : 0; + cursor_pos = !rcmail.env.top_posting && message.length ? message.length + 1 : 0; message += '\n\n' + sig; } } - else + else { cursor_pos = rcmail.env.top_posting ? 0 : message.length; + } input_message.val(message); @@ -528,24 +533,18 @@ function rcube_text_editor(config, id) sigElem = doc.createElement('div'); sigElem.setAttribute('id', '_rc_sig'); - if (rcmail.env.top_posting) { - // if no existing sig and top posting then insert at caret pos + if (rcmail.env.top_posting && !rcmail.env.sig_below) { this.editor.getWin().focus(); // correct focus in IE & Chrome var node = this.editor.selection.getNode(); - if (node.nodeName == 'BODY') { - // no real focus, insert at start - body.insertBefore(sigElem, body.firstChild); - body.insertBefore(doc.createElement('br'), body.firstChild); - } - else { - body.insertBefore(sigElem, node.nextSibling); - body.insertBefore(doc.createElement('br'), node.nextSibling); - } + + // insert at start or at cursor position if found + body.insertBefore(sigElem, node.nodeName == 'BODY' ? body.firstChild : node.nextSibling); + body.insertBefore(doc.createElement('p'), sigElem); } else { body.appendChild(sigElem); - position_element = $(sigElem).prev(); + position_element = rcmail.env.top_posting ? body.firstChild : $(sigElem).prev(); } } diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index fac52ba1e..8202b140d 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -509,6 +509,7 @@ $labels['autoaddsignature'] = 'Automatically add signature'; $labels['newmessageonly'] = 'new message only'; $labels['replyandforwardonly'] = 'replies and forwards only'; $labels['insertsignature'] = 'Insert signature'; +$labels['sigbelow'] = 'Place signature below the quoted message'; $labels['previewpanemarkread'] = 'Mark previewed messages as read'; $labels['afternseconds'] = 'after $n seconds'; $labels['reqmdn'] = 'Always request a return receipt'; diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index ba6f334c9..5009c525a 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -91,6 +91,7 @@ $OUTPUT->set_env('compose_id', $COMPOSE['id']); $OUTPUT->set_env('session_id', session_id()); $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder()); $OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0); +$OUTPUT->set_env('sig_below', $RCMAIL->config->get('sig_below')); $OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ','))); $OUTPUT->set_env('save_localstorage', (bool)$RCMAIL->config->get('compose_save_localstorage')); $OUTPUT->set_env('is_sent', false); @@ -612,8 +613,10 @@ function rcmail_compose_header_from($attrib) if (count($MESSAGE->identities)) { $a_signatures = array(); $identities = array(); - $separator = intval($RCMAIL->config->get('reply_mode')) > 0 - && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- '; + $top_posting = intval($RCMAIL->config->get('reply_mode')) > 0 + && !$RCMAIL->config->get('sig_below') + && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD); + $separator = $top_posting ? '---' : '-- '; $field_attrib['onchange'] = rcmail_output::JS_OBJECT_NAME.".change_identity(this)"; $select_from = new html_select($field_attrib); diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc index 46aed3019..c763dd39a 100644 --- a/program/steps/settings/func.inc +++ b/program/steps/settings/func.inc @@ -845,6 +845,20 @@ function rcmail_user_prefs($current = null) ); } + if (!isset($no_override['sig_below'])) { + if (!$current) { + continue 2; + } + + $field_id = 'rcmfd_sig_below'; + $input = new html_checkbox(array('name' => '_sig_below', 'id' => $field_id, 'value' => 1)); + + $blocks['sig']['options']['sig_below'] = array( + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('sigbelow'))), + 'content' => $input->show($RCMAIL->config->get('sig_below') ? 1 : 0), + ); + } + if (!isset($no_override['strip_existing_sig'])) { if (!$current) { continue 2; diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc index f0ce9c9a3..4ecaa70e6 100644 --- a/program/steps/settings/save_prefs.inc +++ b/program/steps/settings/save_prefs.inc @@ -85,6 +85,7 @@ case 'compose': 'spellcheck_ignore_caps' => isset($_POST['_spellcheck_ignore_caps']) ? true : false, 'show_sig' => isset($_POST['_show_sig']) ? intval($_POST['_show_sig']) : 1, 'reply_mode' => isset($_POST['_reply_mode']) ? intval($_POST['_reply_mode']) : 0, + 'sig_below' => isset($_POST['_sig_below']) ? true : false, 'strip_existing_sig' => isset($_POST['_strip_existing_sig']), 'default_font' => rcube_utils::get_input_value('_default_font', rcube_utils::INPUT_POST), 'default_font_size' => rcube_utils::get_input_value('_default_font_size', rcube_utils::INPUT_POST), -- cgit v1.2.3