-sub ghost_table {
- my ($upfx, $mid, $level) = @_;
- "<table\nsummary=ghost><tr><td>" .
- (INDENT x $level) . "</td><td>" .
- PRE_WRAP . ghost_parent($upfx, $mid) .
- '</pre></td></table>';
-}
-
-sub __thread_entry {
- my ($cb, $git, $state, $mime, $level) = @_;
-
- # lazy load the full message from mini_mime:
- $mime = eval {
- my $path = mid2path(mid_clean($mime->header('Message-ID')));
- Email::MIME->new($git->cat_file('HEAD:'.$path));
- } or return;
-
- if ($state->{anchor_idx} == 0) {
- thread_html_head($cb, $mime, $state);
- }
-
- if (my $ghost = delete $state->{ghost}) {
- # n.b. ghost messages may only be parents, not children
- foreach my $g (@$ghost) {
- $$cb->write(ghost_table('../../', @$g));
- }
- }
- index_entry($$cb, $mime, $level, $state);
- 1;
-}
-
-sub __ghost_entry {
- my ($state, $node, $level) = @_;
- my $ghost = $state->{ghost} ||= [];
- push @$ghost, [ $node->messageid, $level ];
-}
-
-sub thread_entry {
- my ($cb, $git, $state, $node, $level) = @_;
- return unless $node;
- if (my $mime = $node->message) {
- unless (__thread_entry($cb, $git, $state, $mime, $level)) {
- __ghost_entry($state, $node, $level);
- }
- } else {
- __ghost_entry($state, $node, $level);
- }
-
- thread_entry($cb, $git, $state, $node->child, $level + 1);
- thread_entry($cb, $git, $state, $node->next, $level);