Move message rendering code for imp/dimp into shared function
authorMichael M Slusarz <slusarz@curecanti.org>
Sat, 7 Nov 2009 06:03:04 +0000 (23:03 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Sat, 7 Nov 2009 21:26:49 +0000 (14:26 -0700)
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
imp/lib/Contents.php
imp/lib/Mime/Viewer/Rfc822.php [new file with mode: 0644]
imp/lib/UI/Message.php
imp/lib/Views/ShowMessage.php
imp/message.php
imp/themes/ie6_or_less.css
imp/themes/ie7.css
imp/themes/screen.css

index 621c4c7..e6b0513 100644 (file)
@@ -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.
  */
index b7666fd..551ddac 100644 (file)
@@ -378,10 +378,14 @@ class IMP_Contents
      * </pre>
      *
      * @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 (file)
index 0000000..e16202e
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * The IMP_Horde_Mime_Viewer_Rfc822 class extends the base Horde Mime Viewer
+ * by indicating that all subparts should be wrapped in a display DIV.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Michael Slusarz <slusarz@horde.org>
+ * @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;
+    }
+
+}
index 7188001..a5394c6 100644 (file)
@@ -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:
+     * <pre>
+     * '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.
+     * </pre>
+     */
+    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 .= '</div>';
+                    }
+                if (!empty($info['wrap'])) {
+                    $msgtext .= '<div class="' . $info['wrap'] . '">';
+                    $wrap_ids[] = $mime_id;
+                }
+
+                $msgtext .= $this->formatSummary($imp_contents->getSummary($id, $contents_mask), $part_info_display) .
+                    $this->formatStatusMsg($info['status']) .
+                    '<div class="mimePartData">' . $info['data'] . '</div>';
+
+                if (isset($info['js'])) {
+                    $js_onload = array_merge($js_onload, $info['js']);
+                }
+            }
+        }
+
+        while (count($wrap_ids)) {
+            $msgtext .= '</div>';
+            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.
index 705b2f1..1b25a1a 100644 (file)
@@ -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']) .
-                    '<div class="mimePartData">' . $info['data'] . '</div>';
+         * 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") . ']</a>';
             }
         }
index 0ee3c59..3c97b74 100644 (file)
@@ -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") . '</a>')))));
-}
-
 $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']) .
-            '<div class="mimePartData">' . $info['data'] . '</div>';
-
-        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") . '</a>')))));
 }
 
-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');
index cab69da..4585f4b 100644 (file)
@@ -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;
 }
index 93d2923..82989f7 100644 (file)
@@ -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;
 }
index 24a2c26..657b189 100644 (file)
@@ -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;