For /all/ (extindex) and like, Message-ID reuse from client
errors or list-injected footers can cause threading weirdness.
Avoid auto-vivification in the mapping table and dereferencing
of unknown messages.
sub mailto_arg_link {
my ($ibx, $hdr) = @_;
my $cc = {}; # everyone else
sub mailto_arg_link {
my ($ibx, $hdr) = @_;
my $cc = {}; # everyone else
- my $to; # this is the From address by defaultq
+ my $to; # this is the From address by default
my $reply_to_all = 'reply-to-all'; # the only good default :P
my $reply_to_cfg = $ibx->{replyto};
my $reply_to_all = 'reply-to-all'; # the only good default :P
my $reply_to_cfg = $ibx->{replyto};
my $mid = $hdr->header_raw('Message-ID');
push @arg, '--in-reply-to='.squote_maybe(mid_clean($mid));
my $irt = mid_href($mid);
my $mid = $hdr->header_raw('Message-ID');
push @arg, '--in-reply-to='.squote_maybe(mid_clean($mid));
my $irt = mid_href($mid);
+ add_addrs(\$to, $cc, $ibx->{-primary_address}) unless defined($to);
delete $cc->{$to};
if ($obfs) {
my $arg_to = $to;
delete $cc->{$to};
if ($obfs) {
my $arg_to = $to;
sub pad_link ($$;$) {
my ($mid, $level, $s) = @_;
$s ||= '...';
sub pad_link ($$;$) {
my ($mid, $level, $s) = @_;
$s ||= '...';
- my $id = id_compress($mid, 1);
- (' 'x19).indent_for($level).th_pfx($level)."<a\nhref=#r$id>($s)</a>\n";
+ my $href = defined($mid) ?
+ ("<a\nhref=#r".id_compress($mid, 1).">($s)</a>\n") :
+ "($s)\n";
+ (' 'x19).indent_for($level).th_pfx($level).$href;
+}
+
+sub _skel_hdr {
+ # my ($mapping, $mid) = @_;
+ ($_[0]->{$_[1] // \'bogus'} // [ "(?)\n" ])->[0];
my $s = ($idx - 1). ' preceding siblings ...';
$rv .= pad_link($pmid, $level, $s);
} elsif ($idx == 2) {
my $s = ($idx - 1). ' preceding siblings ...';
$rv .= pad_link($pmid, $level, $s);
} elsif ($idx == 2) {
- my $ppmid = $siblings->[0]->{mid};
- $rv .= $pad . $mapping->{$ppmid}->[0];
+ $rv .= $pad . _skel_hdr($mapping,
+ $siblings->[0] ?
+ $siblings->[0]->{mid} : undef);
- $rv .= $pad . $mapping->{$pmid}->[0];
+ $rv .= $pad . _skel_hdr($mapping, $pmid);
}
}
my $s_s = nr_to_s($nr_s, 'sibling', 'siblings');
}
}
my $s_s = nr_to_s($nr_s, 'sibling', 'siblings');
$attr =~ s!<a\nhref=[^>]+>([^<]+)</a>!$1!s; # no point linking to self
$rv .= "<b>@ $attr";
if ($nr_c) {
$attr =~ s!<a\nhref=[^>]+>([^<]+)</a>!$1!s; # no point linking to self
$rv .= "<b>@ $attr";
if ($nr_c) {
- my $cmid = $children->[0]->{mid};
- $rv .= $pad . $mapping->{$cmid}->[0];
+ my $cmid = $children->[0] ? $children->[0]->{mid} : undef;
+ $rv .= $pad . _skel_hdr($mapping, $cmid);
if ($nr_c > 2) {
my $s = ($nr_c - 1). ' more replies';
$rv .= pad_link($cmid, $level + 1, $s);
} elsif (my $cn = $children->[1]) {
if ($nr_c > 2) {
my $s = ($nr_c - 1). ' more replies';
$rv .= pad_link($cmid, $level + 1, $s);
} elsif (my $cn = $children->[1]) {
- $rv .= $pad . $mapping->{$cn->{mid}}->[0];
+ $rv .= $pad . _skel_hdr($mapping, $cn->{mid});
}
}
my $next = $siblings->[$idx+1] if $siblings && $idx >= 0;
if ($next) {
my $nmid = $next->{mid};
}
}
my $next = $siblings->[$idx+1] if $siblings && $idx >= 0;
if ($next) {
my $nmid = $next->{mid};
- $rv .= $pad . $mapping->{$nmid}->[0];
+ $rv .= $pad . _skel_hdr($mapping, $nmid);
my $nnext = $nr_s - $idx;
if ($nnext > 2) {
my $s = ($nnext - 1).' subsequent siblings';
$rv .= pad_link($nmid, $level, $s);
} elsif (my $nn = $siblings->[$idx + 2]) {
my $nnext = $nr_s - $idx;
if ($nnext > 2) {
my $s = ($nnext - 1).' subsequent siblings';
$rv .= pad_link($nmid, $level, $s);
} elsif (my $nn = $siblings->[$idx + 2]) {
- $rv .= $pad . $mapping->{$nn->{mid}}->[0];
+ $rv .= $pad . _skel_hdr($mapping, $nn->{mid});
}
}
$rv .= $pad ."<a\nhref=#r$id>$s_s, $s_c; $ctx->{s_nr}</a>\n";
}
}
$rv .= $pad ."<a\nhref=#r$id>$s_s, $s_c; $ctx->{s_nr}</a>\n";
$ctx->{skel} = \$skel;
$ctx->{prev_attr} = '';
$ctx->{prev_level} = 0;
$ctx->{skel} = \$skel;
$ctx->{prev_attr} = '';
$ctx->{prev_level} = 0;
- $ctx->{root_anchor} = anchor_for($mid);
- $ctx->{mapping} = {};
+ $ctx->{root_anchor} = 'm' . id_compress($mid, 1);
+ $ctx->{mapping} = {}; # mid -> [ header_summary, node, idx, level ]
$ctx->{s_nr} = ($nr > 1 ? "$nr+ messages" : 'only message')
.' in thread';
$ctx->{s_nr} = ($nr > 1 ? "$nr+ messages" : 'only message')
.' in thread';
"<<a\nhref=\"../$href/\">$html</a>>";
}
"<<a\nhref=\"../$href/\">$html</a>>";
}
-sub anchor_for {
- my ($msgid) = @_;
- 'm' . id_compress($msgid, 1);
-}
-
sub ghost_parent {
my ($upfx, $mid) = @_;
sub ghost_parent {
my ($upfx, $mid) = @_;
sub ghost_index_entry {
my ($ctx, $level, $node) = @_;
my ($beg, $end) = thread_adj_level($ctx, $level);
sub ghost_index_entry {
my ($ctx, $level, $node) = @_;
my ($beg, $end) = thread_adj_level($ctx, $level);
- $beg . '<pre>'. ghost_parent($ctx->{-upfx}, $node->{mid})
+ $beg . '<pre>'. ghost_parent($ctx->{-upfx}, $node->{mid} // '?')