lib/PublicInbox/Feed.pm | 12 ++++++++---- lib/PublicInbox/View.pm | 37 ++++++++++++++++++++----------------- lib/PublicInbox/WWW.pm | 8 ++++---- t/view.t | 10 +++++----- diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm index f4d19e0208d1355101e8e03cd521b99b6c568b8f..969fc1107652ad8b74a966eee17d9d770e580844 100644 --- a/lib/PublicInbox/Feed.pm +++ b/lib/PublicInbox/Feed.pm @@ -89,7 +89,12 @@ my $srch = $ctx->{srch}; $srch and $topics = [ [], {} ]; my (undef, $last) = each_recent_blob($ctx, sub { my ($path, $commit, $ts, $u, $subj) = @_; - $state ||= [ undef, {}, $commit, 0 ]; + $state ||= { + ctx => $ctx, + seen => {}, + first_commit => $commit, + anchor_idx => 0, + }; if ($srch) { add_topic($git, $srch, $topics, $path, $ts, $u, $subj); @@ -119,9 +124,8 @@ $cgi or return ''; my $old_r = $cgi->param('r'); my $head = ' '; my $next = ' '; - # $state = [ undef, {}, $first_commit, $last_anchor ]; - my $first = $state->[2]; - my $anchor = $state->[3]; + my $first = $state->{first_commit}; + my $anchor = $state->{anchor_idx}; if ($last) { $next = qq!next!; diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index cf5826886544ffa7879196db324944b7a3121680..64a2086d349e843b644bf94c1797173f69153966 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -25,16 +25,17 @@ my $enc_utf8 = find_encoding('UTF-8'); # public functions: sub msg_html { - my ($class, $mime, $full_pfx, $footer, $srch) = @_; + my ($ctx, $mime, $full_pfx, $footer) = @_; if (defined $footer) { $footer = "\n" . $footer; } else { $footer = ''; } + my $srch = $ctx->{srch} if $ctx; headers_to_html_header($mime, $full_pfx, $srch) . multipart_text_as_html($mime, $full_pfx) . '
' .
-		html_footer($mime, 1, $full_pfx, $srch) .
+		html_footer($mime, 1, $full_pfx, $ctx) .
 		$footer .
 		'
'; } @@ -46,11 +47,11 @@ PRE_WRAP . multipart_text_as_html($mime, $full_pfx) . ''; } # this is already inside a
-# state = [ time, seen = {}, first_commit, page_nr = 0 ]
 sub index_entry {
 	my ($fh, $mime, $level, $state) = @_;
-	my ($srch, $seen, $first_commit) = @$state;
-	my $midx = $state->[3]++;
+	my $midx = $state->{anchor_idx}++;
+	my $ctx = $state->{ctx};
+	my $srch = $ctx->{srch};
 	my ($prev, $next) = ($midx - 1, $midx + 1);
 	my $part_nr = 0;
 	my $enc = enc_for($mime->header("Content-Type"));
@@ -59,6 +60,7 @@ 	my $header_obj = $mime->header_obj;
 
 	my $mid_raw = $header_obj->header('Message-ID');
 	my $id = anchor_for($mid_raw);
+	my $seen = $state->{seen};
 	$seen->{$id} = "#$id"; # save the anchor for later
 
 	my $mid = PublicInbox::Hval->new_msgid($mid_raw);
@@ -68,8 +70,8 @@ 	$from = $from[0]->name;
 
 	$from = PublicInbox::Hval->new_oneline($from)->as_html;
 	$subj = PublicInbox::Hval->new_oneline($subj)->as_html;
-	my $root_anchor = $seen->{root_anchor};
 	my $more = 'permalink';
+	my $root_anchor = $state->{root_anchor};
 	my $path = $root_anchor ? '../' : '';
 	my $href = $mid->as_href;
 	my $irt = $header_obj->header('In-Reply-To');
@@ -81,7 +83,7 @@ 		$t_anchor = T_ANCHOR;
 	} else {
 		$t_anchor = '';
 	}
-	if (defined $srch) {
+	if ($srch) {
 		$subj = "$subj";
 	}
 	if ($root_anchor && $root_anchor eq $id) {
@@ -121,7 +123,7 @@ 	$mime->body_set('');
 
 	my $txt = "${path}m/$href.txt";
 	$rv = "\n$more raw ";
-	$rv .= html_footer($mime, 0);
+	$rv .= html_footer($mime, 0, undef, $ctx);
 
 	if (defined $irt) {
 		unless (defined $anchor) {
@@ -157,13 +159,18 @@ 	my $nr = scalar @$msgs;
 	return missing_thread($cb) if $nr == 0;
 	my $fh = $cb->([200,['Content-Type'=>'text/html; charset=UTF-8']]);
 	my $th = thread_results($msgs);
-	my $state = [ $srch, { root_anchor => anchor_for($mid) }, undef, 0 ];
+	my $state = {
+		ctx => $ctx,
+		seen => {},
+		root_anchor => anchor_for($mid),
+		anchor_idx => 0,
+	};
 	{
 		require PublicInbox::GitCatFile;
 		my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
 		thread_entry($fh, $git, $state, $_, 0) for $th->rootset;
 	}
-	my $final_anchor = $state->[3];
+	my $final_anchor = $state->{anchor_idx};
 	my $next = "";
 	$next .= $final_anchor == 1 ? 'only message in' : 'end of';
 	$next .= " thread, back to index\n";
@@ -401,7 +408,7 @@ 	 '' . PRE_WRAP . $rv);
 }
 
 sub html_footer {
-	my ($mime, $standalone, $full_pfx, $srch) = @_;
+	my ($mime, $standalone, $full_pfx, $ctx) = @_;
 	my %cc; # everyone else
 	my $to; # this is the From address
 
@@ -429,6 +436,7 @@
 	my $cc = uri_escape_utf8(join(',', sort values %cc));
 	my $href = "mailto:$to?In-Reply-To=$irt&Cc=${cc}&Subject=$subj";
 
+	my $srch = $ctx->{srch} if $ctx;
 	my $idx = $standalone ? " index" : '';
 	if ($idx && $srch) {
 		$irt = $mime->header('In-Reply-To') || '';
@@ -541,18 +549,13 @@
 sub thread_entry {
 	my ($fh, $git, $state, $node, $level) = @_;
 	return unless $node;
-	# $state = [ $search_res, $seen, undef, 0 (msg_nr) ];
-	# $seen is overloaded with 3 types of fields:
-	#	1) "root_anchor" => anchor_for(Message-ID),
-	#	2) seen subject hashes: sha1(subject) => 1
-	#	3) anchors hashes: "#$sha1_hex" (same as $seen in index_entry)
 	if (my $mime = $node->message) {
 
 		# lazy load the full message from mini_mime:
 		my $path = mid2path(mid_clean($mime->header('Message-ID')));
 		$mime = eval { Email::MIME->new($git->cat_file("HEAD:$path")) };
 		if ($mime) {
-			if ($state->[3] == 0) {
+			if ($state->{anchor_idx} == 0) {
 				$fh->write(thread_html_head($mime));
 			}
 			index_entry($fh, $mime, $level, $state);
diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm
index 86c64fb665746815a1839a9584665126a988589d..eeae3d326b0c5dd4a34dece0401f1e67f4ceca1e 100644
--- a/lib/PublicInbox/WWW.pm
+++ b/lib/PublicInbox/WWW.pm
@@ -176,9 +176,9 @@ 	my $pfx = msg_pfx($ctx);
 	my $foot = footer($ctx);
 	require Email::MIME;
 	my $mime = Email::MIME->new($x);
-	my $srch = searcher($ctx);
+	searcher($ctx);
 	[ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ],
-	  [ PublicInbox::View->msg_html($mime, $pfx, $foot, $srch) ] ];
+	  [ PublicInbox::View::msg_html($ctx, $mime, $pfx, $foot) ] ];
 }
 
 # /$LISTNAME/f/$MESSAGE_ID.html                   -> HTML content (fullquotes)
@@ -190,9 +190,9 @@ 	require PublicInbox::View;
 	my $foot = footer($ctx);
 	require Email::MIME;
 	my $mime = Email::MIME->new($x);
-	my $srch = searcher($ctx);
+	searcher($ctx);
 	[ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ],
-	  [ PublicInbox::View->msg_html($mime, undef, $foot, $srch)] ];
+	  [ PublicInbox::View::msg_html($ctx, $mime, undef, $foot)] ];
 }
 
 # /$LISTNAME/t/$MESSAGE_ID.html
diff --git a/t/view.t b/t/view.t
index ca456aab86073a09e779515acd7018e1e4c71df4..fd3c75be2bdbdad19048fa5fff9e59c6cb927415 100644
--- a/t/view.t
+++ b/t/view.t
@@ -41,7 +41,7 @@ 		],
 		body => $body,
 	)->as_string;
 	my $mime = Email::MIME->new($s);
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 
 	# ghetto tests
 	like($html, qr!new($s);
-	my $short = PublicInbox::View->msg_html($mime, $pfx);
+	my $short = PublicInbox::View::msg_html(undef, $mime, $pfx);
 	like($short, qr! $parts,
 	);
 
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 	like($html, qr/hi\n-+ part #2 -+\nbye\n/, "multipart split");
 }
 
@@ -113,7 +113,7 @@ 			],
 		parts => $parts,
 	);
 
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 	like($html, qr!see attached patch\n-+ foo\.patch -+\n--- a/file\n!,
 		"parts split with filename");
 }
@@ -139,7 +139,7 @@ 		parts => $parts,
 	);
 
 	my $orig = $mime->body_raw;
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 	like($orig, qr/hi =3D bye=/, "our test used QP correctly");
 	like($html, qr/\bhi = bye\b/, "HTML output decoded QP");
 }