X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/1c065aeeb084074bbebc0b5465f3cb4733c9aae370fb70f290c341ca32d78bdc..2ccb4d626f1a8d6c0e15e0c0253e100178d1fc7de65b383e9e090d2f20978bea:/gitweb.perl?ds=sidebyside diff --git a/gitweb.perl b/gitweb.perl index 91663a4..244bde6 100755 --- a/gitweb.perl +++ b/gitweb.perl @@ -1733,7 +1733,9 @@ sub chop_and_escape_str { # 'foobar' sub esc_html_hl_regions { my ($str, $css_class, @sel) = @_; - return esc_html($str) unless @sel; + my %opts = grep { ref($_) ne 'ARRAY' } @sel; + @sel = grep { ref($_) eq 'ARRAY' } @sel; + return esc_html($str, %opts) unless @sel; my $out = ''; my $pos = 0; @@ -1744,15 +1746,16 @@ sub esc_html_hl_regions { # Don't create empty elements. next if $end <= $begin; - my $escaped = esc_html(substr($str, $begin, $end - $begin)); + my $escaped = esc_html(substr($str, $begin, $end - $begin), + %opts); - $out .= esc_html(substr($str, $pos, $begin - $pos)) + $out .= esc_html(substr($str, $pos, $begin - $pos), %opts) if ($begin - $pos > 0); $out .= $cgi->span({-class => $css_class}, $escaped); $pos = $end; } - $out .= esc_html(substr($str, $pos)) + $out .= esc_html(substr($str, $pos), %opts) if ($pos < length($str)); return $out; @@ -2428,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 = "
$line
\n"; + + return $line; } # Generates undef or something like "_snapshot_" or "snapshot (_tbz2_ _zip_)", @@ -5001,10 +5004,78 @@ sub git_difftree_body { print "\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 '', + '
', + '
', + @$ctx, + '
', + '
', + @$ctx, + '
', + '
'; + } + + if (!@$add) { + # pure removal + print join '', + '
', + '
', + @$rem, + '
', + '
'; + } elsif (!@$rem) { + # pure addition + print join '', + '
', + '
', + @$add, + '
', + '
'; + } else { + print join '', + '
', + '
', + @$rem, + '
', + '
', + @$add, + '
', + '
'; + } +} + +# 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, @@ -5021,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 '', - '
', - '
', - @ctx, - '
', - '
', - @ctx, - '
', - '
'; - @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 '', - '
', - '
', - @rem, - '
', - '
'; - } elsif (!@rem) { - # pure addition - print join '', - '
', - '
', - @add, - '
', - '
'; - } else { - # assume that it is change - print join '', - '
', - '
', - @rem, - '
', - '
', - @add, - '
', - '
'; - } - @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 @@ -5087,6 +5124,8 @@ sub print_sidebyside_diff_chunk { if ($class eq 'ctx') { push @ctx, $line; } + + $prev_class = $class; } } @@ -5208,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 = "
$line
\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 "\n"; # class="patch"