From ca9f1cefefcec92e06426308ce9fbbb27db995ef Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Fri, 6 Nov 2009 23:03:04 -0700 Subject: [PATCH] Move message rendering code for imp/dimp into shared function For message/rfc822 data, indicate which data is part of the original message data by wrapping this data entirely within a div with a border. --- imp/config/mime_drivers.php.dist | 19 ++++++- imp/lib/Contents.php | 6 ++- imp/lib/Mime/Viewer/Rfc822.php | 30 +++++++++++ imp/lib/UI/Message.php | 105 +++++++++++++++++++++++++++++++++++++++ imp/lib/Views/ShowMessage.php | 64 +++--------------------- imp/message.php | 77 ++++------------------------ imp/themes/ie6_or_less.css | 2 +- imp/themes/ie7.css | 2 +- imp/themes/screen.css | 16 ++++-- 9 files changed, 188 insertions(+), 133 deletions(-) create mode 100644 imp/lib/Mime/Viewer/Rfc822.php diff --git a/imp/config/mime_drivers.php.dist b/imp/config/mime_drivers.php.dist index 621c4c7c5..e6b05132f 100644 --- a/imp/config/mime_drivers.php.dist +++ b/imp/config/mime_drivers.php.dist @@ -31,6 +31,7 @@ * pgp PGP signed/encrypted messages * plain URL syntax highlighting for text/plain parts * related multipart/related parts + * rfc822 Digested messages (RFC 2046 [5.2.1]) * smil SMIL documents * smime S/MIME signed/encrypted messages * status Mail delivery status messages @@ -39,8 +40,8 @@ */ $mime_drivers_map['imp']['registered'] = array( 'alternative', 'appledouble', 'enriched', 'html', 'images', 'itip', - 'mdn', 'partial', 'pdf', 'pgp', 'plain', 'related', 'smil', 'smime', - 'status', 'tnef', 'zip' + 'mdn', 'partial', 'pdf', 'pgp', 'plain', 'related', 'rfc822', 'smil', + 'smime', 'status', 'tnef', 'zip' ); /** @@ -271,6 +272,20 @@ $mime_drivers['imp']['partial'] = array( ); /** + * Digest message (RFC 2046 [5.2.1]) settings + * YOU SHOULD NOT NORMALLY ALTER THIS SETTING. + */ +$mime_drivers['imp']['rfc822'] = array( + 'inline' => false, + 'handles' => array( + 'message/rfc822', 'x-extension/eml' + ), + 'icons' => array( + 'default' => 'mail.png' + ) +); + +/** * MS-TNEF Attachment (application/ms-tnef) settings * YOU SHOULD NOT NORMALLY ALTER THIS SETTING. */ diff --git a/imp/lib/Contents.php b/imp/lib/Contents.php index b7666fda3..551ddac9f 100644 --- a/imp/lib/Contents.php +++ b/imp/lib/Contents.php @@ -378,10 +378,14 @@ class IMP_Contents * * * @return array See Horde_Mime_Viewer_Driver::render(). The following - * fields may also be present: + * fields may also be present in addition to the fields + * defined in Horde_Mime_Viewer_Driver: * 'js' - (array) A list of javascript commands to run * after the content is displayed on screen. * 'name' - (string) Contains the MIME name information. + * 'wrap' - (string) If present, indicates that this + * part, and all child parts, will be wrapped + * in a DIV with the given class name. */ public function renderMIMEPart($mime_id, $mode, $options = array()) { diff --git a/imp/lib/Mime/Viewer/Rfc822.php b/imp/lib/Mime/Viewer/Rfc822.php new file mode 100644 index 000000000..e16202e87 --- /dev/null +++ b/imp/lib/Mime/Viewer/Rfc822.php @@ -0,0 +1,30 @@ + + * @package Horde_Mime + */ +class IMP_Horde_Mime_Viewer_Rfc822 extends Horde_Mime_Viewer_Rfc822 +{ + /** + * Return the rendered information about the Horde_Mime_Part object. + * + * @return array See Horde_Mime_Viewer_Driver::render(). + */ + protected function _renderInfo() + { + $ret = parent::_renderInfo(); + if (!empty($ret)) { + $ret[$this->_mimepart->getMimeId()]['wrap'] = 'mimePartWrap'; + } + return $ret; + } + +} diff --git a/imp/lib/UI/Message.php b/imp/lib/UI/Message.php index 718800100..a5394c67c 100644 --- a/imp/lib/UI/Message.php +++ b/imp/lib/UI/Message.php @@ -467,6 +467,111 @@ class IMP_UI_Message } /** + * Output inline message display for the imp and dimp views. + * + * @param object $imp_contents The IMP_Contents object containing the + * message data. + * @param integer $contents_mask The mask needed for a + * IMP_Contents::getSummary() call. + * @param array $part_info_display The list of summary fields to display. + * @param string $show_parts The value of the 'show_parts' pref. + * + * @return array An array with the following keys: + *
+     * 'atc_parts' - (array) The list of attachment MIME IDs.
+     * 'display_ids' - (array) The list of display MIME IDs.
+     * 'js_onload' - (array) A list of javascript code to run onload.
+     * 'msgtext' - (string) The rendered HTML code.
+     * 
+ */ + public function getInlineOutput($imp_contents, $contents_mask, + $part_info_display, $show_parts) + { + $atc_parts = $display_ids = $js_onload = $wrap_ids = array(); + $msgtext = ''; + $parts_list = $imp_contents->getContentTypeMap(); + + if ($show_parts == 'all') { + $atc_parts = array_keys($parts_list); + } + + foreach ($parts_list as $mime_id => $mime_type) { + if (in_array($mime_id, $display_ids, true)) { + continue; + } + + if (!($render_mode = $imp_contents->canDisplay($mime_id, IMP_Contents::RENDER_INLINE | IMP_Contents::RENDER_INFO))) { + if ($imp_contents->isAttachment($mime_type)) { + if ($show_parts == 'atc') { + $atc_parts[] = $mime_id; + } + + if ($GLOBALS['prefs']->getValue('atc_display')) { + $msgtext .= $this->formatSummary($imp_contents->getSummary($mime_id, $contents_mask), $part_info_display, true); + } + } + continue; + } + + $render_part = $imp_contents->renderMIMEPart($mime_id, $render_mode); + if (($render_mode & IMP_Contents::RENDER_INLINE) && + empty($render_part)) { + /* This meant that nothing was rendered - allow this part to + * appear in the attachment list instead. */ + if ($show_parts == 'atc') { + $atc_parts[] = $mime_id; + } + continue; + } + + reset($render_part); + while (list($id, $info) = each($render_part)) { + $display_ids[] = $id; + + if (empty($info)) { + continue; + } + + while (count($wrap_ids)) { + if (strpos(strval($id), strval(end($wrap_ids))) === 0) { + break; + } + array_pop($wrap_ids); + $msgtext .= ''; + } + if (!empty($info['wrap'])) { + $msgtext .= '
'; + $wrap_ids[] = $mime_id; + } + + $msgtext .= $this->formatSummary($imp_contents->getSummary($id, $contents_mask), $part_info_display) . + $this->formatStatusMsg($info['status']) . + '
' . $info['data'] . '
'; + + if (isset($info['js'])) { + $js_onload = array_merge($js_onload, $info['js']); + } + } + } + + while (count($wrap_ids)) { + $msgtext .= '
'; + array_pop($wrap_ids); + } + + if (!strlen($msgtext)) { + $msgtext = $this->formatStatusMsg(array(array('text' => array(_("There are no parts that can be shown inline."))))); + } + + return array( + 'atc_parts' => $atc_parts, + 'display_ids' => $display_ids, + 'js_onload' => $js_onload, + 'msgtext' => $msgtext + ); + } + + /** * Get the display subject (filtered, formatted, and linked). * * @param string $subject The subject text. diff --git a/imp/lib/Views/ShowMessage.php b/imp/lib/Views/ShowMessage.php index 705b2f11b..1b25a1ac9 100644 --- a/imp/lib/Views/ShowMessage.php +++ b/imp/lib/Views/ShowMessage.php @@ -237,14 +237,8 @@ class IMP_Views_ShowMessage } // Create message text and attachment list. - $parts_list = $imp_contents->getContentTypeMap(); - $atc_parts = $display_ids = array(); $result['msgtext'] = ''; - $show_parts = $GLOBALS['prefs']->getValue('parts_display'); - if ($show_parts == 'all') { - $atc_parts = array_keys($parts_list); - } $contents_mask = IMP_Contents::SUMMARY_BYTES | IMP_Contents::SUMMARY_SIZE | @@ -261,64 +255,18 @@ class IMP_Views_ShowMessage } /* Build body text. This needs to be done before we build the - * attachment list that lives in the header. */ - foreach ($parts_list as $mime_id => $mime_type) { - if (in_array($mime_id, $display_ids, true)) { - continue; - } - - - if (!($render_mode = $imp_contents->canDisplay($mime_id, IMP_Contents::RENDER_INLINE | IMP_Contents::RENDER_INFO))) { - if ($imp_contents->isAttachment($mime_type)) { - if ($show_parts == 'atc') { - $atc_parts[] = $mime_id; - } - - if ($GLOBALS['prefs']->getValue('atc_display')) { - $result['msgtext'] .= $imp_ui->formatSummary($imp_contents->getSummary($mime_id, $contents_mask), $part_info_display, true); - } - } - continue; - } - - $render_part = $imp_contents->renderMIMEPart($mime_id, $render_mode); - if (($render_mode & IMP_Contents::RENDER_INLINE) && empty($render_part)) { - /* This meant that nothing was rendered - allow this part to - * appear in the attachment list instead. */ - if ($show_parts == 'atc') { - $atc_parts[] = $mime_id; - } - continue; - } - - reset($render_part); - while (list($id, $info) = each($render_part)) { - $display_ids[] = $id; - - if (empty($info)) { - continue; - } - - $result['msgtext'] .= $imp_ui->formatSummary($imp_contents->getSummary($id, $contents_mask), $part_info_display) . - $imp_ui->formatStatusMsg($info['status']) . - '
' . $info['data'] . '
'; + * attachment list. */ + $inlineout = $imp_ui->getInlineOutput($imp_contents, $contents_mask, $part_info_display, $show_parts); - if (isset($info['js'])) { - $result['js'] = array_merge($result['js'], $info['js']); - } - } - } - - if (!strlen($result['msgtext'])) { - $result['msgtext'] = $imp_ui->formatStatusMsg(array(array('text' => array(_("There are no parts that can be shown inline."))))); - } + $result['js'] = array_merge($result['js'], $inlineout['js_onload']); + $result['msgtext'] .= $inlineout['msgtext']; if (count($atc_parts) || - (($show_parts == 'all') && count($display_ids) > 2)) { + (($show_parts == 'all') && count($inlineout['display_ids']) > 2)) { $result['atc_label'] = ($show_parts == 'all') ? _("Parts") : sprintf(ngettext("%d Attachment", "%d Attachments", count($atc_parts)), count($atc_parts)); - if (count($display_ids) > 2) { + if (count($inlineout['display_ids']) > 2) { $result['atc_download'] = Horde::link($imp_contents->urlView($imp_contents->getMIMEMessage(), 'download_all')) . '[' . _("Save All") . ']'; } } diff --git a/imp/message.php b/imp/message.php index 0ee3c5944..3c97b7475 100644 --- a/imp/message.php +++ b/imp/message.php @@ -567,21 +567,8 @@ foreach ($all_list_headers as $head => $val) { $part_info = $part_info_display = array('icon', 'description', 'type', 'size'); $part_info_action = array('download', 'download_zip', 'img_save', 'strip'); -$parts_list = $imp_contents->getContentTypeMap(); -$strip_atc = $prefs->getValue('strip_attachments'); -$atc_parts = $display_ids = array(); -$js_onload = array(); -$msgtext = ''; - -/* Do MDN processing now. */ -if ($imp_ui->MDNCheck($imp_mbox['mailbox'], $uid, $mime_headers, Horde_Util::getFormData('mdn_confirm'))) { - $msgtext .= $imp_ui->formatStatusMsg(array(array('text' => array(_("The sender of this message is requesting a Message Disposition Notification from you when you have read this message."), sprintf(_("Click %s to send the notification message."), Horde::link(htmlspecialchars(Horde_Util::addParameter($selfURL, 'mdn_confirm', 1))) . _("HERE") . ''))))); -} - $show_parts = Horde_Util::getFormData('show_parts', $prefs->getValue('parts_display')); -if ($show_parts == 'all') { - $atc_parts = array_keys($parts_list); -} +$strip_atc = $prefs->getValue('strip_attachments'); $part_info_display = array_merge($part_info_display, $part_info_action); $contents_mask = IMP_Contents::SUMMARY_BYTES | @@ -595,57 +582,15 @@ if (!$readonly && $strip_atc) { $contents_mask |= IMP_Contents::SUMMARY_STRIP_LINK; } -/* Build body text. This needs to be done before we build the attachment list - * that lives in the header. */ -foreach ($parts_list as $mime_id => $mime_type) { - if (in_array($mime_id, $display_ids, true)) { - continue; - } - - if (!($render_mode = $imp_contents->canDisplay($mime_id, IMP_Contents::RENDER_INLINE | IMP_Contents::RENDER_INFO))) { - if ($imp_contents->isAttachment($mime_type)) { - if ($show_parts == 'atc') { - $atc_parts[] = $mime_id; - } - - if ($prefs->getValue('atc_display')) { - $msgtext .= $imp_ui->formatSummary($imp_contents->getSummary($mime_id, $contents_mask), $part_info_display, true); - } - } - continue; - } - - $render_part = $imp_contents->renderMIMEPart($mime_id, $render_mode); - if (($render_mode & IMP_Contents::RENDER_INLINE) && empty($render_part)) { - /* This meant that nothing was rendered - allow this part to appear - * in the attachment list instead. */ - if ($show_parts == 'atc') { - $atc_parts[] = $mime_id; - } - continue; - } - - reset($render_part); - while (list($id, $info) = each($render_part)) { - $display_ids[] = $id; - - if (empty($info)) { - continue; - } - - $msgtext .= $imp_ui->formatSummary($imp_contents->getSummary($id, $contents_mask), $part_info_display) . - $imp_ui->formatStatusMsg($info['status']) . - '
' . $info['data'] . '
'; - - if (isset($info['js'])) { - $js_onload = array_merge($js_onload, $info['js']); - } - } +/* Do MDN processing now. */ +$mdntext = ''; +if ($imp_ui->MDNCheck($imp_mbox['mailbox'], $uid, $mime_headers, Horde_Util::getFormData('mdn_confirm'))) { + $mdntext .= $imp_ui->formatStatusMsg(array(array('text' => array(_("The sender of this message is requesting a Message Disposition Notification from you when you have read this message."), sprintf(_("Click %s to send the notification message."), Horde::link(htmlspecialchars(Horde_Util::addParameter($selfURL, 'mdn_confirm', 1))) . _("HERE") . ''))))); } -if (!strlen($msgtext)) { - $msgtext = $imp_ui->formatStatusMsg(array(array('text' => array(_("There are no parts that can be shown inline."))))); -} +/* Build body text. This needs to be done before we build the attachment list + * that lives in the header. */ +$inlineout = $imp_ui->getInlineOutput($imp_contents, $contents_mask, $part_info_display, $show_parts); /* Build the Attachments menu. */ $a_template->set('atc', Horde::widget('#', _("Attachments"), 'widget hasmenu', '', '', _("Attachments"), true)); @@ -655,7 +600,7 @@ if ($show_parts == 'atc') { if ($show_parts == 'all') { $a_template->set('show_parts_atc', Horde::widget(Horde_Util::addParameter($headersURL, array('show_parts' => 'atc')), _("Show Attachments Only"), 'widget', '', '', _("Show Attachments Only"), true)); } -if (count($display_ids) > 2) { +if (count($inlineout['display_ids']) > 2) { $a_template->set('download_all', Horde::widget($imp_contents->urlView($imp_contents->getMIMEMessage(), 'download_all'), _("Download All Attachments (in .zip file)"), 'widget', '', '', _("Download All Attachments (in .zip file)"), true)); if ($strip_atc) { $a_template->set('strip_all', Horde::widget(htmlspecialchars(html_entity_decode(Horde_Util::addParameter(Horde_Util::removeParameter(Horde::selfUrl(true), array('actionID')), array('actionID' => 'strip_all', 'message_token' => $message_token)))), _("Strip All Attachments"), 'widget', '', "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete all attachments?")) . "');", _("Strip All Attachments"), true)); @@ -701,10 +646,10 @@ if (!empty($conf['print']['add_printedby'])) { } $m_template->set('headers', $hdrs); -$m_template->set('msgtext', $msgtext); +$m_template->set('msgtext', $mdntext . $inlineout['msgtext']); /* Output message page now. */ -Horde::addInlineScript($js_onload, 'dom'); +Horde::addInlineScript($inlineout['js_onload'], 'dom'); Horde::addScriptFile('effects.js', 'horde'); Horde::addScriptFile('imp.js', 'imp'); Horde::addScriptFile('message.js', 'imp'); diff --git a/imp/themes/ie6_or_less.css b/imp/themes/ie6_or_less.css index cab69dacb..4585f4b3f 100644 --- a/imp/themes/ie6_or_less.css +++ b/imp/themes/ie6_or_less.css @@ -3,7 +3,7 @@ */ /* Fixes broken inline-block. */ -div.msgflags, span.spellcheckPopdownImg, span.treeImg, .downloadAtc, .downloadZipAtc, .saveImgAtc, .deleteImg, .mimePartInfo div, .mimeStatusMessage { +div.msgflags, span.spellcheckPopdownImg, span.treeImg, .downloadAtc, .downloadZipAtc, .saveImgAtc, .deleteImg, .mimePartInfo div, .mimeStatusMessage, .mimeHeaders { zoom: 1; *display: inline; } diff --git a/imp/themes/ie7.css b/imp/themes/ie7.css index 93d292398..82989f776 100644 --- a/imp/themes/ie7.css +++ b/imp/themes/ie7.css @@ -3,7 +3,7 @@ */ /* Fixes broken inline-block. */ -div.msgflags, span.spellcheckPopdownImg, span.treeImg, .downloadAtc, .downloadZipAtc, .saveImgAtc, .deleteImg, .mimePartInfo div, .mimeStatusMessage { +div.msgflags, span.spellcheckPopdownImg, span.treeImg, .downloadAtc, .downloadZipAtc, .saveImgAtc, .deleteImg, .mimePartInfo div, .mimeStatusMessage, .mimeHeaders { zoom: 1; *display: inline; } diff --git a/imp/themes/screen.css b/imp/themes/screen.css index 24a2c260b..657b1896a 100644 --- a/imp/themes/screen.css +++ b/imp/themes/screen.css @@ -520,17 +520,17 @@ td.addressTr span.loadingImg { /* MIME styles. */ .mimeStatusMessage>table, .mimeHeaders { - padding: 4px; margin-bottom: 3px; font-size: 90%; } .mimeStatusMessage>table { - color: #000; background: #ffc; border: 1px solid #fff760; - margin-bottom: 3px; + color: #000; display: -moz-inline-stack; display: inline-block; + margin-bottom: 3px; + padding: 4px; } .mimeStatusIcon { width: 22px; @@ -538,7 +538,9 @@ td.addressTr span.loadingImg { .mimeHeaders { border: 1px solid #ccc; background: #f9f9f9; - width: auto; + display: -moz-inline-stack; + display: inline-block; + padding: 5px; } div.mimeStatusMessage, div.mimePartInfo { margin-bottom: 5px; @@ -572,6 +574,12 @@ div.mimeStatusMessage, div.mimePartInfo { white-space: nowrap; } +.mimePartWrap { + border: 2px solid #666; + margin: 2px 0; + padding: 4px; +} + .downloadAtc, .downloadZipAtc, .saveImgAtc, .closeImg, .deleteImg, .foldersImg, .searchuiImg, .reloadImg { display: -moz-inline-stack; display: inline-block; -- 2.11.0