Ticket #8836: Add 'noprefetch' option to linkurls
authorMichael M Slusarz <slusarz@curecanti.org>
Tue, 26 Jan 2010 23:39:50 +0000 (16:39 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 26 Jan 2010 23:42:01 +0000 (16:42 -0700)
framework/Mime/lib/Horde/Mime/Viewer/Enriched.php
framework/Mime/lib/Horde/Mime/Viewer/Plain.php
framework/Text_Filter/lib/Horde/Text/Filter/Linkurls.php
framework/Text_Filter/lib/Horde/Text/Filter/Text2html.php
imp/lib/Ajax/Application.php
imp/lib/Mime/Viewer/Plain.php
imp/lib/Ui/Message.php
imp/mailbox.php

index 0ac97cc..5f79c9b 100644 (file)
@@ -46,7 +46,7 @@ class Horde_Mime_Viewer_Enriched extends Horde_Mime_Viewer_Driver
     {
         return array(
             $this->_mimepart->getMimeId() => array(
-                'data' => '<html><body>' . $this->_toHTML() . '</body></html>',
+                'data' => '<html><body>' . $this->_toHTML(false) . '</body></html>',
                 'status' => array(),
                 'type' => 'text/html; charset=' . $this->_mimepart->getCharset()
             )
@@ -62,7 +62,7 @@ class Horde_Mime_Viewer_Enriched extends Horde_Mime_Viewer_Driver
     {
         return array(
             $this->_mimepart->getMimeId() => array(
-                'data' => Horde_String::convertCharset($this->_toHTML(), $this->_mimepart->getCharset()),
+                'data' => Horde_String::convertCharset($this->_toHTML(true), $this->_mimepart->getCharset()),
                 'status' => array(),
                 'type' => 'text/html; charset=' . Horde_Nls::getCharset()
             )
@@ -72,9 +72,11 @@ class Horde_Mime_Viewer_Enriched extends Horde_Mime_Viewer_Driver
     /**
      * Convert the enriched text to HTML.
      *
+     * @param string $inline  Rendered inline?
+     *
      * @return string  The HTML-ified version of the MIME part contents.
      */
-    protected function _toHTML()
+    protected function _toHTML($inline)
     {
         $text = trim($this->_mimepart->getContents());
         if (!strlen($text)) {
@@ -170,7 +172,11 @@ class Horde_Mime_Viewer_Enriched extends Horde_Mime_Viewer_Driver
         $text = preg_replace('/^ (.*) $/s', '\1', $text);
 
         // Make URLs clickable.
-        $text = Horde_Text_Filter::filter($text, 'linkurls', array('callback' => 'Horde::externalUrl'));
+        $text = Horde_Text_Filter::filter($text, 'linkurls', array(
+            'callback' => 'Horde::externalUrl',
+            // See Ticket #8836
+            'noprefetch' => ($inline && $GLOBALS['browser']->isBrowser('mozilla') && !$GLOBALS['browser']->usingSSLConnection())
+        ));
 
         /* Wordwrap -- note this could impact on our above RFC compliance *IF*
          * we honored nofill tags (which we don't yet). */
index 4e3a1be..cad7a73 100644 (file)
@@ -43,7 +43,10 @@ class Horde_Mime_Viewer_Plain extends Horde_Mime_Viewer_Driver
 
         return array(
             $this->_mimepart->getMimeId() => array(
-                'data' => '<html><body><tt>' . Horde_Text_Filter::filter($text, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO, 'charset' => $charset, 'class' => null)) . '</tt></body></html>',
+                'data' => '<html><body><tt>' . Horde_Text_Filter::filter($text, 'text2html', array(
+                    'charset' => $charset,
+                    'parselevel' => Horde_Text_Filter_Text2html::MICRO
+                )) . '</tt></body></html>',
                 'status' => array(),
                 'type' => 'text/html; charset=' . $charset
             )
index 181838d..f35e048 100644 (file)
@@ -5,17 +5,23 @@
  *
  * Parameters:
  * <pre>
- * target   -- The link target.  Defaults to _blank.
- * class    -- The CSS class of the generated links.  Defaults to none.
- * nofollow -- Whether to set the 'rel="nofollow"' attribute on links.
- * callback -- An optional callback function that the URL is passed through
- *             before being set as the href attribute.  Must be a string with
- *             the function name, the function must take the original as the
- *             first and only parameter.
- * encode   -- Whether to escape special HTML characters in the URLs and
- *             finally "encode" the complete tag so that it can be decoded
- *             later with the decode() method. This is useful if you want to
- *             run htmlspecialchars() or similar *after* using this filter.
+ * callback - (string) A callback function that the URL is passed through
+ *            before being set as the href attribute.  Must be a string with
+ *            the function name, the function must take the original URL as
+ *            the first and only parameter.
+ *            DEFAULT: No callback
+ * class - (string) The CSS class of the generated links.
+ *         DEFAULT: none
+ * encode - (boolean)  Whether to escape special HTML characters in the URLs
+ *          and finally "encode" the complete tag so that it can be decoded
+ *          later with the decode() method. This is useful if you want to
+ *          run htmlspecialchars() or similar *after* using this filter.
+ *          DEFAULT: false
+ * nofollow - (boolean) Whether to set the 'rel="nofollow"' attribute on
+ *            links.
+ *            DEFAULT: false
+ * target - (string) The link target.
+ *          DEFAULT: '_blank'
  * </pre>
  *
  * Copyright 2003-2010 The Horde Project (http://www.horde.org/)
@@ -53,22 +59,31 @@ class Horde_Text_Filter_Linkurls extends Horde_Text_Filter
         if (!empty($class)) {
             $class = ' class="' . $class . '"';
         }
-        $nofollow = $this->_params['nofollow'] ? ' rel="nofollow"' : '';
 
-        $replacement = $this->_params['callback']
-            ? '\' . ' . $this->_params['callback'] . '(\'$0\') . \''
-            : '$0';
-        if ($this->_params['encode']) {
-            $replacement = 'chr(0).chr(0).chr(0).base64_encode(\'<a href="\'.htmlspecialchars(\'' . $replacement . '\').\'"' . $nofollow . ' target="_blank"' . $class . '>\'.htmlspecialchars(\'$0\').\'</a>\').chr(0).chr(0).chr(0)';
-        } else {
-            $replacement = '\'<a href="' . $replacement . '"' . $nofollow
-                . ' target="_blank"' . $class . '>$0</a>\'';
+        $href = $this->_params['callback']
+            ? '\' . htmlspecialchars(' . $this->_params['callback'] . '(\'$0\')) . \''
+            : '\' . htmlspecialchars(\'$0\') . \'';
+
+        $replacement = '<a href="' . $href . '"' .
+            ($this->_params['nofollow'] ? ' rel="nofollow"' : '') .
+            ' target="_blank"' . $class .
+            '>\' . htmlspecialchars(\'$0\') . \'</a>';
+
+        if ($this->_params['noprefetch']) {
+            $replacement = '<meta http-equiv="x-dns-prefetch-control" value="off" />' .
+                $replacement .
+                '<meta http-equiv="x-dns-prefetch-control" value="on" />';
         }
 
-        $regexp = array('|([\w+-]{1,20})://([^\s"<]*[\w+#?/&=])|e' =>
-                        $replacement);
+        $replacement = $this->_params['encode']
+            ? 'chr(0) . chr(0) . chr(0) . base64_encode(\'' . $replacement . '\') . chr(0) . chr(0) . chr(0)'
+            : '\'' . $replacement . '\'';
 
-        return array('regexp' => $regexp);
+        return array(
+            'regexp' => array(
+                '|([\w+-]{1,20})://([^\s"<]*[\w+#?/&=])|e' => $replacement
+            )
+        );
     }
 
     /**
index 1a4ffc3..b2d8c5a 100644 (file)
@@ -5,14 +5,12 @@
  *
  * Parameters:
  * <pre>
- * parselevel -- The parselevel of the output. See the list of constants below.
- * charset    -- The charset to use for htmlspecialchars() calls.
- * class      -- The CSS class name for the links.
- * nofollow   -- Whether to set the 'rel="nofollow"' attribute on links.
- * callback   -- An optional callback function that the URL is passed through
- *               before being set as the href attribute.  Must be a string with
- *               the function name, the function must take the original as the
- *               first and only parameter.
+ * callback - (string) See Horde_Text_Filter_Linkurls::.
+ * charset - (string) The charset to use for htmlspecialchars() calls.
+ * class - (string) See Horde_Text_Filter_Linkurls::.
+ * nofollow - (boolean) See Horde_Text_Filter_Linkurls::.
+ * noprefetch - (boolean) See Horde_Text_Filter_Linkurls::.
+ * parselevel - (integer) The parselevel of the output (see below).
  * </pre>
  *
  * <pre>
@@ -40,7 +38,6 @@
  */
 class Horde_Text_Filter_Text2html extends Horde_Text_Filter
 {
-    /* TODO */
     const PASSTHRU = 0;
     const SYNTAX = 1;
     const MICRO = 2;
@@ -57,7 +54,9 @@ class Horde_Text_Filter_Text2html extends Horde_Text_Filter
         'callback' => 'Horde::externalUrl',
         'charset' => null,
         'class' => 'fixed',
-        'nofollow' => false
+        'nofollow' => false,
+        'noprefetch' => false,
+        'parselevel' => 0
     );
 
     /**
@@ -100,7 +99,12 @@ class Horde_Text_Filter_Text2html extends Horde_Text_Filter
         }
 
         if ($this->_params['parselevel'] < self::NOHTML) {
-            $filters = array('linkurls' => array('callback' => $this->_params['callback'], 'nofollow' => $this->_params['nofollow'], 'encode' => true));
+            $filters = array('linkurls' => array(
+                'callback' => $this->_params['callback'],
+                'nofollow' => $this->_params['nofollow'],
+                'noprefetch' => $this->_params['noprefetch'],
+                'encode' => true
+            ));
             if ($this->_params['parselevel'] < self::MICRO_LINKURL) {
                 $filters['emails'] = array('encode' => true);
             }
index f427592..86e65e8 100644 (file)
@@ -871,7 +871,7 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
     public function Text2Html($vars)
     {
         $result = new stdClass;
-        $result->text = Horde_Text_Filter::filter($vars->text, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO_LINKURL, 'class' => null, 'callback' => null));
+        $result->text = Horde_Text_Filter::filter($vars->text, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO_LINKURL));
 
         return $result;
     }
index 847ec21..9d9dcac 100644 (file)
@@ -81,8 +81,10 @@ class IMP_Horde_Mime_Viewer_Plain extends Horde_Mime_Viewer_Plain
         // Build filter stack. Starts with HTML markup and tab expansion.
         $filters = array(
             'text2html' => array(
-                'parselevel' => Horde_Text_Filter_Text2html::MICRO,
-                'charset' => Horde_Nls::getCharset()
+                'charset' => Horde_Nls::getCharset(),
+                // See Ticket #8836
+                'noprefetch' => ($GLOBALS['browser']->isBrowser('mozilla') && !$GLOBALS['browser']->usingSSLConnection()),
+                'parselevel' => Horde_Text_Filter_Text2html::MICRO
             ),
             'tabs2spaces' => array(),
         );
@@ -317,8 +319,10 @@ class IMP_Horde_Mime_Viewer_Plain extends Horde_Mime_Viewer_Plain
         // Escape text
         $filters = array(
             'text2html' => array(
-                'parselevel' => Horde_Text_Filter_Text2html::MICRO,
-                'charset' => Horde_Nls::getCharset()
+                'charset' => Horde_Nls::getCharset(),
+                // See Ticket #8836
+                'noprefetch' => ($inline && $GLOBALS['browser']->isBrowser('mozilla') && !$GLOBALS['browser']->usingSSLConnection()),
+                'parselevel' => Horde_Text_Filter_Text2html::MICRO
             ),
             'tabs2spaces' => array(),
         );
index b6441a3..a48eb3f 100644 (file)
@@ -235,7 +235,11 @@ class IMP_Ui_Message
                 }
                 break;
             } elseif (empty($data['email'])) {
-                if ($url = Horde_Text_Filter::filter($match, 'linkurls', array('callback' => 'Horde::externalUrl'))) {
+                if ($url = Horde_Text_Filter::filter($match, 'linkurls', array(
+                    'callback' => 'Horde::externalUrl',
+                    // See Ticket #8836
+                    'noprefetch' => ($GLOBALS['browser']->isBrowser('mozilla') && !$GLOBALS['browser']->usingSSLConnection())
+                ))) {
                     if (!empty($opts['raw'])) {
                         return $match;
                     }
@@ -577,7 +581,11 @@ class IMP_Ui_Message
      */
     public function getDisplaySubject($subject)
     {
-        return Horde_Text_Filter::filter(IMP::filterText($subject), 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO, 'class' => null, 'callback' => null));
+        return Horde_Text_Filter::filter(IMP::filterText($subject), 'text2html', array(
+            // See Ticket #8836
+            'noprefetch' => ($GLOBALS['browser']->isBrowser('mozilla') && !$GLOBALS['browser']->usingSSLConnection()),
+            'parselevel' => Horde_Text_Filter_Text2html::MICRO
+        ));
     }
 
     /**
index ff120f3..e20b8ca 100644 (file)
@@ -763,7 +763,9 @@ while (list(,$ob) = each($mbox_info['overview'])) {
             }
 
             if (!$preview_tooltip) {
-                $ptext = Horde_Text_Filter::filter($ptext, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::NOHTML, 'charset' => '', 'class' => ''));
+                $ptext = Horde_Text_Filter::filter($ptext, 'text2html', array(
+                    'parselevel' => Horde_Text_Filter_Text2html::NOHTML
+                ));
             }
 
             $maxlen = $prefs->getValue('preview_maxlen');