diff options
author | Jakub Narebski <jnareb@gmail.com> | 2012-02-27 02:55:22 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-02-26 22:02:58 -0800 |
commit | e607b79fb14f2196f7ea46d2115f21c548972e78 (patch) | |
tree | 5091a242695ef871b7cf832e785f3848e90b25ac /gitweb | |
parent | 5fb3cf23170f7dc43568d0234c338d67372c97cc (diff) | |
download | git-e607b79fb14f2196f7ea46d2115f21c548972e78.tar.gz |
gitweb: Highlight matched part of shortened project descriptionjn/gitweb-hilite-regions
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>
Diffstat (limited to 'gitweb')
-rwxr-xr-x | gitweb/gitweb.perl | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 724f06f1f0..01c13183cb 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1742,20 +1742,61 @@ sub esc_html_hl_regions { return $out; } -# highlight match (if any), and escape HTML -sub esc_html_match_hl { +# return positions of beginning and end of each match +sub matchpos_list { my ($str, $regexp) = @_; - return esc_html($str) unless defined $regexp; + return unless (defined $str && defined $regexp); my @matches; while ($str =~ /$regexp/g) { 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_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 @@ -5405,9 +5446,10 @@ sub git_project_list_rows { "</td>\n" . "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"), -class => "list", - $search_regexp ? () : -title => $pr->{'descr_long'}}, + -title => $pr->{'descr_long'}}, $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'})) . "</td>\n" . "<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n"; |