зеркало из https://github.com/microsoft/git.git
Merge branch 'jn/gitweb-hilite-regions'
* jn/gitweb-hilite-regions: gitweb: Highlight matched part of shortened project description gitweb: Highlight matched part of project description when searching projects gitweb: Highlight matched part of project name when searching projects gitweb: Introduce esc_html_match_hl and esc_html_hl_regions
This commit is contained in:
Коммит
6759f95d63
|
@ -1724,6 +1724,88 @@ sub chop_and_escape_str {
|
|||
}
|
||||
}
|
||||
|
||||
# Highlight selected fragments of string, using given CSS class,
|
||||
# and escape HTML. It is assumed that fragments do not overlap.
|
||||
# Regions are passed as list of pairs (array references).
|
||||
#
|
||||
# Example: esc_html_hl_regions("foobar", "mark", [ 0, 3 ]) returns
|
||||
# '<span class="mark">foo</span>bar'
|
||||
sub esc_html_hl_regions {
|
||||
my ($str, $css_class, @sel) = @_;
|
||||
return esc_html($str) unless @sel;
|
||||
|
||||
my $out = '';
|
||||
my $pos = 0;
|
||||
|
||||
for my $s (@sel) {
|
||||
$out .= esc_html(substr($str, $pos, $s->[0] - $pos))
|
||||
if ($s->[0] - $pos > 0);
|
||||
$out .= $cgi->span({-class => $css_class},
|
||||
esc_html(substr($str, $s->[0], $s->[1] - $s->[0])));
|
||||
|
||||
$pos = $s->[1];
|
||||
}
|
||||
$out .= esc_html(substr($str, $pos))
|
||||
if ($pos < length($str));
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
# return positions of beginning and end of each match
|
||||
sub matchpos_list {
|
||||
my ($str, $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
|
||||
|
||||
|
@ -5368,10 +5450,17 @@ sub git_project_list_rows {
|
|||
print "</td>\n";
|
||||
}
|
||||
print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
||||
-class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
|
||||
-class => "list"},
|
||||
esc_html_match_hl($pr->{'path'}, $search_regexp)) .
|
||||
"</td>\n" .
|
||||
"<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
||||
-class => "list", -title => $pr->{'descr_long'}},
|
||||
esc_html($pr->{'descr'})) . "</td>\n" .
|
||||
-class => "list",
|
||||
-title => $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";
|
||||
print "<td class=\"". age_class($pr->{'age'}) . "\">" .
|
||||
(defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "</td>\n" .
|
||||
|
|
Загрузка…
Ссылка в новой задаче