Allow remaining images on DIMP main page to be loaded via Data URL
authorMichael M Slusarz <slusarz@curecanti.org>
Thu, 15 Jan 2009 18:05:05 +0000 (11:05 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Thu, 15 Jan 2009 18:09:55 +0000 (11:09 -0700)
Loading DIMP's index page on a supported browser, with CSS/JS caching,
now results in 0 images that need to be separately loaded.

Should probably move this to Horde core proper ASAP (along with all
JS/CSS caching code) so that other apps can make use of this. This is
less effective for non-AJAXy applications since the data needs to be
sent on every page load (vs. the image data being cached in CSS).
However, some images are generated on the fly/don't reside in the app
themes directory so they aren't available to be served via CSS.

imp/lib/DIMP.php
imp/lib/IMAP/Thread.php
imp/lib/IMP.php
imp/templates/index/index.inc

index 07a7d1b..9658c98 100644 (file)
@@ -50,8 +50,8 @@ class DIMP
                            empty($params['id']) ? array() : array('id' => $params['id']),
                            !empty($title))
             . (!empty($params['icon'])
-               ? Horde::img($params['icon'], $title, '',
-                            $GLOBALS['registry']->getImageDir(empty($params['app']) ? 'imp' : $params['app']))
+               ? IMP::img($params['icon'], $title, '',
+                          $GLOBALS['registry']->getImageDir(empty($params['app']) ? 'imp' : $params['app']))
                : '')
             . $title . '</a>';
     }
@@ -422,7 +422,7 @@ class DIMP
 
         if ($elt['user_icon']) {
             $ob->cl = 'custom';
-            $ob->i = Horde::img($elt['icon'], $elt['alt'], '', $elt['icondir']);
+            $ob->i = IMP::img($elt['icon'], $elt['alt'], '', $elt['icondir']);
         }
 
         return $ob;
index 8a8ebec..911ccff 100644 (file)
@@ -133,12 +133,13 @@ class IMP_IMAP_Thread
     /**
      * Get potential image URLs that may be used to display a thread.
      *
-     * @param ids $ids  Add unique DOM ID to each image?
+     * @param ids $ids      Add unique DOM ID to each image?
+     * @param ids $datauri  Output data URIs, if possible?
      *
      * @return array  An array with the image code as a key and the image url
      *                as the value.
      */
-    static public function getImageUrls($ids = true)
+    static public function getImageUrls($ids = true, $datauri = false)
     {
         $graphicsdir = $GLOBALS['registry']->getImageDir('horde');
         $args = array();
@@ -147,7 +148,11 @@ class IMP_IMAP_Thread
             if ($ids) {
                 $args['id'] = 'thread_img_' . $key;
             }
-            $out[$key] = Horde::img('tree/' . (($key != 0 && !empty($GLOBALS['nls']['rtl'][$GLOBALS['language']])) ? ('rev-' . $val) : $val), '', $args, $graphicsdir);
+            if ($datauri) {
+                $out[$key] = IMP::img('tree/' . (($key != 0 && !empty($GLOBALS['nls']['rtl'][$GLOBALS['language']])) ? ('rev-' . $val) : $val), '', $args, $graphicsdir);
+            } else {
+                $out[$key] = Horde::img('tree/' . (($key != 0 && !empty($GLOBALS['nls']['rtl'][$GLOBALS['language']])) ? ('rev-' . $val) : $val), '', $args, $graphicsdir);
+            }
         }
 
         return $out;
index b3553ba..74a4a3e 100644 (file)
@@ -1723,14 +1723,20 @@ class IMP
     }
 
     /**
-     * TODO
+     * TODO - Move to Horde core
      */
     public function stylesheetCallback($matches)
     {
-        return $matches[1] .
-            'data:image/' . substr($matches[2], strrpos($matches[2], '.') + 1) . ';base64,' .
-            base64_encode(file_get_contents(dirname(realpath($GLOBALS['registry']->get('fileroot', 'horde'))) . $matches[2])) .
-            $matches[3];
+        return $matches[1] . IMP::base64ImgData($matches[2]) . $matches[3];
+    }
+
+    /**
+     * TODO - Move to Horde core
+     */
+    public function base64ImgData($file)
+    {
+        return 'data:image/' . substr($file, strrpos($file, '.') + 1) . ';base64,' .
+            base64_encode(file_get_contents(dirname(realpath($GLOBALS['registry']->get('fileroot', 'horde'))) . $file));
     }
 
     /**
@@ -1812,6 +1818,64 @@ class IMP
     }
 
     /**
+     * Constructs a correctly-pathed link to an image.
+     * TODO - Move to Horde core
+     *
+     * @param string $src   The image file.
+     * @param string $alt   Text describing the image.
+     * @param mixed  $attr  Any additional attributes for the image tag. Can
+     *                      be a pre-built string or an array of key/value
+     *                      pairs that will be assembled and html-encoded.
+     * @param string $dir   The root graphics directory.
+     *
+     * @return string  The full image tag.
+     */
+    static public function img($src, $alt = '', $attr = '', $dir = null)
+    {
+        /* If browser does not support images, simply return the ALT text. */
+        if (!$GLOBALS['browser']->hasFeature('images') ||
+            !$GLOBALS['browser']->hasFeature('dataurl')) {
+            return Horde::img($src, $alt, $attr, $dir);
+        }
+
+        /* If no directory has been specified, get it from the registry. */
+        if (is_null($dir)) {
+            $dir = $GLOBALS['registry']->getImageDir();
+        }
+
+        /* If a directory has been provided, prepend it to the image source. */
+        if (!empty($dir)) {
+            $src = $dir . '/' . $src;
+        }
+
+        /* Build all of the tag attributes. */
+        $attributes = array('alt' => $alt);
+        if (is_array($attr)) {
+            $attributes = array_merge($attributes, $attr);
+        }
+        if (empty($attributes['title'])) {
+            $attributes['title'] = '';
+        }
+
+        $img = '<img';
+        $charset = NLS::getCharset();
+        $old_error = error_reporting(0);
+        foreach ($attributes as $attribute => $value) {
+            $img .= ' ' . $attribute . '="' . ($attribute == 'src' ? $value : htmlspecialchars($value, ENT_COMPAT, $charset)) . '"';
+        }
+        error_reporting($old_error);
+
+        /* If the user supplied a pre-built string of attributes, add that. */
+        if (is_string($attr) && !empty($attr)) {
+            $img .= ' ' . $attr;
+        }
+
+        /* Return the closed image tag. */
+        return $img . ' src="' . IMP::base64ImgData($src) . '" />';
+    }
+
+
+    /**
      * Do garbage collection in the statically served file directory.
      *
      * @param string $type  Either 'css' or 'js'.
index 30bd697..e774978 100644 (file)
@@ -3,13 +3,13 @@
 $hordeimg = $registry->getImageDir('horde');
 
 // Thread images
-$thread_imgs = IMP_IMAP_Thread::getImageUrls();
+$thread_imgs = IMP_IMAP_Thread::getImageUrls(true, true);
 
 // Attachment images
 $imp_ui = new IMP_UI_Mailbox('INBOX');
 $atc_imgs = array();
 foreach ($imp_ui->getAttachmentAltList() as $k => $v) {
-    $atc_imgs[] = Horde::img($k . '.png', $v, array('id' => 'atc_img_' . $k));
+    $atc_imgs[] = IMP::img($k . '.png', $v, array('id' => 'atc_img_' . $k));
 }
 
 $usetrash = $prefs->getValue('use_trash');
@@ -47,8 +47,8 @@ function _simpleButton($id, $text, $image, $imagedir = null)
         . (strlen($id) ? ' id="' . $id . '"' : '')
         . (strlen($ak) ? ' accesskey="' . $ak . '"' : '') . '>'
         . ($imagedir
-            ? Horde::img($image, Horde::stripAccessKey($text), '', $imagedir)
-            : Horde::img($image, Horde::stripAccessKey($text)))
+            ? IMP::img($image, Horde::stripAccessKey($text), '', $imagedir)
+            : IMP::img($image, Horde::stripAccessKey($text)))
         . '<a>'
         . Horde::highlightAccessKey($text, $ak) . '</a></li>';
 }
@@ -287,7 +287,7 @@ function _simpleButton($id, $text, $image, $imagedir = null)
         <div id="msgHeaders" style="display:none">
          <div class="dimpOptions noprint">
           <div id="msg_newwin_options"><span class="iconImg newwinImg"></span><a><?php echo _("Open in new window") ?></a></div>
-          <div id="msg_print"><?php echo Horde::img('print.png', '', '', $hordeimg) ?><a><?php echo _("Print") ?></a></div>
+          <div id="msg_print"><?php echo IMP::img('print.png', '', '', $hordeimg) ?><a><?php echo _("Print") ?></a></div>
 <?php if (!empty($conf['user']['allow_view_source'])): ?>
           <div id="msg_view_source"><span class="iconImg msgsourceImg"></span><a><?php echo _("View Message Source") ?></a></div>
 <?php endif; ?>