]> Sergey Matveev's repositories - public-inbox.git/commitdiff
view: diffstat anchors for multi-message/attachment views
authorEric Wong <e@80x24.org>
Thu, 31 Jan 2019 11:33:49 +0000 (11:33 +0000)
committerEric Wong <e@80x24.org>
Fri, 1 Feb 2019 01:49:39 +0000 (01:49 +0000)
diffstat <-> ^diff anchors work within the same attachment or
message while in HTML views which display multiple messages.

Documentation/design_www.txt
lib/PublicInbox/View.pm
lib/PublicInbox/ViewDiff.pm
lib/PublicInbox/WwwAtomStream.pm

index c7d7fcbc7900183d646be7da73e7dfccf5c1ae8c..cd715b2a3f50abd10d3b644628114b0dd3fd296c 100644 (file)
@@ -6,12 +6,15 @@ URL and anchor naming
 /$INBOX/new.atom                       -> Atom feed
 
 #### Optional, relies on Search::Xapian
-/$INBOX/$MESSAGE_ID/t/                 -> HTML content of thread
+/$INBOX/$MESSAGE_ID/t/                 -> HTML content of thread (nested)
+/$INBOX/$MESSAGE_ID/T/                 -> HTML content of thread (flat)
        anchors:
        #u          location of $MESSAGE_ID in URL
        #m<SHA-1>   per-message links, where <SHA-1> is of the Message-ID
                    of each message (stable)
        #s<NUM>     relative numeric position of message in thread (unstable)
+       #i<...>     diffstat location for patch emails
+       #Z?<...>    per-file diff header location for patch emails
 
 /$INBOX/$MESSAGE_ID/t.atom             -> Atom feed for thread
 /$INBOX/$MESSAGE_ID/t.mbox.gz          -> gzipped mbox of thread
index ca9b95505f6c767784d77023d8ec5fe500cf1a7e..8c8125369a69eb2b3e5961b5258a5c2056725f9a 100644 (file)
@@ -37,7 +37,7 @@ sub msg_html {
                if ($nr == 1) {
                        # $more cannot be true w/o $smsg being defined:
                        my $upfx = $more ? '../'.mid_escape($smsg->mid).'/' : '';
-                       $tip . multipart_text_as_html($mime, $upfx, $ibx) .
+                       $tip . multipart_text_as_html($mime, $upfx, $ctx) .
                                '</pre><hr>'
                } elsif ($more && @$more) {
                        ++$end;
@@ -90,7 +90,7 @@ sub msg_html_more {
                        my $mime = $smsg->{mime};
                        my $upfx = '../' . mid_escape($smsg->mid) . '/';
                        _msg_html_prepare($mime->header_obj, $ctx, $more, $nr) .
-                               multipart_text_as_html($mime, $upfx, $ibx) .
+                               multipart_text_as_html($mime, $upfx, $ctx) .
                                '</pre><hr>'
                } else {
                        '';
@@ -262,7 +262,7 @@ sub index_entry {
 
        # scan through all parts, looking for displayable text
        my $ibx = $ctx->{-inbox};
-       msg_iter($mime, sub { $rv .= add_text_body($mhref, $ibx, $_[0]) });
+       msg_iter($mime, sub { $rv .= add_text_body($mhref, $ctx, $_[0]) });
 
        # add the footer
        $rv .= "\n<a\nhref=#$id_m\nid=e$id>^</a> ".
@@ -490,11 +490,11 @@ sub thread_html {
 }
 
 sub multipart_text_as_html {
-       my ($mime, $upfx, $ibx) = @_;
+       my ($mime, $upfx, $ctx) = @_;
        my $rv = "";
 
        # scan through all parts, looking for displayable text
-       msg_iter($mime, sub { $rv .= add_text_body($upfx, $ibx, $_[0]) });
+       msg_iter($mime, sub { $rv .= add_text_body($upfx, $ctx, $_[0]) });
        $rv;
 }
 
@@ -547,10 +547,11 @@ sub attach_link ($$$$;$) {
 }
 
 sub add_text_body {
-       my ($upfx, $ibx, $p) = @_;
+       my ($upfx, $ctx, $p) = @_;
+       my $ibx = $ctx->{-inbox};
        my $obfs_ibx = $ibx->{obfuscate} ? $ibx : undef;
        # $p - from msg_iter: [ Email::MIME, depth, @idx ]
-       my ($part, $depth) = @$p; # attachment @idx is unused
+       my ($part, $depth, @idx) = @$p;
        my $ct = $part->content_type || 'text/plain';
        my $fn = $part->filename;
        my ($s, $err) = msg_part_text($part, $ct);
@@ -561,9 +562,16 @@ sub add_text_body {
        # link generation in diffs with the extra '%0D'
        $s =~ s/\r\n/\n/sg;
 
-       my ($diff, $spfx);
+       # always support diff-highlighting, but we can't linkify hunk
+       # headers for solver unless some coderepo are configured:
+       my $diff;
        if ($s =~ /^(?:diff|---|\+{3}) /ms) {
-               $diff = [];
+               # diffstat anchors do not link across attachments or messages:
+               $idx[0] = $upfx . $idx[0] if $upfx ne '';
+               $ctx->{-apfx} = join('/', @idx);
+               $ctx->{-anchors} = {}; # attr => filename
+               $ctx->{-diff} = $diff = [];
+               my $spfx;
                if ($ibx->{-repo_objs}) {
                        my $n_slash = $upfx =~ tr!/!/!;
                        if ($n_slash == 0) {
@@ -574,6 +582,7 @@ sub add_text_body {
                                $spfx = '../../';
                        }
                }
+               $ctx->{-spfx} = $spfx;
        };
 
        my @lines = split(/^/m, $s);
@@ -598,18 +607,18 @@ sub add_text_body {
                                $s .= $l->linkify_2(ascii_html($cur));
                        }
                } else {
-                       flush_diff(\$s, $spfx, $l, $diff) if $diff && @$diff;
+                       flush_diff(\$s, $ctx, $l) if $diff && @$diff;
                        push @quot, $cur;
                }
        }
 
        if (@quot) { # ugh, top posted
                flush_quote(\$s, $l, \@quot);
-               flush_diff(\$s, $spfx, $l, $diff) if $diff && @$diff;
+               flush_diff(\$s, $ctx, $l) if $diff && @$diff;
                obfuscate_addrs($obfs_ibx, $s) if $obfs_ibx;
                $s;
        } else {
-               flush_diff(\$s, $spfx, $l, $diff) if $diff && @$diff;
+               flush_diff(\$s, $ctx, $l) if $diff && @$diff;
                obfuscate_addrs($obfs_ibx, $s) if $obfs_ibx;
                if ($s =~ /\n\z/s) { # common, last line ends with a newline
                        $s;
index 38cb5a18d711b980b87b5eafea55f973f11e2a47..2074e12fffbd01a5deb6ffd955849e7aaafd185d 100644 (file)
@@ -76,10 +76,10 @@ sub to_state ($$$) {
 }
 
 sub anchor0 ($$$$$) {
-       my ($dst, $anchors, $linkify, $fn, $rest) = @_;
-       if (my $attr = to_attr($fn)) {
-               $anchors->{$attr} = 1;
-               $$dst .= " <a\nhref=#$attr>" .
+       my ($dst, $ctx, $linkify, $fn, $rest) = @_;
+       if (my $attr = to_attr($ctx->{-apfx}.$fn)) {
+               $ctx->{-anchors}->{$attr} = 1;
+               $$dst .= " <a\nid=i$attr\nhref=#$attr>" .
                        ascii_html($fn) . '</a>'.
                        to_html($linkify, $rest);
                return 1;
@@ -88,33 +88,33 @@ sub anchor0 ($$$$$) {
 }
 
 sub anchor1 ($$$$$) {
-       my ($dst, $anchors, $linkify, $pb, $s) = @_;
-       my $attr = to_attr($pb) or return;
+       my ($dst, $ctx, $linkify, $pb, $s) = @_;
+       my $attr = to_attr($ctx->{-apfx}.$pb) or return;
        my $line = to_html($linkify, $s);
 
-       if (delete $anchors->{$attr} && $line =~ s/^diff //) {
-               $$dst .= "<a\nhref=#ds\nid=$attr>diff</a> ".$line;
+       if (delete $ctx->{-anchors}->{$attr} && $line =~ s/^diff //) {
+               $$dst .= "<a\nhref=#i$attr\nid=$attr>diff</a> ".$line;
                return 1;
        }
        undef
 }
 
-sub flush_diff ($$$$) {
-       my ($dst, $spfx, $linkify, $diff) = @_;
+sub flush_diff ($$$) {
+       my ($dst, $ctx, $linkify) = @_;
+       my $diff = $ctx->{-diff};
+       my $spfx = $ctx->{-spfx};
        my $state = DSTATE_INIT;
        my $dctx = { Q => '' }; # {}, keys: oid_a, oid_b, path_a, path_b
-       my $anchors = {}; # attr => filename
 
        foreach my $s (@$diff) {
                if ($s =~ /^---$/) {
                        to_state($dst, $state, DSTATE_STAT);
-                       $$dst .= "<span\nid=ds>" . $s . '</span>';
+                       $$dst .= $s;
                } elsif ($s =~ /^ /) {
                        # works for common cases, but not weird/long filenames
                        if ($state == DSTATE_STAT &&
                                        $s =~ /^ (\S+)(\s+\|.*\z)/s) {
-                               anchor0($dst, $anchors, $linkify, $1, $2)
-                                       and next;
+                               anchor0($dst, $ctx, $linkify, $1, $2) and next;
                        } elsif ($state2class[$state]) {
                                to_state($dst, $state, DSTATE_CTX);
                        }
@@ -136,8 +136,7 @@ sub flush_diff ($$$$) {
                                        $dctx->{Q} .=
                                             "&a=".uri_escape_utf8($pa, UNSAFE);
                                }
-                               anchor1($dst, $anchors, $linkify, $pb, $s)
-                                       and next;
+                               anchor1($dst, $ctx, $linkify, $pb, $s) and next;
                        }
                        $$dst .= to_html($linkify, $s);
                } elsif ($s =~ s/^(index $OID_NULL\.\.)($OID_BLOB)\b//o) {
index 712c3dc88e34a3c210d6f74ac2ebd013c2863f91..6d3a93649b29162a42d6892ced17ab256a366425 100644 (file)
@@ -137,7 +137,7 @@ sub feed_entry {
                qq{<content\ntype="xhtml">} .
                qq{<div\nxmlns="http://www.w3.org/1999/xhtml">} .
                qq(<pre\nstyle="white-space:pre-wrap">) .
-               PublicInbox::View::multipart_text_as_html($mime, $href) .
+               PublicInbox::View::multipart_text_as_html($mime, $href, $ctx) .
                '</pre></div></content></entry>';
 }