Skip to content

Commit e607b79

Browse files
jnarebgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5fb3cf2 commit e607b79

File tree

1 file changed

+47
-5
lines changed

1 file changed

+47
-5
lines changed

gitweb/gitweb.perl

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,20 +1742,61 @@ sub esc_html_hl_regions {
17421742
return $out;
17431743
}
17441744

1745-
# highlight match (if any), and escape HTML
1746-
sub esc_html_match_hl {
1745+
# return positions of beginning and end of each match
1746+
sub matchpos_list {
17471747
my ($str, $regexp) = @_;
1748-
return esc_html($str) unless defined $regexp;
1748+
return unless (defined $str && defined $regexp);
17491749

17501750
my @matches;
17511751
while ($str =~ /$regexp/g) {
17521752
push @matches, [$-[0], $+[0]];
17531753
}
1754+
return @matches;
1755+
}
1756+
1757+
# highlight match (if any), and escape HTML
1758+
sub esc_html_match_hl {
1759+
my ($str, $regexp) = @_;
1760+
return esc_html($str) unless defined $regexp;
1761+
1762+
my @matches = matchpos_list($str, $regexp);
17541763
return esc_html($str) unless @matches;
17551764

17561765
return esc_html_hl_regions($str, 'match', @matches);
17571766
}
17581767

1768+
1769+
# highlight match (if any) of shortened string, and escape HTML
1770+
sub esc_html_match_hl_chopped {
1771+
my ($str, $chopped, $regexp) = @_;
1772+
return esc_html_match_hl($str, $regexp) unless defined $chopped;
1773+
1774+
my @matches = matchpos_list($str, $regexp);
1775+
return esc_html($chopped) unless @matches;
1776+
1777+
# filter matches so that we mark chopped string
1778+
my $tail = "... "; # see chop_str
1779+
unless ($chopped =~ s/\Q$tail\E$//) {
1780+
$tail = '';
1781+
}
1782+
my $chop_len = length($chopped);
1783+
my $tail_len = length($tail);
1784+
my @filtered;
1785+
1786+
for my $m (@matches) {
1787+
if ($m->[0] > $chop_len) {
1788+
push @filtered, [ $chop_len, $chop_len + $tail_len ] if ($tail_len > 0);
1789+
last;
1790+
} elsif ($m->[1] > $chop_len) {
1791+
push @filtered, [ $m->[0], $chop_len + $tail_len ];
1792+
last;
1793+
}
1794+
push @filtered, $m;
1795+
}
1796+
1797+
return esc_html_hl_regions($chopped . $tail, 'match', @filtered);
1798+
}
1799+
17591800
## ----------------------------------------------------------------------
17601801
## functions returning short strings
17611802

@@ -5405,9 +5446,10 @@ sub git_project_list_rows {
54055446
"</td>\n" .
54065447
"<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
54075448
-class => "list",
5408-
$search_regexp ? () : -title => $pr->{'descr_long'}},
5449+
-title => $pr->{'descr_long'}},
54095450
$search_regexp
5410-
? esc_html_match_hl($pr->{'descr_long'}, $search_regexp)
5451+
? esc_html_match_hl_chopped($pr->{'descr_long'},
5452+
$pr->{'descr'}, $search_regexp)
54115453
: esc_html($pr->{'descr'})) .
54125454
"</td>\n" .
54135455
"<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";

0 commit comments

Comments
 (0)