{
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()
)
{
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()
)
/**
* 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)) {
$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). */
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
)
*
* 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/)
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
+ )
+ );
}
/**
*
* 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>
*/
class Horde_Text_Filter_Text2html extends Horde_Text_Filter
{
- /* TODO */
const PASSTHRU = 0;
const SYNTAX = 1;
const MICRO = 2;
'callback' => 'Horde::externalUrl',
'charset' => null,
'class' => 'fixed',
- 'nofollow' => false
+ 'nofollow' => false,
+ 'noprefetch' => false,
+ 'parselevel' => 0
);
/**
}
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);
}
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;
}
// 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(),
);
// 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(),
);
}
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;
}
*/
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
+ ));
}
/**
}
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');