Indefero

Indefero Commit Details


Date:2011-10-05 19:06:51 (13 years 2 months ago)
Author:Thomas Keller
Branch:develop, feature.diff-whitespace, feature.wiki-default-page, release-1.2, release-1.3
Commit:f19f07ec59b307b2f89bd35251dd2837758faec1
Parents: 83761c66c56cc7392d816a5d200a5cd1332f3020
Message:Change the unidiff rendering by letting the actual content be rendered into a separate container that can overflow and side-scroll for long lines.

This effectively removes the need for all kinds of line-breaking hacks
that have been applied before and only worked when the browser was
actually able to break a word group apart somewhere.

Lines are now always rendered as-is; as a nice side effect the line numbers
are always visible, independently how far one scrolled into one direction,
so the context is always clear. If the rendering area is made smaller, the
table rendering also degrades gracefully and provides horizontal scrolling
for views that did not need them before.

The size that is occupied by the number display is now also automatically
determined by the size that is needed to render the biggest line number
in a column. Empty columns are rendered with a zero size.

Currently all this works nicely with a recent version of Chrome, Firefox
still needs some fine tuning for the vertical positioning. Other browsers
are untested as of now.
Changes:

File differences

src/IDF/Diff.php
168168
169169
170170
171
171
172172
173173
174174
175175
176176
177
178
177
179178
179
180
181
182
180183
181184
182
185
186
183187
184
188
185189
186190
187191
188192
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
193204
194
195
196205
197206
198
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
199230
231
200232
201233
202234
203235
204236
205
237
206238
207239
208240
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".'<table class="diff" summary="">'."\n";
$out .= '<tr id="diff-'.md5($filename).'"><th colspan="3">'.Pluf_esc($filename).'</th></tr>'."\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('<tr class="diff-line"><td class="diff-lc">%s</td><td class="diff-lc">%s</td><td class="%s%s mono">%s</td></tr>'."\n", $line[0], $line[1], $class, $pretty, $line_content);
$offsets[] = sprintf('<td class="diff-lc">%s</td><td class="diff-lc">%s</td>', $left, $right);
$content = Pluf_esc($content);
$content = self::makeNonPrintableCharsVisible($content);
$contents[] = sprintf('<td class="%s%s mono">%s</td>', $class, $pretty, $content);
$maxlinenum = max($maxlinenum, max($left, $right));
}
if (count($file['chunks']) > $cc) {
$offsets[] = '<td class="next">...</td><td class="next">...</td>';
$contents[] = '<td class="next">&nbsp;</td>';
}
if (count($file['chunks']) > $cc)
$out .= '<tr class="diff-next"><td>...</td><td>...</td><td>&nbsp;</td></tr>'."\n";
$cc++;
}
$out .= '</table>';
$inner = '<table class="diff-content">' ."\n".
'<tr class="diff-line">' .
implode('</tr>'."\n".'<tr class="diff-line">', $contents) .
'</tr>' ."\n".
'</table>' ."\n";
$rows = count($offsets);
$colwidth = (ceil(log10($maxlinenum)) + 1) * 10;
$first = array_shift($offsets);
$out .= '<table class="diff" summary="">' ."\n".
'<colgroup><col width="'.$colwidth.'" /><col width="'.$colwidth.'" /><col width="*" /></colgroup>' ."\n".
'<tr id="diff-'.md5($filename).'">'.
'<th colspan="3">'.Pluf_esc($filename).'</th>'.
'</tr>' ."\n".
'<tr class="line">' .
$first . sprintf('<td rowspan="%d"><div class="diff-content">%s</div></td>', $rows, $inner) .
'</tr>' ."\n".
'<tr class="line">' .
implode('</tr>'."\n".'<tr class="line">', $offsets) .
'</tr>' ."\n".
'</table>' ."\n";
}
return Pluf_Template::markSafe($out);
}
private static function makeNonPrintableCharsVisible($line)
{
return preg_replace('/([^[:print:]])/e',
return preg_replace('/([^[:print:]\t])/e',
'"<span class=\"non-printable\" title=\"0x".strtoupper(bin2hex("\\1"))."\">".bin2hex("\\1")."</span>"',
$line);
}
www/media/idf/css/style.css
574574
575575
576576
577
577578
578579
579580
......
583584
584585
585586
586
587
588
589
590
587
588
591589
592590
593
591
594592
593
594
595
596
597
598
599
600
601
602
603
595604
596
597605
606
598607
599608
600
609
610
611
601612
602
603
604
605
606
613
614
607615
608616
609
610
617
618
619
620
621
622
623
611624
612625
613
614
626
627
628
629
630
631
615632
616633
617
618
619
620
634
635
636
637
638
639
621640
622641
623
624
642
643
625644
626645
627646
......
638657
639658
640659
641
642
660
661
643662
644663
645
646
664
665
647666
648667
649
650
668
669
651670
652671
653
654
672
673
655674
656675
657676
658
659
660
661
662
663
664
665
666
677
678
667679
668680
669
670
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
671696
672697
673
674698
675699
676700
table.diff {
border-bottom: 1px solid #d3d7cf;
width: 100%;
table-layout: fixed;
}
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 td {
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 {
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 {
background-color: #dfd;
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;
}
td.diff-r {
background-color: #fdd;
table.diff-content td.diff {
line-height: 12px;
padding: 2px;
font-size: 90%;
border: none;
white-space: pre;
}
td.diff {
border-bottom: none;
border-top: none;
white-space: pre;
table.diff-content td.diff-a {
background-color: #dfd;
}
table.diff-content td.diff-r {
background-color: #fdd;
}
td.diff > span.non-printable {
visibility: hidden;
table.diff-content td.diff > span.non-printable {
visibility: hidden;
color: white;
text-transform: uppercase;
float: none;
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 tr.diff-next {
background-color: #e4e8E0;
vertical-align: top;
text-align: right;
border-color: #d3d7cf;
table.diff-content td.diff > span.non-printable > * {
color: white;
}
table.diff tr.diff-next td {
padding: 1px 5px;
/*
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;
}
/**
* view file content
*/

Archive Download the corresponding diff file

Page rendered in 0.08783s using 13 queries.