gitweb: Highlight matched part of shortened project description
Previous commit make gitweb use esc_html_match_hl() to mark match in the _whole_ description of a project when searching projects. This commit makes gitweb highlight match in _shortened_ description, based on match in whole description, using esc_html_match_hl_chopped() subroutine. If match is in removed (chopped) part, even partially, then trailing "... " is highlighted. Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
		
				
					committed by
					
						
						Junio C Hamano
					
				
			
			
				
	
			
			
			
						parent
						
							5fb3cf2317
						
					
				
				
					commit
					e607b79fb1
				
			@ -1742,20 +1742,61 @@ sub esc_html_hl_regions {
 | 
				
			|||||||
	return $out;
 | 
						return $out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# highlight match (if any), and escape HTML
 | 
					# return positions of beginning and end of each match
 | 
				
			||||||
sub esc_html_match_hl {
 | 
					sub matchpos_list {
 | 
				
			||||||
	my ($str, $regexp) = @_;
 | 
						my ($str, $regexp) = @_;
 | 
				
			||||||
	return esc_html($str) unless defined $regexp;
 | 
						return unless (defined $str && defined $regexp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	my @matches;
 | 
						my @matches;
 | 
				
			||||||
	while ($str =~ /$regexp/g) {
 | 
						while ($str =~ /$regexp/g) {
 | 
				
			||||||
		push @matches, [$-[0], $+[0]];
 | 
							push @matches, [$-[0], $+[0]];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return @matches;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# highlight match (if any), and escape HTML
 | 
				
			||||||
 | 
					sub esc_html_match_hl {
 | 
				
			||||||
 | 
						my ($str, $regexp) = @_;
 | 
				
			||||||
 | 
						return esc_html($str) unless defined $regexp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						my @matches = matchpos_list($str, $regexp);
 | 
				
			||||||
	return esc_html($str) unless @matches;
 | 
						return esc_html($str) unless @matches;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return esc_html_hl_regions($str, 'match', @matches);
 | 
						return esc_html_hl_regions($str, 'match', @matches);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# highlight match (if any) of shortened string, and escape HTML
 | 
				
			||||||
 | 
					sub esc_html_match_hl_chopped {
 | 
				
			||||||
 | 
						my ($str, $chopped, $regexp) = @_;
 | 
				
			||||||
 | 
						return esc_html_match_hl($str, $regexp) unless defined $chopped;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						my @matches = matchpos_list($str, $regexp);
 | 
				
			||||||
 | 
						return esc_html($chopped) unless @matches;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# filter matches so that we mark chopped string
 | 
				
			||||||
 | 
						my $tail = "... "; # see chop_str
 | 
				
			||||||
 | 
						unless ($chopped =~ s/\Q$tail\E$//) {
 | 
				
			||||||
 | 
							$tail = '';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						my $chop_len = length($chopped);
 | 
				
			||||||
 | 
						my $tail_len = length($tail);
 | 
				
			||||||
 | 
						my @filtered;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for my $m (@matches) {
 | 
				
			||||||
 | 
							if ($m->[0] > $chop_len) {
 | 
				
			||||||
 | 
								push @filtered, [ $chop_len, $chop_len + $tail_len ] if ($tail_len > 0);
 | 
				
			||||||
 | 
								last;
 | 
				
			||||||
 | 
							} elsif ($m->[1] > $chop_len) {
 | 
				
			||||||
 | 
								push @filtered, [ $m->[0], $chop_len + $tail_len ];
 | 
				
			||||||
 | 
								last;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							push @filtered, $m;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return esc_html_hl_regions($chopped . $tail, 'match', @filtered);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## ----------------------------------------------------------------------
 | 
					## ----------------------------------------------------------------------
 | 
				
			||||||
## functions returning short strings
 | 
					## functions returning short strings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -5405,9 +5446,10 @@ sub git_project_list_rows {
 | 
				
			|||||||
		      "</td>\n" .
 | 
							      "</td>\n" .
 | 
				
			||||||
		      "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
 | 
							      "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
 | 
				
			||||||
		                        -class => "list",
 | 
							                        -class => "list",
 | 
				
			||||||
		                        $search_regexp ? () : -title => $pr->{'descr_long'}},
 | 
							                        -title => $pr->{'descr_long'}},
 | 
				
			||||||
		                        $search_regexp
 | 
							                        $search_regexp
 | 
				
			||||||
		                        ? esc_html_match_hl($pr->{'descr_long'}, $search_regexp)
 | 
							                        ? esc_html_match_hl_chopped($pr->{'descr_long'},
 | 
				
			||||||
 | 
							                                                    $pr->{'descr'}, $search_regexp)
 | 
				
			||||||
		                        : esc_html($pr->{'descr'})) .
 | 
							                        : esc_html($pr->{'descr'})) .
 | 
				
			||||||
		      "</td>\n" .
 | 
							      "</td>\n" .
 | 
				
			||||||
		      "<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
 | 
							      "<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user