From 8eefbb2158c43b51a8c33e6c480cbe61539b9535 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Mon, 27 Aug 2012 04:16:04 -0400 Subject: [PATCH] Add option to enable HTML editor on forwarding (#1488517) --- program/steps/mail/compose.inc | 147 ++++++++++++++++++++++++++++++++++-------------- 1 files changed, 103 insertions(+), 44 deletions(-) diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index d5356e0..e57b44a 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -17,9 +17,6 @@ +-----------------------------------------------------------------------+ | Author: Thomas Bruederli <roundcube@gmail.com> | +-----------------------------------------------------------------------+ - - $Id$ - */ // define constants for message compose mode @@ -29,7 +26,6 @@ define('RCUBE_COMPOSE_EDIT', 0x0109); $MESSAGE_FORM = null; -$MESSAGE = null; $COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GET); $COMPOSE = null; @@ -119,7 +115,11 @@ } // redirect to a unique URL with all parameters stored in session - $OUTPUT->redirect(array('_action' => 'compose', '_id' => $COMPOSE['id'])); + $OUTPUT->redirect(array( + '_action' => 'compose', + '_id' => $COMPOSE['id'], + '_search' => $_REQUEST['_search'], + )); } @@ -139,7 +139,7 @@ // set current mailbox in client environment $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder()); $OUTPUT->set_env('sig_above', $RCMAIL->config->get('sig_above', false)); -$OUTPUT->set_env('top_posting', $RCMAIL->config->get('top_posting', false)); +$OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0); $OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ','))); // default font for HTML editor @@ -181,7 +181,7 @@ $MESSAGE = new rcube_message($msg_uid); // make sure message is marked as read - if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) + if ($MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) $RCMAIL->storage->set_flag($msg_uid, 'SEEN'); if (!empty($MESSAGE->headers->charset)) @@ -241,6 +241,9 @@ $MESSAGE->forward_attachment = true; } } +else { + $MESSAGE = new stdClass(); +} $MESSAGE->compose = array(); @@ -249,7 +252,8 @@ if (count($MESSAGE->identities)) { foreach ($MESSAGE->identities as $idx => $ident) { - $email = mb_strtolower(rcube_idn_to_utf8($ident['email'])); + $ident['email'] = format_email($ident['email']); + $email = format_email(rcube_idn_to_utf8($ident['email'])); $MESSAGE->identities[$idx]['email_ascii'] = $ident['email']; $MESSAGE->identities[$idx]['ident'] = format_email_recipient($ident['email'], $ident['name']); @@ -274,7 +278,7 @@ $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset); foreach ($a_to as $addr) { if (!empty($addr['mailto'])) { - $a_recipients[] = strtolower($addr['mailto']); + $a_recipients[] = format_email($addr['mailto']); $a_names[] = $addr['name']; } } @@ -283,7 +287,7 @@ $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset); foreach ($a_cc as $addr) { if (!empty($addr['mailto'])) { - $a_recipients[] = strtolower($addr['mailto']); + $a_recipients[] = format_email($addr['mailto']); $a_names[] = $addr['name']; } } @@ -430,7 +434,7 @@ if (empty($addr_part['mailto'])) continue; - $mailto = mb_strtolower(rcube_idn_to_utf8($addr_part['mailto'])); + $mailto = format_email(rcube_idn_to_utf8($addr_part['mailto'])); if (!in_array($mailto, $a_recipients) && ($header == 'to' || empty($MESSAGE->compose['from_email']) || $mailto != $MESSAGE->compose['from_email']) @@ -526,7 +530,7 @@ function rcmail_compose_header_from($attrib) { - global $MESSAGE, $OUTPUT; + global $MESSAGE, $OUTPUT, $RCMAIL, $compose_mode; // pass the following attributes to the form class $field_attrib = array('name' => '_from'); @@ -537,6 +541,8 @@ if (count($MESSAGE->identities)) { $a_signatures = array(); + $separator = $RCMAIL->config->get('sig_above') + && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- '; $field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)"; $select_from = new html_select($field_attrib); @@ -550,13 +556,27 @@ // add signature to array if (!empty($sql_arr['signature']) && empty($COMPOSE['param']['nosig'])) { - $a_signatures[$identity_id]['text'] = $sql_arr['signature']; - $a_signatures[$identity_id]['is_html'] = ($sql_arr['html_signature'] == 1) ? true : false; - if ($a_signatures[$identity_id]['is_html']) - { - $h2t = new html2text($a_signatures[$identity_id]['text'], false, false); - $a_signatures[$identity_id]['plain_text'] = trim($h2t->get_text()); + $text = $html = $sql_arr['signature']; + + if ($sql_arr['html_signature']) { + $h2t = new html2text($sql_arr['signature'], false, false); + $text = trim($h2t->get_text()); } + else { + $html = htmlentities($html, ENT_NOQUOTES, RCMAIL_CHARSET); + } + + if (!preg_match('/^--[ -]\r?\n/m', $text)) { + $text = $separator . "\n" . $text; + $html = $separator . "<br>" . $html; + } + + if (!$sql_arr['html_signature']) { + $html = "<pre>" . $html . "</pre>"; + } + + $a_signatures[$identity_id]['text'] = $text; + $a_signatures[$identity_id]['html'] = $html; } } @@ -590,9 +610,12 @@ $useHtml = $MESSAGE->has_html_part(false); } else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - $useHtml = ($html_editor == 1 || ($html_editor == 2 && $MESSAGE->has_html_part(false))); + $useHtml = ($html_editor == 1 || ($html_editor >= 2 && $MESSAGE->has_html_part(false))); } - else { // RCUBE_COMPOSE_FORWARD or NEW + else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { + $useHtml = ($html_editor == 1 || ($html_editor == 3 && $MESSAGE->has_html_part(false))); + } + else { $useHtml = ($html_editor == 1); } @@ -621,12 +644,13 @@ rcmail_write_forward_attachment($MESSAGE); } // reply/edit/draft/forward - else if ($compose_mode) { + else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || $RCMAIL->config->get('reply_mode') != -1)) { $isHtml = rcmail_compose_editor_mode(); if (!empty($MESSAGE->parts)) { foreach ($MESSAGE->parts as $part) { - if ($part->type != 'content' || !$part->size) { + // skip no-content and attachment parts (#1488557) + if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) { continue; } @@ -659,12 +683,12 @@ unset($plugin); // add blocked.gif attachment (#1486516) - if ($isHtml && preg_match('#<img src="\./program/blocked\.gif"#', $body)) { - if ($attachment = rcmail_save_image('program/blocked.gif', 'image/gif')) { + if ($isHtml && preg_match('#<img src="\./program/resources/blocked\.gif"#', $body)) { + if ($attachment = rcmail_save_image('program/resources/blocked.gif', 'image/gif')) { $COMPOSE['attachments'][$attachment['id']] = $attachment; - $body = preg_replace('#\./program/blocked\.gif#', - $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id'], - $body); + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); + $body = preg_replace('#\./program/resources/blocked\.gif#', $url, $body); } } @@ -764,7 +788,9 @@ // If desired, set this textarea to be editable by TinyMCE if ($isHtml) { + $MESSAGE_BODY = htmlentities($MESSAGE_BODY, ENT_NOQUOTES, RCMAIL_CHARSET); $attrib['class'] = 'mce_editor'; + $attrib['is_escaped'] = true; $textarea = new html_textarea($attrib); $out .= $textarea->show($MESSAGE_BODY); } @@ -813,6 +839,9 @@ if (!$spellcheck_langs[$lang]) $lang = 'en'; + $OUTPUT->set_env('spell_langs', $spellcheck_langs); + $OUTPUT->set_env('spell_lang', $lang); + $editor_lang_set = array(); foreach ($spellcheck_langs as $key => $name) { $editor_lang_set[] = ($key == $lang ? '+' : '') . JQ($name).'='.JQ($key); @@ -830,11 +859,11 @@ "googie.lang_learn_word = \"%s\";\n". "googie.setLanguages(%s);\n". "googie.setCurrentLanguage('%s');\n". - "googie.setSpellContainer('spellcheck-control');\n". + "googie.setDecoration(false);\n". "googie.decorateTextarea('%s');\n". "%s.set_env('spellcheck', googie);", $RCMAIL->output->get_skin_path(), - $RCMAIL->url(array('_task' => 'utils', '_action' => 'spell')), + $RCMAIL->url(array('_task' => 'utils', '_action' => 'spell', '_remote' => 1)), !empty($dictionary) ? 'true' : 'false', JQ(Q(rcube_label('checkspelling'))), JQ(Q(rcube_label('resumeediting'))), @@ -851,7 +880,7 @@ $OUTPUT->set_env('spellcheck_langs', join(',', $editor_lang_set)); } - $out .= "\n".'<iframe name="savetarget" src="program/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;"></iframe>'; return $out; } @@ -880,8 +909,9 @@ $prefix .= "\n"; $suffix = ''; - if ($RCMAIL->config->get('top_posting')) + if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting $prefix = "\n\n\n" . $prefix; + } } else { // save inline images to files @@ -895,7 +925,7 @@ $prefix = '<p>' . Q($prefix) . "</p>\n"; $prefix .= '<blockquote>'; - if ($RCMAIL->config->get('top_posting')) { + if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting $prefix = '<br>' . $prefix; $suffix = '</blockquote>'; } @@ -950,18 +980,18 @@ "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", rcube_label('subject'), Q($MESSAGE->subject), rcube_label('date'), Q($date), - rcube_label('from'), htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $charset), - rcube_label('to'), htmlspecialchars(Q($MESSAGE->get_header('to'), 'replace'), ENT_COMPAT, $charset)); + rcube_label('from'), Q($MESSAGE->get_header('from'), 'replace'), + rcube_label('to'), Q($MESSAGE->get_header('to'), 'replace')); if ($MESSAGE->headers->cc) $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", rcube_label('cc'), - htmlspecialchars(Q($MESSAGE->get_header('cc'), 'replace'), ENT_COMPAT, $charset)); + Q($MESSAGE->get_header('cc'), 'replace')); if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from) $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", rcube_label('replyto'), - htmlspecialchars(Q($MESSAGE->get_header('replyto'), 'replace'), ENT_COMPAT, $charset)); + Q($MESSAGE->get_header('replyto'), 'replace')); $prefix .= "</tbody></table><br>"; } @@ -1041,7 +1071,8 @@ if (!$skip && ($attachment = rcmail_save_attachment($message, $pid))) { $COMPOSE['attachments'][$attachment['id']] = $attachment; if ($bodyIsHtml && ($part->content_id || $part->content_location)) { - $url = $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id']; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); if ($part->content_id) $cid_map['cid:'.$part->content_id] = $url; else @@ -1066,7 +1097,8 @@ if (($part->content_id || $part->content_location) && $part->filename) { if ($attachment = rcmail_save_attachment($message, $pid)) { $COMPOSE['attachments'][$attachment['id']] = $attachment; - $url = $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id']; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); if ($part->content_id) $cid_map['cid:'.$part->content_id] = $url; else @@ -1153,10 +1185,22 @@ $data = $message->get_part_content($pid); } + $mimetype = $part->ctype_primary . '/' . $part->ctype_secondary; + $filename = $part->filename; + if (!strlen($filename)) { + if ($mimetype == 'text/html') { + $filename = rcube_label('htmlmessage'); + } + else { + $filename = 'Part_'.$pid; + } + $filename .= '.' . $part->ctype_secondary; + } + $attachment = array( 'group' => $COMPOSE['id'], - 'name' => $part->filename ? $part->filename : 'Part_'.$pid.'.'.$part->ctype_secondary, - 'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary, + 'name' => $filename, + 'mimetype' => $mimetype, 'content_id' => $part->content_id, 'data' => $data, 'path' => $path, @@ -1393,7 +1437,7 @@ $attrib['value'] = '1'; $checkbox = new html_checkbox($attrib); - if ($MESSAGE && in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) + if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) $mdn_default = (bool) $MESSAGE->headers->mdn_to; else $mdn_default = $RCMAIL->config->get('mdn_default'); @@ -1502,6 +1546,7 @@ $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task)); $hiddenfields->add(array('name' => '_action', 'value' => 'send')); $hiddenfields->add(array('name' => '_id', 'value' => $COMPOSE['id'])); + $hiddenfields->add(array('name' => '_attachments')); $form_start = empty($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : ''; $form_start .= $hiddenfields->show(); @@ -1519,7 +1564,7 @@ } -function rcmail_adressbook_list($attrib = array()) +function rcmail_addressbook_list($attrib = array()) { global $RCMAIL, $OUTPUT; @@ -1548,7 +1593,7 @@ $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id))); } - $OUTPUT->add_gui_object('adressbookslist', $attrib['id']); + $OUTPUT->add_gui_object('addressbookslist', $attrib['id']); return html::tag('ul', $attrib, $out, html::$common_attrib); } @@ -1570,6 +1615,19 @@ } +/** + * Register a certain container as active area to drop files onto + */ +function compose_file_drop_area($attrib) +{ + global $OUTPUT; + + if ($attrib['id']) { + $OUTPUT->add_gui_object('filedrop', $attrib['id']); + $OUTPUT->set_env('filedrop', array('action' => 'upload', 'fieldname' => '_attachments')); + } +} + // register UI objects $OUTPUT->add_handlers(array( @@ -1579,12 +1637,13 @@ 'composeattachmentlist' => 'rcmail_compose_attachment_list', 'composeattachmentform' => 'rcmail_compose_attachment_form', 'composeattachment' => 'rcmail_compose_attachment_field', + 'filedroparea' => 'compose_file_drop_area', 'priorityselector' => 'rcmail_priority_selector', 'editorselector' => 'rcmail_editor_selector', 'receiptcheckbox' => 'rcmail_receipt_checkbox', 'dsncheckbox' => 'rcmail_dsn_checkbox', 'storetarget' => 'rcmail_store_target_selection', - 'adressbooks' => 'rcmail_adressbook_list', + 'addressbooks' => 'rcmail_addressbook_list', 'addresslist' => 'rcmail_contacts_list', )); -- Gitblit v1.9.1