Drop zero width space charater insertion

word-break: break-word is sufficient.

fixes #12774
This commit is contained in:
Eric Lippmann 2016-11-23 11:05:39 +01:00
parent 6e319aeac7
commit 17398fc513
1 changed files with 10 additions and 90 deletions

View File

@ -45,35 +45,6 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract
'@@@@@@', '@@@@@@',
); );
/**
* The character ​
*
* @var string
*/
protected $zeroWidthSpace;
/**
* The encoded character ​
*
* @var string
*/
protected $zeroWidthSpaceEnt = '​';
/**
* Create a new Zend_View_Helper_PluginOutput
*/
public function __construct()
{
// This is actually not required as the value is constant,
// but as its (visual) length is 0, it's likely to be mixed up with the empty string.
$this->zeroWidthSpace = '<span style="visibility:hidden; display:none;">'
. html_entity_decode($this->zeroWidthSpaceEnt, ENT_NOQUOTES, 'UTF-8')
. '</span>';
$this->zeroWidthSpaceEnt = '<span style="visibility:hidden; display:none;">'
. $this->zeroWidthSpaceEnt
. '</span>';
}
/** /**
* Render plugin output * Render plugin output
* *
@ -96,29 +67,21 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract
$this->getPurifier()->purify($output) $this->getPurifier()->purify($output)
); );
$isHtml = true; $isHtml = true;
$useDom = true;
} else { } else {
// Plaintext // Plaintext
$count = 0;
$output = preg_replace( $output = preg_replace(
self::$txtPatterns, self::$txtPatterns,
self::$txtReplacements, self::$txtReplacements,
$this->view->escape($output), $this->view->escape($output)
-1,
$count
); );
$isHtml = false; $isHtml = false;
$useDom = (bool) $count;
} }
// Help browsers to break words in plugin output
$output = trim($output); $output = trim($output);
// Add space after comma where missing // Add space after comma where missing, to help browsers to break words in plugin output
$output = preg_replace('/,(?=[^\s])/', ', ', $output); $output = preg_replace('/,(?=[^\s])/', ', ', $output);
$output = $useDom ? $this->fixLinksAndWrapping($output) : $this->fixWrapping($output, $this->zeroWidthSpaceEnt);
if (! $raw) { if (! $raw) {
if ($isHtml) { if ($isHtml) {
$output = $this->fixLinks($output);
$output = '<div class="plugin-output">' . $output . '</div>'; $output = '<div class="plugin-output">' . $output . '</div>';
} else { } else {
$output = '<div class="plugin-output preformatted">' . $output . '</div>'; $output = '<div class="plugin-output preformatted">' . $output . '</div>';
@ -128,40 +91,31 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract
} }
/** /**
* Replace classic Icinga CGI links with Icinga Web 2 links and * Replace classic Icinga CGI links with Icinga Web 2 links
* add zero width space to make wrapping easier for the user agent
* *
* @param string $html * @param string $html
* *
* @return string * @return string
*/ */
protected function fixLinksAndWrapping($html) protected function fixLinks($html)
{ {
$dom = new DOMDocument();
$ret = array();
$dom = new DOMDocument;
$dom->loadXML('<div>' . $html . '</div>', LIBXML_NOERROR | LIBXML_NOWARNING); $dom->loadXML('<div>' . $html . '</div>', LIBXML_NOERROR | LIBXML_NOWARNING);
$dom->preserveWhiteSpace = false; $dom->preserveWhiteSpace = false;
$links = $dom->getElementsByTagName('a'); $links = $dom->getElementsByTagName('a');
foreach ($links as $tag) foreach ($links as $link) {
{ /** @var \DOMElement $link */
$href = $tag->getAttribute('href'); $href = $link->getAttribute('href');
if (preg_match('~^/cgi\-bin/status\.cgi\?(.+)$~', $href, $m)) { if (preg_match('~^/cgi\-bin/status\.cgi\?(.+)$~', $href, $m)) {
parse_str($m[1], $params); parse_str($m[1], $params);
if (isset($params['host'])) { if (isset($params['host'])) {
$tag->setAttribute('href', $this->view->baseUrl( $link->setAttribute('href', $this->view->baseUrl(
'/monitoring/host/show?host=' . urlencode($params['host'] '/monitoring/host/show?host=' . urlencode($params['host']
))); )));
} }
} else {
// ignoring
} }
//$ret[$tag->getAttribute('href')] = $tag->childNodes->item(0)->nodeValue;
} }
$this->fixWrappingRecursive($dom);
return substr($dom->saveHTML(), 5, -7); return substr($dom->saveHTML(), 5, -7);
} }
@ -194,38 +148,4 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract
} }
return self::$purifier; return self::$purifier;
} }
/**
* Add zero width space to all text in the DOM to make wrapping easier for the user agent
*
* @param DOMNode $node
*/
protected function fixWrappingRecursive(DOMNode $node)
{
if ($node instanceof DOMText) {
$node->data = $this->fixWrapping($node->data, $this->zeroWidthSpace);
} elseif ($node->childNodes !== null) {
foreach ($node->childNodes as $childNode) {
$this->fixWrappingRecursive($childNode);
}
}
}
/**
* Add zero width space to make wrapping easier for the user agent
*
* @param string $output
* @param string $zeroWidthSpace
*
* @return string
*/
protected function fixWrapping($output, $zeroWidthSpace)
{
// TODO(el): Disabled until we find a bulletproof implementation
return $output;
// Add zero width space after ')', ']', ':', '.', '_' and '-' if not surrounded by whitespaces
$output = preg_replace('/([^\s])([\\)\\]:._-])([^\s])/', '$1$2' . $zeroWidthSpace . '$3', $output);
// Add zero width space before '(' and '[' if not surrounded by whitespaces
return preg_replace('/([^\s])([([])([^\s])/', '$1' . $zeroWidthSpace . '$2$3', $output);
}
} }