Fix font artifacts in text2html conversion (#1490353)

Use white-space:nowrap elements instead of unicode word-joiner character
pull/277/head
Aleksander Machniak 10 years ago
parent b3bf9c88dc
commit c4ad7edd53

@ -46,10 +46,6 @@ class rcube_text2html
protected $config = array( protected $config = array(
// non-breaking space // non-breaking space
'space' => "\xC2\xA0", 'space' => "\xC2\xA0",
// word-joiner (zero-width no-break space)
// 'wordjoiner' => "\xEF\xBB\xBF", // U+2060
// use deprecated U+FEFF character because of webkit issue with displaying U+2060 (#1490353)
'wordjoiner' => "\xEF\xBB\xBF", // U+FEFF
// enables format=flowed parser // enables format=flowed parser
'flowed' => false, 'flowed' => false,
// enables wrapping for non-flowed text // enables wrapping for non-flowed text
@ -63,6 +59,9 @@ class rcube_text2html
'links' => true, 'links' => true,
// string replacer class // string replacer class
'replacer' => 'rcube_string_replacer', 'replacer' => 'rcube_string_replacer',
// prefix and suffix of unwrappable line
'nobr_start' => '<span style="white-space:nowrap">',
'nobr_end' => '</span>',
); );
@ -281,12 +280,11 @@ class rcube_text2html
// replace HTML special characters // replace HTML special characters
$text = strtr($text, $table); $text = strtr($text, $table);
$nbsp = $this->config['space'];
$nobr = $this->config['wordjoiner'];
// replace some whitespace characters // replace some whitespace characters
$text = str_replace(array("\r", "\t"), array('', ' '), $text); $text = str_replace(array("\r", "\t"), array('', ' '), $text);
$nbsp = $this->config['space'];
// replace spaces with non-breaking spaces // replace spaces with non-breaking spaces
if ($is_flowed) { if ($is_flowed) {
$pos = 0; $pos = 0;
@ -304,15 +302,13 @@ class rcube_text2html
$text = $copy; $text = $copy;
} }
// make the whole line non-breakable // make the whole line non-breakable if needed
else { else if ($text !== '' && preg_match('/[^a-zA-Z0-9_]/', $text)) {
$repl = array( // use non-breakable spaces to correctly display
' ' => $nbsp, // trailing/leading spaces and multi-space inside
'-' => $nobr . '-' . $nobr, $text = str_replace(' ', $nbsp, $text);
'/' => $nobr . '/', // wrap in nobr element, so it's not wrapped on e.g. - or /
); $text = $this->config['nobr_start'] . $text . $this->config['nobr_end'];
$text = str_replace(array_keys($repl), array_values($repl), $text);
} }
return $text; return $text;

@ -21,49 +21,53 @@ class Framework_Text2Html extends PHPUnit_Framework_TestCase
'flowed' => false, 'flowed' => false,
'wrap' => false, 'wrap' => false,
'space' => '_', // replace UTF-8 non-breaking space for simpler testing 'space' => '_', // replace UTF-8 non-breaking space for simpler testing
'nobr_start' => '>',
'nobr_end' => '<',
); );
$data[] = array(" aaaa", "_aaaa", $options); $data[] = array(" aaaa", ">_aaaa<", $options);
$data[] = array("aaaa aaaa", "aaaa_aaaa", $options); $data[] = array("aa>aa", ">aa&gt;aa<", $options);
$data[] = array("aaaa aaaa", "aaaa__aaaa", $options); $data[] = array("aaaa aaaa", ">aaaa_aaaa<", $options);
$data[] = array("aaaa aaaa", "aaaa___aaaa", $options); $data[] = array("aaaa aaaa", ">aaaa__aaaa<", $options);
$data[] = array("aaaa\taaaa", "aaaa____aaaa", $options); $data[] = array("aaaa aaaa", ">aaaa___aaaa<", $options);
$data[] = array("aaaa\taaaa", ">aaaa____aaaa<", $options);
$data[] = array("aaaa\naaaa", "aaaa<br>aaaa", $options); $data[] = array("aaaa\naaaa", "aaaa<br>aaaa", $options);
$data[] = array("aaaa\n aaaa", "aaaa<br>_aaaa", $options); $data[] = array("aaaa\n aaaa", "aaaa<br>>_aaaa<", $options);
$data[] = array("aaaa\n aaaa", "aaaa<br>__aaaa", $options); $data[] = array("aaaa\n aaaa", "aaaa<br>>__aaaa<", $options);
$data[] = array("aaaa\n aaaa", "aaaa<br>___aaaa", $options); $data[] = array("aaaa\n aaaa", "aaaa<br>>___aaaa<", $options);
$data[] = array("\taaaa", "____aaaa", $options); $data[] = array("\n", "<br>", $options);
$data[] = array("\taaaa", ">____aaaa<", $options);
$data[] = array("\naaaa", "<br>aaaa", $options); $data[] = array("\naaaa", "<br>aaaa", $options);
$data[] = array("\n aaaa", "<br>_aaaa", $options); $data[] = array("\n aaaa", "<br>>_aaaa<", $options);
$data[] = array("\n aaaa", "<br>__aaaa", $options); $data[] = array("\n aaaa", "<br>>__aaaa<", $options);
$data[] = array("\n aaaa", "<br>___aaaa", $options); $data[] = array("\n aaaa", "<br>>___aaaa<", $options);
$data[] = array("aaaa\n\nbbbb", "aaaa<br><br>bbbb", $options); $data[] = array("aaaa\n\nbbbb", "aaaa<br><br>bbbb", $options);
$data[] = array(">aaaa \n>aaaa", "<blockquote>aaaa_<br>aaaa</blockquote>", $options); $data[] = array(">aaaa \n>aaaa", "<blockquote>>aaaa_<<br>aaaa</blockquote>", $options);
$data[] = array(">aaaa\n>aaaa", "<blockquote>aaaa<br>aaaa</blockquote>", $options); $data[] = array(">aaaa\n>aaaa", "<blockquote>aaaa<br>aaaa</blockquote>", $options);
$data[] = array(">aaaa \n>bbbb\ncccc dddd", "<blockquote>aaaa_<br>bbbb</blockquote>cccc_dddd", $options); $data[] = array(">aaaa \n>bbbb\ncccc dddd", "<blockquote>>aaaa_<<br>bbbb</blockquote>>cccc_dddd<", $options);
$data[] = array("aaaa-bbbb/cccc", "aaaa\xEF\xBB\xBF-\xEF\xBB\xBFbbbb\xEF\xBB\xBF/cccc", $options); $data[] = array("aaaa-bbbb/cccc", ">aaaa-bbbb/cccc<", $options);
$options['flowed'] = true; $options['flowed'] = true;
$data[] = array(" aaaa", "aaaa", $options); $data[] = array(" aaaa", "aaaa", $options);
$data[] = array("aaaa aaaa", "aaaa_aaaa", $options); $data[] = array("aaaa aaaa", ">aaaa_aaaa<", $options);
$data[] = array("aaaa aaaa", "aaaa__aaaa", $options); $data[] = array("aaaa aaaa", ">aaaa__aaaa<", $options);
$data[] = array("aaaa aaaa", "aaaa___aaaa", $options); $data[] = array("aaaa aaaa", ">aaaa___aaaa<", $options);
$data[] = array("aaaa\taaaa", "aaaa____aaaa", $options); $data[] = array("aaaa\taaaa", ">aaaa____aaaa<", $options);
$data[] = array("aaaa\naaaa", "aaaa<br>aaaa", $options); $data[] = array("aaaa\naaaa", "aaaa<br>aaaa", $options);
$data[] = array("aaaa\n aaaa", "aaaa<br>aaaa", $options); $data[] = array("aaaa\n aaaa", "aaaa<br>aaaa", $options);
$data[] = array("aaaa\n aaaa", "aaaa<br>_aaaa", $options); $data[] = array("aaaa\n aaaa", "aaaa<br>>_aaaa<", $options);
$data[] = array("aaaa\n aaaa", "aaaa<br>__aaaa", $options); $data[] = array("aaaa\n aaaa", "aaaa<br>>__aaaa<", $options);
$data[] = array("\taaaa", "____aaaa", $options); $data[] = array("\taaaa", ">____aaaa<", $options);
$data[] = array("\naaaa", "<br>aaaa", $options); $data[] = array("\naaaa", "<br>aaaa", $options);
$data[] = array("\n aaaa", "<br>aaaa", $options); $data[] = array("\n aaaa", "<br>aaaa", $options);
$data[] = array("\n aaaa", "<br>_aaaa", $options); $data[] = array("\n aaaa", "<br>>_aaaa<", $options);
$data[] = array("\n aaaa", "<br>__aaaa", $options); $data[] = array("\n aaaa", "<br>>__aaaa<", $options);
$data[] = array("aaaa\n\nbbbb", "aaaa<br><br>bbbb", $options); $data[] = array("aaaa\n\nbbbb", "aaaa<br><br>bbbb", $options);
$data[] = array(">aaaa \n>aaaa", "<blockquote>aaaa aaaa</blockquote>", $options); $data[] = array(">aaaa \n>aaaa", "<blockquote>aaaa aaaa</blockquote>", $options);
$data[] = array(">aaaa\n>aaaa", "<blockquote>aaaa<br>aaaa</blockquote>", $options); $data[] = array(">aaaa\n>aaaa", "<blockquote>aaaa<br>aaaa</blockquote>", $options);
$data[] = array(">aaaa \n>bbbb\ncccc dddd", "<blockquote>aaaa bbbb</blockquote>cccc_dddd", $options); $data[] = array(">aaaa \n>bbbb\ncccc dddd", "<blockquote>aaaa bbbb</blockquote>>cccc_dddd<", $options);
$data[] = array(chr(0x002).chr(0x003), chr(0x002).chr(0x003), $options); $data[] = array("\x02\x03", ">\x02\x03<", $options);
$options['flowed'] = false; $options['flowed'] = false;
$options['wrap'] = true; $options['wrap'] = true;

Loading…
Cancel
Save