From 3412e50b54e3daac8745234e21ab6e72be0ed165 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli <thomas@roundcube.net> Date: Wed, 04 Jun 2014 11:20:33 -0400 Subject: [PATCH] Fix attachment menu structure and aria-attributes --- program/steps/mail/compose.inc | 176 +++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 107 insertions(+), 69 deletions(-) diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index 8303944..b569385 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -62,36 +62,6 @@ rcmail_process_compose_params($COMPOSE); - // add attachments listed by message_compose hook - if (is_array($plugin['attachments'])) { - foreach ($plugin['attachments'] as $attach) { - // we have structured data - if (is_array($attach)) { - $attachment = $attach; - } - // only a file path is given - else { - $filename = basename($attach); - $attachment = array( - 'group' => $COMPOSE_ID, - 'name' => $filename, - 'mimetype' => rcube_mime::file_content_type($attach, $filename), - 'path' => $attach, - ); - } - - // save attachment if valid - if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) { - $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); - } - - if ($attachment['status'] && !$attachment['abort']) { - unset($attachment['data'], $attachment['status'], $attachment['abort']); - $COMPOSE['attachments'][$attachment['id']] = $attachment; - } - } - } - // check if folder for saving sent messages exists and is subscribed (#1486802) if ($sent_folder = $COMPOSE['param']['sent_mbox']) { rcmail_check_sent_folder($sent_folder, true); @@ -111,7 +81,8 @@ 'nobodywarning', 'notsentwarning', 'notuploadedwarning', 'savingmessage', 'sendingmessage', 'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'uploadingmany', 'fileuploaderror', 'sendmessage', 'savenewresponse', 'responsename', 'responsetext', 'save', - 'savingresponse', 'restoresavedcomposedata', 'restoremessage', 'delete', 'restore', 'ignore'); + 'savingresponse', 'restoresavedcomposedata', 'restoremessage', 'delete', 'restore', 'ignore', + 'selectimportfile'); $OUTPUT->set_pagetitle($RCMAIL->gettext('compose')); @@ -121,10 +92,13 @@ $OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0); $OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ','))); +$drafts_mbox = $RCMAIL->config->get('drafts_mbox'); +$config_show_sig = $RCMAIL->config->get('show_sig', 1); + // add config parameters to client script -if (!empty($CONFIG['drafts_mbox'])) { - $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']); - $OUTPUT->set_env('draft_autosave', $CONFIG['draft_autosave']); +if (strlen($drafts_mbox)) { + $OUTPUT->set_env('drafts_mailbox', $drafts_mbox); + $OUTPUT->set_env('draft_autosave', $RCMAIL->config->get('draft_autosave')); } // default font for HTML editor @@ -142,7 +116,7 @@ if ($msg_uid = $COMPOSE['param']['draft_uid']) { $compose_mode = RCUBE_COMPOSE_DRAFT; $OUTPUT->set_env('draft_id', $msg_uid); - $RCMAIL->storage->set_folder($CONFIG['drafts_mbox']); + $RCMAIL->storage->set_folder($drafts_mbox); } else if ($msg_uid = $COMPOSE['param']['reply_uid']) { $compose_mode = RCUBE_COMPOSE_REPLY; @@ -159,7 +133,6 @@ $COMPOSE['mode'] = $compose_mode; $OUTPUT->set_env('compose_mode', $compose_mode); -$config_show_sig = $RCMAIL->config->get('show_sig', 1); if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) { // don't add signature in draft/edit mode, we'll also not remove the old-one // but only on page display, later we should be able to change identity/sig (#1489229) @@ -186,7 +159,9 @@ $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$msg_uid]); } else { - $prefer_html = $CONFIG['prefer_html'] || $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT; + $prefer_html = $RCMAIL->config->get('prefer_html') || $RCMAIL->config->get('htmleditor') + || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT; + $RCMAIL->config->set('prefer_html', $prefer_html); } @@ -204,14 +179,20 @@ if (!$MESSAGE->headers) { // error } - else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - $COMPOSE['reply_uid'] = $msg_uid; + else if ($compose_mode == RCUBE_COMPOSE_FORWARD || $compose_mode == RCUBE_COMPOSE_REPLY) { + if ($compose_mode == RCUBE_COMPOSE_REPLY) { + $COMPOSE['reply_uid'] = $msg_uid; + + if (!empty($COMPOSE['param']['all'])) { + $MESSAGE->reply_all = $COMPOSE['param']['all']; + } + } + else { + $COMPOSE['forward_uid'] = $msg_uid; + } + $COMPOSE['reply_msgid'] = $MESSAGE->headers->messageID; $COMPOSE['references'] = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID); - - if (!empty($COMPOSE['param']['all'])) { - $MESSAGE->reply_all = $COMPOSE['param']['all']; - } // Save the sent message in the same folder of the message being replied to if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $COMPOSE['mailbox']) @@ -267,6 +248,10 @@ } } +if (!empty($COMPOSE['reply_msgid'])) { + $OUTPUT->set_env('reply_msgid', $COMPOSE['reply_msgid']); +} + $MESSAGE->compose = array(); // get user's identities @@ -290,6 +275,7 @@ $a_recipients = array(); $parts = array('to', 'cc', 'bcc', 'replyto', 'followupto'); $separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; +$from_email = @mb_strtolower($MESSAGE->compose['from_email']); foreach ($parts as $header) { $fvalue = ''; @@ -387,21 +373,20 @@ continue; } - $mailto = format_email(rcube_utils::idn_to_utf8($addr_part['mailto'])); + // According to RFC5321 local part of email address is case-sensitive + // however, here it is better to compare addresses in case-insensitive manner + $mailto = format_email(rcube_utils::idn_to_utf8($addr_part['mailto'])); + $mailto_lc = mb_strtolower($addr_part['mailto']); - if (!in_array($mailto, $a_recipients) - && ($header == 'to' - || $compose_mode != RCUBE_COMPOSE_REPLY - || empty($MESSAGE->compose['from_email']) - || $mailto != $MESSAGE->compose['from_email']) + if (($header == 'to' || $compose_mode != RCUBE_COMPOSE_REPLY || $mailto_lc != $from_email) + && !in_array($mailto_lc, $a_recipients) ) { - if ($addr_part['name'] && $addr_part['mailto'] != $addr_part['name']) - $string = format_email_recipient($mailto, $addr_part['name']); - else - $string = $mailto; + if ($addr_part['name'] && $mailto != $addr_part['name']) { + $mailto = format_email_recipient($mailto, $addr_part['name']); + } - $fvalue[] = $string; - $a_recipients[] = $addr_part['mailto']; + $fvalue[] = $mailto; + $a_recipients[] = $mailto_lc; } } @@ -478,6 +463,11 @@ } } + // resolve _forward_uid=* to an absolute list of messages from a search result + if ($COMPOSE['param']['forward_uid'] == '*' && is_object($_SESSION['search'][1])) { + $COMPOSE['param']['forward_uid'] = $_SESSION['search'][1]->get(); + } + // clean HTML message body which can be submitted by URL if (!empty($COMPOSE['param']['body'])) { $COMPOSE['param']['body'] = rcmail_wash_html($COMPOSE['param']['body'], array('safe' => false, 'inline_html' => true), array()); @@ -491,6 +481,36 @@ // pipe compose parameters thru plugins $plugin = $RCMAIL->plugins->exec_hook('message_compose', $COMPOSE); $COMPOSE['param'] = array_merge($COMPOSE['param'], $plugin['param']); + + // add attachments listed by message_compose hook + if (is_array($plugin['attachments'])) { + foreach ($plugin['attachments'] as $attach) { + // we have structured data + if (is_array($attach)) { + $attachment = $attach + array('group' => $COMPOSE_ID); + } + // only a file path is given + else { + $filename = basename($attach); + $attachment = array( + 'group' => $COMPOSE_ID, + 'name' => $filename, + 'mimetype' => rcube_mime::file_content_type($attach, $filename), + 'path' => $attach, + ); + } + + // save attachment if valid + if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) { + $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); + } + + if ($attachment['status'] && !$attachment['abort']) { + unset($attachment['data'], $attachment['status'], $attachment['abort']); + $COMPOSE['attachments'][$attachment['id']] = $attachment; + } + } + } } function rcmail_compose_headers($attrib) @@ -849,7 +869,7 @@ function rcmail_compose_body($attrib) { - global $RCMAIL, $CONFIG, $OUTPUT, $HTML_MODE, $MESSAGE_BODY; + global $RCMAIL, $OUTPUT, $HTML_MODE, $MESSAGE_BODY; list($form_start, $form_end) = get_form_tags($attrib); unset($attrib['form']); @@ -901,7 +921,7 @@ $RCMAIL->html_editor(); // Set language list - if (!empty($CONFIG['enable_spellcheck'])) { + if ($RCMAIL->config->get('enable_spellcheck')) { $engine = new rcube_spellchecker(); $dictionary = (bool) $RCMAIL->config->get('spellcheck_dictionary'); $spellcheck_langs = $engine->languages(); @@ -957,7 +977,7 @@ $OUTPUT->set_env('spellcheck_langs', join(',', $editor_lang_set)); } - $out .= "\n".'<iframe name="savetarget" src="program/resources/blank.gif" style="width:0;height:0;border:none;visibility:hidden;"></iframe>'; + $out .= "\n".'<iframe name="savetarget" src="program/resources/blank.gif" style="width:0;height:0;border:none;visibility:hidden;" aria-hidden="true"></iframe>'; return $out; } @@ -1233,6 +1253,7 @@ $storage = $RCMAIL->get_storage(); $names = array(); + $refs = array(); $loaded_attachments = array(); foreach ((array)$COMPOSE['attachments'] as $attachment) { @@ -1243,7 +1264,10 @@ $index = $storage->index(null, rcmail_sort_column(), rcmail_sort_order()); $COMPOSE['forward_uid'] = $index->get(); } - else { + else if (!is_array($COMPOSE['forward_uid']) && strpos($COMPOSE['forward_uid'], ':')) { + $COMPOSE['forward_uid'] = rcube_imap_generic::uncompressMessageSet($COMPOSE['forward_uid']); + } + else if (is_string($COMPOSE['forward_uid'])) { $COMPOSE['forward_uid'] = explode(',', $COMPOSE['forward_uid']); } @@ -1312,6 +1336,18 @@ else if ($path) { @unlink($path); } + + if ($message->headers->messageID) { + $refs[] = $message->headers->messageID; + } + } + + // set In-Reply-To and References headers + if (count($refs) == 1) { + $COMPOSE['reply_msgid'] = $refs[0]; + } + if (!empty($refs)) { + $COMPOSE['references'] = implode(' ', $refs); } } @@ -1453,20 +1489,21 @@ function rcmail_compose_attachment_list($attrib) { - global $RCMAIL, $OUTPUT, $CONFIG, $COMPOSE; + global $RCMAIL, $OUTPUT, $COMPOSE; // add ID if not given if (!$attrib['id']) $attrib['id'] = 'rcmAttachmentList'; - $out = "\n"; - $jslist = array(); - $button = ''; + $out = "\n"; + $jslist = array(); + $button = ''; + $skin_path = $RCMAIL->config->get('skin_path'); if (is_array($COMPOSE['attachments'])) { if ($attrib['deleteicon']) { $button = html::img(array( - 'src' => $CONFIG['skin_path'] . $attrib['deleteicon'], + 'src' => $skin_path . $attrib['deleteicon'], 'alt' => $RCMAIL->gettext('delete') )); } @@ -1503,13 +1540,13 @@ } if ($attrib['deleteicon']) - $COMPOSE['deleteicon'] = $CONFIG['skin_path'] . $attrib['deleteicon']; + $COMPOSE['deleteicon'] = $skin_path . $attrib['deleteicon']; else if (rcube_utils::get_boolean($attrib['textbuttons'])) $COMPOSE['textbuttons'] = true; if ($attrib['cancelicon']) - $OUTPUT->set_env('cancelicon', $CONFIG['skin_path'] . $attrib['cancelicon']); + $OUTPUT->set_env('cancelicon', $skin_path . $attrib['cancelicon']); if ($attrib['loadingicon']) - $OUTPUT->set_env('loadingicon', $CONFIG['skin_path'] . $attrib['loadingicon']); + $OUTPUT->set_env('loadingicon', $skin_path . $attrib['loadingicon']); $OUTPUT->set_env('attachments', $jslist); $OUTPUT->add_gui_object('attachmentlist', $attrib['id']); @@ -1592,7 +1629,7 @@ $sel = 0; $out = $form_start ? "$form_start\n" : ''; - $out .= $selector->show(strval($sel)); + $out .= $selector->show((int) $sel); $out .= $form_end ? "\n$form_end" : ''; return $out; @@ -1827,9 +1864,10 @@ foreach ($RCMAIL->get_compose_responses(true) as $response) { $key = $response['key']; $item = html::a(array( - 'href '=> '#'.urlencode($response['name']), + 'href' => '#'.urlencode($response['name']), 'class' => rtrim('insertresponse ' . $attrib['itemclass']), 'unselectable' => 'on', + 'tabindex' => '0', 'rel' => $key, ), rcube::Q($response['name'])); -- Gitblit v1.9.1