]> Lady’s Gitweb - Gitweb/blobdiff - gitweb.perl
gitweb: Push formatting diff lines to print_diff_chunk()
[Gitweb] / gitweb.perl
index 0d86a7f111fa78e1646689001ce16fc33d6633e2d364f680622709dccc772c24..244bde6c90d165aed2f0aa0fd9012e9d6c08167ec37267b237c088f4c0635364 100755 (executable)
@@ -2431,26 +2431,26 @@ sub format_cc_diff_chunk_header {
 }
 
 # process patch (diff) line (not to be used for diff headers),
-# returning class and HTML-formatted (but not wrapped) line
-sub process_diff_line {
-       my $line = shift;
-       my ($from, $to) = @_;
-
-       my $diff_class = diff_line_class($line, $from, $to);
+# returning HTML-formatted (but not wrapped) line
+sub format_diff_line {
+       my ($line, $diff_class, $from, $to) = @_;
 
        chomp $line;
        $line = untabify($line);
 
        if ($from && $to && $line =~ m/^\@{2} /) {
                $line = format_unidiff_chunk_header($line, $from, $to);
-               return $diff_class, $line;
-
        } elsif ($from && $to && $line =~ m/^\@{3}/) {
                $line = format_cc_diff_chunk_header($line, $from, $to);
-               return $diff_class, $line;
-
+       } else {
+               $line = esc_html($line, -nbsp=>1);
        }
-       return $diff_class, esc_html($line, -nbsp=>1);
+
+       my $diff_classes = "diff";
+       $diff_classes .= " $diff_class" if ($diff_class);
+       $line = "<div class=\"$diff_classes\">$line</div>\n";
+
+       return $line;
 }
 
 # Generates undef or something like "_snapshot_" or "snapshot (_tbz2_ _zip_)",
@@ -5004,10 +5004,78 @@ sub git_difftree_body {
        print "</table>\n";
 }
 
-sub print_sidebyside_diff_chunk {
-       my @chunk = @_;
+# Print context lines and then rem/add lines in a side-by-side manner.
+sub print_sidebyside_diff_lines {
+       my ($ctx, $rem, $add) = @_;
+
+       # print context block before add/rem block
+       if (@$ctx) {
+               print join '',
+                       '<div class="chunk_block ctx">',
+                               '<div class="old">',
+                               @$ctx,
+                               '</div>',
+                               '<div class="new">',
+                               @$ctx,
+                               '</div>',
+                       '</div>';
+       }
+
+       if (!@$add) {
+               # pure removal
+               print join '',
+                       '<div class="chunk_block rem">',
+                               '<div class="old">',
+                               @$rem,
+                               '</div>',
+                       '</div>';
+       } elsif (!@$rem) {
+               # pure addition
+               print join '',
+                       '<div class="chunk_block add">',
+                               '<div class="new">',
+                               @$add,
+                               '</div>',
+                       '</div>';
+       } else {
+               print join '',
+                       '<div class="chunk_block chg">',
+                               '<div class="old">',
+                               @$rem,
+                               '</div>',
+                               '<div class="new">',
+                               @$add,
+                               '</div>',
+                       '</div>';
+       }
+}
+
+# Print context lines and then rem/add lines in inline manner.
+sub print_inline_diff_lines {
+       my ($ctx, $rem, $add) = @_;
+
+       print @$ctx, @$rem, @$add;
+}
+
+# Print context lines and then rem/add lines.
+sub print_diff_lines {
+       my ($ctx, $rem, $add, $diff_style, $is_combined) = @_;
+
+       if ($diff_style eq 'sidebyside' && !$is_combined) {
+               print_sidebyside_diff_lines($ctx, $rem, $add);
+       } else {
+               # default 'inline' style and unknown styles
+               print_inline_diff_lines($ctx, $rem, $add);
+       }
+}
+
+sub print_diff_chunk {
+       my ($diff_style, $is_combined, $from, $to, @chunk) = @_;
        my (@ctx, @rem, @add);
 
+       # The class of the previous line.
+       my $prev_class = '';
+
        return unless @chunk;
 
        # incomplete last line might be among removed or added lines,
@@ -5024,57 +5092,23 @@ sub print_sidebyside_diff_chunk {
        foreach my $line_info (@chunk) {
                my ($class, $line) = @$line_info;
 
+               $line = format_diff_line($line, $class, $from, $to);
+
                # print chunk headers
                if ($class && $class eq 'chunk_header') {
                        print $line;
                        next;
                }
 
-               ## print from accumulator when type of class of lines change
-               # empty contents block on start rem/add block, or end of chunk
-               if (@ctx && (!$class || $class eq 'rem' || $class eq 'add')) {
-                       print join '',
-                               '<div class="chunk_block ctx">',
-                                       '<div class="old">',
-                                       @ctx,
-                                       '</div>',
-                                       '<div class="new">',
-                                       @ctx,
-                                       '</div>',
-                               '</div>';
-                       @ctx = ();
-               }
-               # empty add/rem block on start context block, or end of chunk
-               if ((@rem || @add) && (!$class || $class eq 'ctx')) {
-                       if (!@add) {
-                               # pure removal
-                               print join '',
-                                       '<div class="chunk_block rem">',
-                                               '<div class="old">',
-                                               @rem,
-                                               '</div>',
-                                       '</div>';
-                       } elsif (!@rem) {
-                               # pure addition
-                               print join '',
-                                       '<div class="chunk_block add">',
-                                               '<div class="new">',
-                                               @add,
-                                               '</div>',
-                                       '</div>';
-                       } else {
-                               # assume that it is change
-                               print join '',
-                                       '<div class="chunk_block chg">',
-                                               '<div class="old">',
-                                               @rem,
-                                               '</div>',
-                                               '<div class="new">',
-                                               @add,
-                                               '</div>',
-                                       '</div>';
-                       }
-                       @rem = @add = ();
+               ## print from accumulator when have some add/rem lines or end
+               # of chunk (flush context lines), or when have add and rem
+               # lines and new block is reached (otherwise add/rem lines could
+               # be reordered)
+               if (!$class || ((@rem || @add) && $class eq 'ctx') ||
+                   (@rem && @add && $class ne $prev_class)) {
+                       print_diff_lines(\@ctx, \@rem, \@add,
+                                        $diff_style, $is_combined);
+                       @ctx = @rem = @add = ();
                }
 
                ## adding lines to accumulator
@@ -5090,6 +5124,8 @@ sub print_sidebyside_diff_chunk {
                if ($class eq 'ctx') {
                        push @ctx, $line;
                }
+
+               $prev_class = $class;
        }
 }
 
@@ -5211,27 +5247,19 @@ sub git_patchset_body {
 
                        next PATCH if ($patch_line =~ m/^diff /);
 
-                       my ($class, $line) = process_diff_line($patch_line, \%from, \%to);
-                       my $diff_classes = "diff";
-                       $diff_classes .= " $class" if ($class);
-                       $line = "<div class=\"$diff_classes\">$line</div>\n";
+                       my $class = diff_line_class($patch_line, \%from, \%to);
 
-                       if ($diff_style eq 'sidebyside' && !$is_combined) {
-                               if ($class eq 'chunk_header') {
-                                       print_sidebyside_diff_chunk(@chunk);
-                                       @chunk = ( [ $class, $line ] );
-                               } else {
-                                       push @chunk, [ $class, $line ];
-                               }
-                       } else {
-                               # default 'inline' style and unknown styles
-                               print $line;
+                       if ($class eq 'chunk_header') {
+                               print_diff_chunk($diff_style, $is_combined, \%from, \%to, @chunk);
+                               @chunk = ();
                        }
+
+                       push @chunk, [ $class, $patch_line ];
                }
 
        } continue {
                if (@chunk) {
-                       print_sidebyside_diff_chunk(@chunk);
+                       print_diff_chunk($diff_style, $is_combined, \%from, \%to, @chunk);
                        @chunk = ();
                }
                print "</div>\n"; # class="patch"
This page took 0.362042 seconds and 4 git commands to generate.