diff --git a/src/IDF/Diff.php b/src/IDF/Diff.php
index 501b2b1..8f10e7f 100644
--- a/src/IDF/Diff.php
+++ b/src/IDF/Diff.php
@@ -168,41 +168,73 @@ class IDF_Diff
public function as_html()
{
$out = '';
- foreach ($this->files as $filename=>$file) {
+ foreach ($this->files as $filename => $file) {
$pretty = '';
$fileinfo = IDF_FileUtil::getMimeType($filename);
if (IDF_FileUtil::isSupportedExtension($fileinfo[2])) {
$pretty = ' prettyprint';
}
- $out .= "\n".'
'."\n";
- $out .= ''.Pluf_esc($filename).' |
'."\n";
+
$cc = 1;
+ $offsets = array();
+ $contents = array();
+ $maxlinenum = 0;
+
foreach ($file['chunks'] as $chunk) {
foreach ($chunk as $line) {
- if ($line[0] and $line[1]) {
+ list($left, $right, $content) = $line;
+ if ($left and $right) {
$class = 'diff diff-c';
- } elseif ($line[0]) {
+ } elseif ($left) {
$class = 'diff diff-r';
} else {
$class = 'diff diff-a';
}
- $line_content = Pluf_esc($line[2]);
- $line_content = preg_replace("/\t/", " ", $line_content);
- $line_content = self::makeNonPrintableCharsVisible($line_content);
- $out .= sprintf('%s | %s | %s |
'."\n", $line[0], $line[1], $class, $pretty, $line_content);
+
+ $offsets[] = sprintf('%s | %s | ', $left, $right);
+ $content = Pluf_esc($content);
+ $content = self::makeNonPrintableCharsVisible($content);
+ $contents[] = sprintf('%s | ', $class, $pretty, $content);
+
+ $maxlinenum = max($maxlinenum, max($left, $right));
+ }
+ if (count($file['chunks']) > $cc) {
+ $offsets[] = '... | ... | ';
+ $contents[] = ' | ';
}
- if (count($file['chunks']) > $cc)
- $out .= '... | ... | |
'."\n";
$cc++;
}
- $out .= '
';
+
+ $inner = '' ."\n".
+ '' .
+ implode('
'."\n".'', $contents) .
+ '
' ."\n".
+ '
' ."\n";
+
+ $rows = count($offsets);
+ $colwidth = (ceil(log10($maxlinenum)) + 1) * 10;
+ $first = array_shift($offsets);
+
+ $out .= '' ."\n".
+ '' ."\n".
+ ''.
+ ''.Pluf_esc($filename).' | '.
+ '
' ."\n".
+ '' .
+ $first . sprintf('%s | ', $rows, $inner) .
+ '
' ."\n".
+ '' .
+ implode('
'."\n".'', $offsets) .
+ '
' ."\n".
+ '
' ."\n";
}
+
return Pluf_Template::markSafe($out);
}
private static function makeNonPrintableCharsVisible($line)
{
- return preg_replace('/([^[:print:]])/e',
+ return preg_replace('/([^[:print:]\t])/e',
'"".bin2hex("\\1").""',
$line);
}
diff --git a/www/media/idf/css/style.css b/www/media/idf/css/style.css
index 98f0b1f..08371e9 100644
--- a/www/media/idf/css/style.css
+++ b/www/media/idf/css/style.css
@@ -574,6 +574,7 @@ table.commit table.changes table.properties td.removed {
table.diff {
border-bottom: 1px solid #d3d7cf;
width: 100%;
+ table-layout: fixed;
}
table.diff th {
@@ -583,45 +584,63 @@ table.diff th {
}
-table.diff tr {
- border-left: 1px solid #d3d7cf;
- border-right: 1px solid #d3d7cf;
- border-bottom: none;
- border-top: none;
+table.diff tr.line {
+ border: 1px solid #d3d7cf;
+}
+
+table.diff tr.line td.diff-lc {
+ font-size: 90%;
+ padding: 1px 10px;
+ text-align: right;
+ width: 20px;
+}
+
+table.diff tr.line div.diff-content {
+ overflow: auto;
+ display: block;
}
table.diff td {
- font-size: 90%;
vertical-align: top;
- padding: 1px;
border-color: inherit;
+ padding: 0;
}
-table.diff td.diff-lc {
+table.diff td.next {
+ background-color: #e4e8E0;
+ vertical-align: top;
text-align: right;
- padding: 1px 5px;
- border-color: inherit;
- border-top: 1px solid #d3d7cf;
- border-bottom: 1px solid #d3d7cf;
- width: 3em;
+ border-color: #d3d7cf;
+ padding: 1px 10px;
}
-td.diff-a {
+table.diff-content {
+ border: 0;
+ /* setting this to 100% sometimes triggers the overflow of the parent container,
+ when it is not actually needed. we try to prevent that by taking not the
+ complete available space... */
+ width: 99.99%;
+ margin: 0;
+}
+
+table.diff-content td.diff {
+ line-height: 12px;
+ padding: 2px;
+ font-size: 90%;
+ border: none;
+ white-space: pre;
+}
+
+table.diff-content td.diff-a {
background-color: #dfd;
}
-td.diff-r {
+table.diff-content td.diff-r {
background-color: #fdd;
}
-td.diff {
- border-bottom: none;
- border-top: none;
- white-space: pre;
-}
-
-td.diff > span.non-printable {
- visibility: hidden;
+table.diff-content td.diff > span.non-printable {
+ visibility: hidden;
color: white;
text-transform: uppercase;
float: none;
@@ -638,39 +657,44 @@ td.diff > span.non-printable {
vertical-align: 10%;
}
-td.diff:hover > span.non-printable {
- visibility: visible;
+table.diff-content td.diff:hover > span.non-printable {
+ visibility: visible;
}
-td.diff-a > span.non-printable {
- background: #0A0;
+table.diff-content td.diff-a > span.non-printable {
+ background: #0A0;
}
-td.diff-r > span.non-printable {
- background: #A00;
+table.diff-content td.diff-r > span.non-printable {
+ background: #A00;
}
-td.diff-c > span.non-printable {
- background: black;
+table.diff-content td.diff-c > span.non-printable {
+ background: black;
}
/* override prettify css rule */
-td.diff > span.non-printable > * {
- color: white;
+table.diff-content td.diff > span.non-printable > * {
+ color: white;
}
-table.diff tr.diff-next {
- background-color: #e4e8E0;
- vertical-align: top;
- text-align: right;
- border-color: #d3d7cf;
+/*
+ This is a special hack: the outer td.next has
+ top/bottom border and padding and comes to a total
+ height of 20px - BUT it shares the upper border
+ with the previous row, so the height is actually
+ only 19px. The inner table has no lines between rows,
+ so the upper border is counted and we have 20px
+ in the interior, which is one pixel too much for
+ every occurrence.
+ What we now do is to remove the 1px top padding and
+ therefor lower the total height of the inner one
+ again by one to match the outer.
+*/
+table.diff-content td.next {
+ padding-top: 0;
}
-table.diff tr.diff-next td {
- padding: 1px 5px;
-}
-
-
/**
* view file content
*/