diff --git a/inc/DifferenceEngine.php b/inc/DifferenceEngine.php index 1b68cf6d3ad990aa8541260b93b5476c77d3e226..e0fbf8e030fdef502eb12379c8fa84340c9e3399 100644 --- a/inc/DifferenceEngine.php +++ b/inc/DifferenceEngine.php @@ -797,7 +797,7 @@ class DiffFormatter { function _lines($lines, $prefix = ' ') { foreach ($lines as $line) - echo "$prefix $line\n"; + echo "$prefix ".$this->_escape($line)."\n"; } function _context($lines) { @@ -816,6 +816,10 @@ class DiffFormatter { echo "---\n"; $this->_added($closing); } + + function _escape($str){ + return $str; + } } /** @@ -871,13 +875,13 @@ class _HWLDF_WordAccumulator { function _flushGroup($new_tag) { if ($this->_group !== '') { if ($this->_tag == 'mark') - $this->_line .= '<strong '.HTMLDiff::css('diff-mark').'>'.$this->_group.'</strong>'; + $this->_line .= '<strong '.HTMLDiff::css('diff-mark').'>'.$this->_escape($this->_group).'</strong>'; elseif ($this->_tag == 'add') - $this->_line .= '<span '.HTMLDiff::css('diff-addedline').'>'.$this->_group.'</span>'; + $this->_line .= '<span '.HTMLDiff::css('diff-addedline').'>'.$this->_escape($this->_group).'</span>'; elseif ($this->_tag == 'del') - $this->_line .= '<span '.HTMLDiff::css('diff-deletedline').'><del>'.$this->_group.'</del></span>'; + $this->_line .= '<span '.HTMLDiff::css('diff-deletedline').'><del>'.$this->_escape($this->_group).'</del></span>'; else - $this->_line .= $this->_group; + $this->_line .= $this->_escape($this->_group); } $this->_group = ''; $this->_tag = $new_tag; @@ -912,6 +916,10 @@ class _HWLDF_WordAccumulator { $this->_flushLine('~done'); return $this->_lines; } + + function _escape($str){ + return hsc($str); + } } class WordLevelDiff extends MappedDiff { @@ -1029,6 +1037,7 @@ class UnifiedDiffFormatter extends DiffFormatter { * */ class TableDiffFormatter extends DiffFormatter { + var $colspan = 2; function __construct() { $this->leading_context_lines = 2; @@ -1053,8 +1062,8 @@ class TableDiffFormatter extends DiffFormatter { global $lang; $l1 = $lang['line'].' '.$xbeg; $l2 = $lang['line'].' '.$ybeg; - $r = '<tr><td '.HTMLDiff::css('diff-blockheader').' colspan="2">'.$l1.":</td>\n". - '<td '.HTMLDiff::css('diff-blockheader').' colspan="2">'.$l2.":</td>\n". + $r = '<tr><td '.HTMLDiff::css('diff-blockheader').' colspan="'.$this->colspan.'">'.$l1.":</td>\n". + '<td '.HTMLDiff::css('diff-blockheader').' colspan="'.$this->colspan.'">'.$l2.":</td>\n". "</tr>\n"; return $r; } @@ -1069,25 +1078,38 @@ class TableDiffFormatter extends DiffFormatter { function _lines($lines, $prefix=' ', $color="white") { } - function addedLine($line) { - return '<td>+</td><td '.HTMLDiff::css('diff-addedline').'>' . $line.'</td>'; + function addedLine($line,$escaped=false) { + if (!$escaped){ + $line = $this->_escape($line); + } + return '<td '.HTMLDiff::css('diff-lineheader').'>+</td>'. + '<td '.HTMLDiff::css('diff-addedline').'>' . $line.'</td>'; } - function deletedLine($line) { - return '<td>-</td><td '.HTMLDiff::css('diff-deletedline').'>' . $line.'</td>'; + function deletedLine($line,$escaped=false) { + if (!$escaped){ + $line = $this->_escape($line); + } + return '<td '.HTMLDiff::css('diff-lineheader').'>-</td>'. + '<td '.HTMLDiff::css('diff-deletedline').'>' . $line.'</td>'; } function emptyLine() { - return '<td colspan="2"> </td>'; + return '<td colspan="'.$this->colspan.'"> </td>'; } function contextLine($line) { - return '<td> </td><td '.HTMLDiff::css('diff-context').'>'.$line.'</td>'; + return '<td '.HTMLDiff::css('diff-lineheader').'> </td>'. + '<td '.HTMLDiff::css('diff-context').'>'.$this->_escape($line).'</td>'; } function _added($lines) { + $this->_addedLines($lines,false); + } + + function _addedLines($lines,$escaped=false){ foreach ($lines as $line) { - print('<tr>' . $this->emptyLine() . $this->addedLine($line) . "</tr>\n"); + print('<tr>' . $this->emptyLine() . $this->addedLine($line,$escaped) . "</tr>\n"); } } @@ -1104,15 +1126,19 @@ class TableDiffFormatter extends DiffFormatter { } function _changed($orig, $closing) { - $diff = new WordLevelDiff($orig, $closing); + $diff = new WordLevelDiff($orig, $closing); // this escapes the diff data $del = $diff->orig(); $add = $diff->closing(); while ($line = array_shift($del)) { $aline = array_shift($add); - print('<tr>' . $this->deletedLine($line) . $this->addedLine($aline) . "</tr>\n"); + print('<tr>' . $this->deletedLine($line,true) . $this->addedLine($aline,true) . "</tr>\n"); } - $this->_added($add); # If any leftovers + $this->_addedLines($add,true); # If any leftovers + } + + function _escape($str) { + return hsc($str); } } @@ -1121,7 +1147,7 @@ class TableDiffFormatter extends DiffFormatter { * */ class InlineDiffFormatter extends DiffFormatter { - var $colspan = 4; + var $colspan = 2; function __construct() { $this->leading_context_lines = 2; @@ -1167,28 +1193,32 @@ class InlineDiffFormatter extends DiffFormatter { function _added($lines) { foreach ($lines as $line) { - print('<tr><td colspan="'.$this->colspan.'" '.HTMLDiff::css('diff-addedline').'>'. $line . "</td></tr>\n"); + print('<tr><td '.HTMLDiff::css('diff-lineheader').'> </td><td '.HTMLDiff::css('diff-addedline').'>'. $this->_escape($line) . "</td></tr>\n"); } } function _deleted($lines) { foreach ($lines as $line) { - print('<tr><td colspan="'.$this->colspan.'" '.HTMLDiff::css('diff-deletedline').'><del>' . $line . "</del></td></tr>\n"); + print('<tr><td '.HTMLDiff::css('diff-lineheader').'> </td><td '.HTMLDiff::css('diff-deletedline').'><del>' . $this->_escape($line) . "</del></td></tr>\n"); } } function _context($lines) { foreach ($lines as $line) { - print('<tr><td colspan="'.$this->colspan.'" '.HTMLDiff::css('diff-context').'>'.$line."</td></tr>\n"); + print('<tr><td '.HTMLDiff::css('diff-lineheader').'> </td><td '.HTMLDiff::css('diff-context').'>'. $this->_escape($line) ."</td></tr>\n"); } } function _changed($orig, $closing) { - $diff = new InlineWordLevelDiff($orig, $closing); + $diff = new InlineWordLevelDiff($orig, $closing); // this escapes the diff data $add = $diff->inline(); foreach ($add as $line) - print('<tr><td colspan="'.$this->colspan.'">'.$line."</td></tr>\n"); + print('<tr><td '.HTMLDiff::css('diff-lineheader').'> </td><td>'.$line."</td></tr>\n"); + } + + function _escape($str) { + return hsc($str); } } diff --git a/inc/html.php b/inc/html.php index c2723bcebda5db93d873f7e42fea83cb97eb1600..59415f7da0e602f3fb1cd3dde04fe4b4e9ccf4a6 100644 --- a/inc/html.php +++ b/inc/html.php @@ -1003,14 +1003,16 @@ function html_backlinks(){ * @param string $r_rev Right revision * @param string $id Page id, if null $ID is used * @param bool $media If it is for media files + * @param bool $inline Return the header on a single line * @return array HTML snippets for diff header */ -function html_diff_head($l_rev, $r_rev, $id = null, $media = false) { +function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = false) { global $lang; if ($id === null) { global $ID; $id = $ID; } + $head_separator = $inline ? ' ' : '<br />'; $media_or_wikiFN = $media ? 'mediaFN' : 'wikiFN'; $ml_or_wl = $media ? 'ml' : 'wl'; $l_minor = $r_minor = ''; @@ -1032,7 +1034,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false) { $l_head_title = ($media) ? dformat($l_rev) : $id.' ['.dformat($l_rev).']'; $l_head = '<a class="wikilink1" href="'.$ml_or_wl($id,"rev=$l_rev").'">'. $l_head_title.'</a>'. - '<br />'.$l_user.' '.$l_sum; + $head_separator.$l_user.' '.$l_sum; } if($r_rev){ @@ -1050,7 +1052,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false) { $r_head_title = ($media) ? dformat($r_rev) : $id.' ['.dformat($r_rev).']'; $r_head = '<a class="wikilink1" href="'.$ml_or_wl($id,"rev=$r_rev").'">'. $r_head_title.'</a>'. - '<br />'.$r_user.' '.$r_sum; + $head_separator.$r_user.' '.$r_sum; }elseif($_rev = @filemtime($media_or_wikiFN($id))){ $_info = getRevisionInfo($id,$_rev,true, $media); if($_info['user']){ @@ -1067,7 +1069,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false) { $r_head = '<a class="wikilink1" href="'.$ml_or_wl($id).'">'. $r_head_title.'</a> '. '('.$lang['current'].')'. - '<br />'.$_user.' '.$_sum; + $head_separator.$_user.' '.$_sum; }else{ $r_head = '— ('.$lang['current'].')'; } @@ -1160,10 +1162,10 @@ function html_diff($text='',$intro=true,$type=null){ } $r_text = rawWiki($ID,$r_rev); - list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev); + list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev, null, false, $type == 'inline'); } - $df = new Diff(explode("\n",hsc($l_text)),explode("\n",hsc($r_text))); + $df = new Diff(explode("\n",$l_text),explode("\n",$r_text)); if($type == 'inline'){ $tdf = new InlineDiffFormatter(); @@ -1205,6 +1207,18 @@ function html_diff($text='',$intro=true,$type=null){ ?> <div class="table"> <table class="diff diff_<?php echo $type?>"> + <?php if ($type == 'inline') { ?> + <tr> + <th class="diff-lineheader">-</th><th <?php echo $l_minor?>> + <?php echo $l_head?> + </th> + </tr> + <tr> + <th class="diff-lineheader">+</th><th <?php echo $r_minor?>> + <?php echo $r_head?> + </th> + </tr> + <?php } else { ?> <tr> <th colspan="2" <?php echo $l_minor?>> <?php echo $l_head?> @@ -1213,7 +1227,8 @@ function html_diff($text='',$intro=true,$type=null){ <?php echo $r_head?> </th> </tr> - <?php echo html_insert_softbreaks($tdf->format($df)); ?> + <?php } + echo html_insert_softbreaks($tdf->format($df)); ?> </table> </div> <?php @@ -1238,8 +1253,8 @@ function html_softbreak_callback($match){ &\#?\\w{1,6};) # ... for html entities - we don't want to split them (ok to catch some invalid combinations) &\#?\\w{1,6}; # yes pattern - a quicker match for the html entity, since we know we have one | -[?/,&\#;:]+ # no pattern - any other group of 'special' characters to insert a breaking character after -) # end conditional expression +[?/,&\#;:] # no pattern - any other group of 'special' characters to insert a breaking character after +)+ # end conditional expression REGEX; return preg_replace('<'.$regex.'>xu','\0​',$match[0]); diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index 3405ec258355b0b0411afd5c5d035b744292493d..4772fd2a5ec1e583c60a555a12b56528dea11434 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -632,7 +632,6 @@ div.dokuwiki td.diff-blockheader { div.dokuwiki table.diff th { border-bottom: 1px solid __border__; font-size: 110%; - width: 50%; font-weight: normal; text-align: left; } @@ -650,6 +649,17 @@ div.dokuwiki table.diff th span.sum { div.dokuwiki table.diff th.minor { font-style: italic; } +.dokuwiki table.diff_sidebyside th { + width: 50%; +} +.dokuwiki table.diff .diff-lineheader { + width: .7em; + text-align: right; +} +[dir=rtl] .dokuwiki table.diff .diff-lineheader { + text-align: left; +} +.dokuwiki table.diff .diff-lineheader, div.dokuwiki table.diff td { font-family: monospace; font-size: 100%; diff --git a/lib/tpl/dokuwiki/css/_diff.css b/lib/tpl/dokuwiki/css/_diff.css index 62f8312133d602be4d6154018b37670e30cf9b80..58c24b5c79b840595350f6cff7f62ae99b40ca59 100644 --- a/lib/tpl/dokuwiki/css/_diff.css +++ b/lib/tpl/dokuwiki/css/_diff.css @@ -21,7 +21,6 @@ .dokuwiki table.diff th { border-bottom: 1px solid __border__; font-size: 110%; - width: 50%; font-weight: normal; } .dokuwiki table.diff th a { @@ -37,8 +36,19 @@ .dokuwiki table.diff th.minor { color: #999; } +.dokuwiki table.diff_sidebyside th { + width: 50%; +} /* table body */ +.dokuwiki table.diff .diff-lineheader { + width: .7em; + text-align: right; +} +[dir=rtl] .dokuwiki table.diff .diff-lineheader { + text-align: left; +} +.dokuwiki table.diff .diff-lineheader, .dokuwiki table.diff td { font-family: Consolas, "Andale Mono WT", "Andale Mono", "Bitstream Vera Sans Mono", "Nimbus Mono L", Monaco, "Courier New", monospace; }