'override' => 0,
'default' => [0]},
- # Enable and configure ability to change common timezone for dates
- # in gitweb output via JavaScript. Enabled by default.
- # Project specific override is not supported.
- 'javascript-timezone' => {
- 'override' => 0,
- 'default' => [
- 'local', # default timezone: 'utc', 'local', or '(-|+)HHMM' format,
- # or undef to turn off this feature
- 'gitweb_tz', # name of cookie where to store selected timezone
- 'datetime', # CSS class used to mark up dates for manipulation
- ]},
-
# Syntax highlighting support. This is based on Daniel Svensson's
# and Sham Chukoury's work in gitweb-xmms2.git.
# It requires the 'highlight' program present in $PATH,
"patch" => \&git_patch,
"patches" => \&git_patches,
"remotes" => \&git_remotes,
- "rss" => \&git_rss,
"atom" => \&git_atom,
"search" => \&git_search,
"search_help" => \&git_search_help,
# finally, we have the hash of allowed extra_options for the commands that
# allow them
our %allowed_options = (
- "--no-merges" => [ qw(rss atom log shortlog history) ],
+ "--no-merges" => [ qw(atom log shortlog history) ],
);
# fill %input_params with the CGI parameters. All values except for 'opt'
$out .= esc_html(substr($str, $pos, $begin - $pos), %opts)
if ($begin - $pos > 0);
- $out .= $cgi->span({-class => $css_class}, $escaped);
+ $out .= "<mark class=\"$css_class\">$escaped</mark>";
$pos = $end;
}
my @matches = matchpos_list($str, $regexp);
return esc_html($str) unless @matches;
- return esc_html_hl_regions($str, 'match', @matches);
+ return esc_html_hl_regions($str, undef, @matches);
}
push @filtered, $m;
}
- return esc_html_hl_regions($chopped . $tail, 'match', @filtered);
+ return esc_html_hl_regions($chopped . $tail, undef, @filtered);
}
## ----------------------------------------------------------------------
$title =~ s/^/ /g;
$title =~ s/$/ /g;
if (defined $matched && $matched eq $ctag) {
- $title = qq(<span class="match">$title</span>);
+ $title = qq(<mark>$title</mark>);
}
$cloud->add($title, href(project=>undef, ctag=>$ctag),
$ctags_lc{$ctag}->{count});
foreach my $ctag (keys %ctags_lc) {
my $title = esc_html($ctags_lc{$ctag}->{topname}, -nbsp=>1);
if (defined $matched && $matched eq $ctag) {
- $title = qq(<span class="match">$title</span>);
+ $title = qq(<mark>$title</mark>);
}
$cloud->{$ctag}{count} = $ctags_lc{$ctag}->{count};
$cloud->{$ctag}{ctag} =
$co{'age'} = $age;
$co{'age_string'} = age_string($age);
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($co{'committer_epoch'});
+ $co{'age_string_iso8601'} = sprintf "%4i-%02u-%02i %02u:%02u:%02uZ", 1900 + $year, $mon+1, $mday, $hour, $min, $sec;
if ($age > 60*60*24*7*2) {
$co{'age_string_date'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday;
- $co{'age_string_age'} = $co{'age_string'};
+ $co{'age_string_age'} = "$co{'age_string_iso8601'} ($co{'age_string'})";
} else {
$co{'age_string_date'} = $co{'age_string'};
- $co{'age_string_age'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday;
+ $co{'age_string_age'} = $co{'age_string_iso8601'};
}
return %co;
}
## functions printing HTML: header, footer, error page
sub get_page_title {
- my $title = to_utf8($site_name);
-
+ # Formats:
+ # SITE_NAME
+ # SITE_NAME - projects in FILTER
+ # PROJECT - SITE_NAME
+ # PROJECT ACTION - SITE_NAME
+ # FILENAME - PROJECT ACTION - SITE_NAME
+ my $title;
unless (defined $project) {
+ $title = to_utf8($site_name);
if (defined $project_filter) {
$title .= " - projects in '" . esc_path($project_filter) . "'";
}
return $title;
}
- $title .= " - " . to_utf8($project);
+ $title = to_utf8($project);
- return $title unless (defined $action);
- $title .= "/$action"; # $action is US-ASCII (7bit ASCII)
-
- return $title unless (defined $file_name);
- $title .= " - " . esc_path($file_name);
- if ($action eq "tree" && $file_name !~ m|/$|) {
- $title .= "/";
+ if (defined $action) {
+ $title .= " $action"; # $action is US-ASCII (7bit ASCII)
+ if (defined $file_name) {
+ $title = " - " . $title;
+ if ($action eq "tree" && $file_name !~ m|/$|) {
+ $title = "/" . $title;
+ }
+ $title = esc_path($file_name) . $title;
+ }
}
- return $title;
-}
+ $title .= " - " . to_utf8($site_name);
-sub get_content_type_html {
- # require explicit support from the UA if we are to send the page as
- # 'application/xhtml+xml', otherwise send it as plain old 'text/html'.
- # we have to do this because MSIE sometimes globs '*/*', pretending to
- # support xhtml+xml but choking when it gets what it asked for.
- if (defined $cgi->http('HTTP_ACCEPT') &&
- $cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ &&
- $cgi->Accept('application/xhtml+xml') != 0) {
- return 'application/xhtml+xml';
- } else {
- return 'text/html';
- }
+ return $title;
}
sub print_feed_meta {
$href_params{'-title'} = 'log';
}
- foreach my $format (qw(RSS Atom)) {
+ foreach my $format (qw(Atom)) {
my $type = lc($format);
my %link_attr = (
'-rel' => 'alternate',
} else {
printf('<link rel="alternate" title="%s projects list" '.
'href="%s" type="text/plain; charset=utf-8" />'."\n",
- esc_attr($site_name),
+ esc_attr(to_utf8($site_name)),
esc_attr(href(project=>undef, action=>"project_index")));
printf('<link rel="alternate" title="%s projects feeds" '.
'href="%s" type="text/x-opml" />'."\n",
- esc_attr($site_name),
+ esc_attr(to_utf8($site_name)),
esc_attr(href(project=>undef, action=>"opml")));
}
}
# print out each stylesheet that exist, providing backwards capability
# for those people who defined $stylesheet in a config file
if (defined $stylesheet) {
- print '<link rel="stylesheet" type="text/css" href="'.esc_url($stylesheet).'"/>'."\n";
+ print '<link rel="stylesheet" href="'.esc_url($stylesheet).'"/>'."\n";
} else {
foreach my $stylesheet (@stylesheets) {
next unless $stylesheet;
- print '<link rel="stylesheet" type="text/css" href="'.esc_url($stylesheet).'"/>'."\n";
+ print '<link rel="stylesheet" href="'.esc_url($stylesheet).'"/>'."\n";
}
}
print_feed_meta()
if ($status eq '200 OK');
if (defined $favicon) {
- print qq(<link rel="shortcut icon" href=").esc_url($favicon).qq(" type="image/png" />\n);
+ print qq(<link rel="icon" href=").esc_url($favicon).qq("/>\n);
}
}
if ($use_pathinfo) {
$action .= "/".esc_url($project);
}
- print $cgi->start_form(-method => "get", -action => $action) .
- "<div class=\"search\">\n" .
+ print $cgi->start_form(-method => "get", -action => $action, -role => "search") .
(!$use_pathinfo &&
$cgi->input({-name=>"p", -value=>$project, -type=>"hidden"}) . "\n") .
$cgi->input({-name=>"a", -value=>"search", -type=>"hidden"}) . "\n" .
$cgi->checkbox(-name => 'sr', -value => 1, -label => 're',
-checked => $search_use_regexp) .
"</span>" .
- "</div>" .
$cgi->end_form() . "\n";
}
my %opts = @_;
my $title = get_page_title();
- my $content_type = get_content_type_html();
- print $cgi->header(-type=>$content_type, -charset => 'utf-8',
+ # I wanted to switch to text/html, but it uses nested <a> in a couple of places (e.g. log refs are links inside the commit summary link), which is invalid but works in the XML syntax. Pity.
+ # (Various other invalid HTML is produced that HTML would have fixed but XHTML allows to be broken, like table > tr, lacking tbody.)
+ # TODO: reduce the doctype to <!DOCTYPE html>, but that takes replacing entities like ⋅ with ⋅.
+ print $cgi->header(-type => 'application/xhtml+xml', -charset => 'utf-8',
-status=> $status, -expires => $expires)
unless ($opts{'-no_http_header'});
- my $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : '';
print <<EOF;
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
-<!-- git web interface version $version, (C) 2005-2006, Kay Sievers <kay.sievers\@vrfy.org>, Christian Gierke -->
-<!-- git core binaries version $git_version -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-AU" lang="en-AU">
<head>
-<meta http-equiv="content-type" content="$content_type; charset=utf-8"/>
-<meta name="generator" content="gitweb/$version git/$git_version$mod_perl_version"/>
+<meta charset="utf-8"/>
<meta name="robots" content="index, nofollow"/>
<title>$title</title>
EOF
# the stylesheet, favicon etc urls won't work correctly with path_info
# unless we set the appropriate base URL
if ($ENV{'PATH_INFO'}) {
- print "<base href=\"".esc_url($base_url)."\" />\n";
+ print "<base href=\"".esc_url($base_url)."\"/>\n";
}
print_header_links($status);
print to_utf8($site_html_head_string);
}
- print "</head>\n" .
- "<body>\n";
-
if (defined $site_header && -f $site_header) {
insert_file($site_header);
}
- print "<div class=\"page_header\">\n";
+ print "</head>\n<body>\n<header class=\"page_header\">\n";
if (defined $logo) {
print $cgi->a({-href => esc_url($logo_url),
-title => $logo_label},
-class => "logo"}));
}
print_nav_breadcrumbs(%opts);
- print "</div>\n";
+ print "</header>\n";
+ print "<nav class=\"page_subhead\">\n";
+}
+
+sub git_end_subhead_html {
my $have_search = gitweb_check_feature('search');
if (defined $project && $have_search) {
print_search_form();
}
+ print "</nav>\n";
}
sub git_footer_html {
my $feed_class = 'rss_logo';
- print "<div class=\"page_footer\">\n";
+ print "<footer class=\"page_footer\">\n";
if (defined $project) {
my $descr = git_get_project_description($project);
if (defined $descr) {
}
$href_params{'-title'} ||= 'log';
- foreach my $format (qw(RSS Atom)) {
+ foreach my $format (qw(Atom)) {
$href_params{'action'} = lc($format);
print $cgi->a({-href => href(%href_params),
-title => "$href_params{'-title'} $format feed",
project_filter => $project_filter),
-class => $feed_class}, "TXT") . "\n";
}
- print "</div>\n"; # class="page_footer"
+ print "</footer>\n"; # class="page_footer"
if (defined $t0 && gitweb_check_feature('timed')) {
print "<div id=\"generating_info\">\n";
$number_of_git_cmds.
'</span> git commands '.
" to generate.\n";
- print "</div>\n"; # class="page_footer"
+ print "</div>\n";
}
if (defined $site_footer && -f $site_footer) {
insert_file($site_footer);
}
- print qq!<script type="text/javascript" src="!.esc_url($javascript).qq!"></script>\n!;
if (defined $action &&
$action eq 'blame_incremental') {
- print qq!<script type="text/javascript">\n!.
+ print qq!<script src="!.esc_url($javascript).qq!"></script>\n!;
+ print qq!<script>\n!.
qq!startBlame("!. esc_attr(href(action=>"blame_data", -replay=>1)) .qq!",\n!.
qq! "!. esc_attr(href()) .qq!");\n!.
qq!</script>\n!;
} else {
- my ($jstimezone, $tz_cookie, $datetime_class) =
- gitweb_get_feature('javascript-timezone');
-
- print qq!<script type="text/javascript">\n!.
- qq!window.onload = function () {\n!;
if (gitweb_check_feature('javascript-actions')) {
- print qq! fixLinks();\n!;
- }
- if ($jstimezone && $tz_cookie && $datetime_class) {
- print qq! var tz_cookie = { name: '$tz_cookie', expires: 14, path: '/' };\n!. # in days
- qq! onloadTZSetup('$jstimezone', tz_cookie, '$datetime_class');\n!;
+ print qq!<script src="!.esc_url($javascript).qq!"></script>\n!;
+ print qq!<script>\n!.
+ qq!window.onload = function () {\n!;
+ if (gitweb_check_feature('javascript-actions')) {
+ print qq! fixLinks();\n!;
+ }
+ print qq!};\n!.
+ qq!</script>\n!;
}
- print qq!};\n!.
- qq!</script>\n!;
}
print "</body>\n" .
503 => '503 Service Unavailable',
);
git_header_html($http_responses{$status}, undef, %opts);
+ git_end_subhead_html();
print <<EOF;
<div class="page_body">
<br /><br />
sub git_print_page_nav {
my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_;
- $extra = '' if !defined $extra; # pager or formats
my @navs = qw(summary shortlog log commit commitdiff tree);
if ($suppress) {
print "<div class=\"page_nav\">\n" .
(join " | ",
map { $_ eq $current ?
- $_ : $cgi->a({-href => ($arg{$_}{_href} ? $arg{$_}{_href} : href(%{$arg{$_}}))}, "$_")
+ $cgi->span({-class => "current"}, $_) : $cgi->a({-href => ($arg{$_}{_href} ? $arg{$_}{_href} : href(%{$arg{$_}}))}, "$_")
} @navs);
- print "<br/>\n$extra<br/>\n" .
- "</div>\n";
+ print "<br/>\n$extra" if defined $extra; # pager or formats
+ print "</div>\n";
+ git_end_subhead_html();
}
# returns a submenu for the navigation of the refs views (tags, heads,
sub format_repo_url {
my ($name, $url) = @_;
- return "<tr class=\"metadata_url\"><td>$name</td><td>$url</td></tr>\n";
+ return "<tr class=\"metadata_url\"><th>$name</th><td>$url</td></tr>\n";
}
# Group output by placing it in a DIV element and adding a header.
sub format_timestamp_html {
my $date = shift;
- my $strtime = $date->{'rfc2822'};
- my (undef, undef, $datetime_class) =
- gitweb_get_feature('javascript-timezone');
- if ($datetime_class) {
- $strtime = qq!<span class="$datetime_class">$strtime</span>!;
- }
-
- my $localtime_format = '(%02d:%02d %s)';
- if ($date->{'hour_local'} < 6) {
- $localtime_format = '(<span class="atnight">%02d:%02d</span> %s)';
- }
- $strtime .= ' ' .
- sprintf($localtime_format,
- $date->{'hour_local'}, $date->{'minute_local'}, $date->{'tz_local'});
-
- return $strtime;
+ return qq!<time datetime="$date->{'iso-8601'}" title="$date->{'iso-tz'}">$date->{'rfc2822'}</time>!;
}
# Outputs the author name and date in long form
@people = ('author', 'committer') unless @people;
foreach my $who (@people) {
my %wd = parse_date($co->{"${who}_epoch"}, $co->{"${who}_tz"});
- print "<tr><td>$who</td><td>" .
+ print "<tr><th>$who</th><td>" .
format_search_author($co->{"${who}_name"}, $who,
esc_html($co->{"${who}_name"})) . " " .
format_search_author($co->{"${who}_email"}, $who,
print format_log_line_html($line) . "<br/>\n";
}
-
- if ($opts{'-final_empty_line'}) {
- # end with single empty line
- print "<br/>\n" unless $skip_blank_line;
- }
}
# return link target (what link points to)
my ($difftree, $hash, @parents) = @_;
my ($parent) = $parents[0];
my $have_blame = gitweb_check_feature('blame');
- print "<div class=\"list_head\">\n";
if ($#{$difftree} > 10) {
+ print "<div class=\"list_head\">\n";
print(($#{$difftree} + 1) . " files changed:\n");
+ print "</div>\n";
}
- print "</div>\n";
print "<table class=\"" .
(@parents > 1 ? "combined " : "") .
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
+ print "<section class=\"cards\">\n";
for (my $i = 0; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
next if !%co;
my $commit = $co{'id'};
my $ref = format_ref_marker($refs, $commit);
+ print "<article>\n";
git_print_header_div('commit',
- "<span class=\"age\">$co{'age_string'}</span>" .
+ "<time datetime=\"$co{'age_string_iso8601'}\" title=\"$co{'age_string_iso8601'}\" class=\"age\">$co{'age_string'}</time>" .
esc_html($co{'title'}) . $ref,
$commit);
print "<div class=\"title_text\">\n" .
$cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") .
" | " .
$cgi->a({-href => href(action=>"tree", hash=>$commit, hash_base=>$commit)}, "tree") .
- "<br/>\n" .
"</div>\n";
git_print_authorship(\%co, -tag => 'span');
- print "<br/>\n</div>\n";
+ print "</div>\n";
print "<div class=\"log_body\">\n";
- git_print_log($co{'comment'}, -final_empty_line=> 1);
+ git_print_log($co{'comment'});
print "</div>\n";
+ print "</article>\n";
}
+ print "</section>\n";
if ($extra) {
print "<div class=\"page_nav\">\n";
print "$extra\n";
}
$alternate ^= 1;
# git_summary() used print "<td><i>$co{'age_string'}</i></td>\n" .
- print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+ print "<td title=\"$co{'age_string_age'}\"><time datetime=\"$co{'age_string_iso8601'}\">$co{'age_string_date'}</time></td>\n" .
format_author_html('td', \%co, 10) . "<td>";
print format_subject_html($co{'title'}, $co{'title_short'},
href(action=>"commit", hash=>$commit), $ref);
print "<tr class=\"light\">\n";
}
$alternate ^= 1;
- print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+ print "<td title=\"$co{'age_string_age'}\"><time datetime=\"$co{'age_string_iso8601'}\">$co{'age_string_date'}</time></td>\n" .
# shortlog: format_author_html('td', \%co, 10)
format_author_html('td', \%co, 15, 3) . "<td>";
# originally git_history used chop_str($co{'title'}, 50)
$alternate ^= 1;
%co = parse_commit($set{'commit'});
my $author = chop_and_escape_str($co{'author_name'}, 15, 5);
- print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+ print "<td title=\"$co{'age_string_age'}\"><time datetime=\"$co{'age_string_iso8601'}\">$co{'age_string_date'}</time></td>\n" .
"<td><i>$author</i></td>\n" .
"<td>" .
$cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'},
hash=>$set{'to_id'}, file_name=>$set{'to_file'}),
-class => "list"},
- "<span class=\"match\">" . esc_path($set{'file'}) . "</span>") .
+ "<mark>" . esc_path($set{'file'}) . "</mark>") .
"<br/>\n";
}
}
$ltext = untabify($ltext);
if ($ltext =~ m/^(.*)($search_regexp)(.*)$/i) {
$ltext = esc_html($1, -nbsp=>1);
- $ltext .= '<span class="match">';
+ $ltext .= '<mark>';
$ltext .= esc_html($2, -nbsp=>1);
- $ltext .= '</span>';
+ $ltext .= '</mark>';
$ltext .= esc_html($3, -nbsp=>1);
} else {
$ltext = esc_html($ltext, -nbsp=>1);
}
print "<div class=\"pre\">" .
$cgi->a({-href => $file_href.'#l'.$lno,
- -class => "linenr"}, sprintf('%4i', $lno)) .
- ' ' . $ltext . "</div>\n";
+ -class => "linenr"}, sprintf('%4i ', $lno)) .
+ $ltext . "</div>\n";
}
}
if ($lastfile) {
print "<tr class=\"light\">\n";
}
$alternate ^= 1;
- print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+ print "<td title=\"$co{'age_string_age'}\"><time datetime=\"$co{'age_string_iso8601'}\">$co{'age_string_date'}</time></td>\n" .
format_author_html('td', \%co, 15, 5) .
"<td>" .
$cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
$match = esc_html($match);
$trail = esc_html($trail);
- print "$lead<span class=\"match\">$match</span>$trail<br />";
+ print "$lead<mark>$match</mark>$trail<br />";
}
}
print "</td>\n" .
}
git_header_html();
+ git_end_subhead_html();
if (defined $home_text && -f $home_text) {
print "<div class=\"index_include\">\n";
insert_file($home_text);
git_header_html();
git_print_page_nav('summary','', $head);
- print "<div class=\"title\"> </div>\n";
print "<table class=\"projects_list\">\n" .
- "<tr id=\"metadata_desc\"><td>description</td><td>" . esc_html($descr) . "</td></tr>\n";
+ "<tr id=\"metadata_desc\"><th>description</th><td>" . esc_html($descr) . "</td></tr>\n";
if ($owner and not $omit_owner) {
- print "<tr id=\"metadata_owner\"><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
+ print "<tr id=\"metadata_owner\"><th>owner</th><td>" . esc_html($owner) . "</td></tr>\n";
}
if (defined $cd{'rfc2822'}) {
- print "<tr id=\"metadata_lchange\"><td>last change</td>" .
+ print "<tr id=\"metadata_lchange\"><th>last change</th>" .
"<td>".format_timestamp_html(\%cd)."</td></tr>\n";
}
# without ability to add tags, don't show if there are none
my $cloud = git_populate_project_tagcloud($ctags);
print "<tr id=\"metadata_ctags\">" .
- "<td>content tags</td>" .
+ "<th>content tags</th>" .
"<td>".git_show_project_tagcloud($cloud, 48)."</td>" .
"</tr>\n";
}
print "</table>\n";
+ print("<section class=\"cards\">\n");
+
# If XSS prevention is on, we don't include README.html.
# TODO: Allow a readme in some safe format.
if (!$prevent_xss && -s "$projectroot/$project/README.html") {
+ print("<article>\n");
print "<div class=\"title\">readme</div>\n" .
"<div class=\"readme\">\n";
insert_file("$projectroot/$project/README.html");
print "\n</div>\n"; # class="readme"
+ print("</article>\n");
}
# we need to request one more than 16 (0..15) to check if
# those 16 are all
my @commitlist = $head ? parse_commits($head, 17) : ();
if (@commitlist) {
+ print("<article>\n");
git_print_header_div('shortlog');
git_shortlog_body(\@commitlist, 0, 15, $refs,
$#commitlist <= 15 ? undef :
$cgi->a({-href => href(action=>"shortlog")}, "..."));
+ print("</article>\n");
}
if (@taglist) {
+ print("<article>\n");
git_print_header_div('tags');
git_tags_body(\@taglist, 0, 15,
$#taglist <= 15 ? undef :
$cgi->a({-href => href(action=>"tags")}, "..."));
+ print("</article>\n");
}
if (@headlist) {
+ print("<article>\n");
git_print_header_div('heads');
git_heads_body(\@headlist, $head, 0, 15,
$#headlist <= 15 ? undef :
$cgi->a({-href => href(action=>"heads")}, "..."));
+ print("</article>\n");
}
if (%remotedata) {
+ print("<article>\n");
git_print_header_div('remotes');
git_remotes_body(\%remotedata, 15, $head);
+ print("</article>\n");
}
if (@forklist) {
+ print("<article>\n");
git_print_header_div('forks');
git_project_list_body(\@forklist, 'age', 0, 15,
$#forklist <= 15 ? undef :
$cgi->a({-href => href(action=>"forks")}, "..."),
'no_header');
+ print("</article>\n");
}
+ print("</section>\n");
git_footer_html();
}
print "<div class=\"title_text\">\n" .
"<table class=\"object_header\">\n" .
"<tr>\n" .
- "<td>object</td>\n" .
+ "<th>object</th>\n" .
"<td>" . $cgi->a({-class => "list", -href => href(action=>$tag{'type'}, hash=>$tag{'object'})},
$tag{'object'}) . "</td>\n" .
"<td class=\"link\">" . $cgi->a({-href => href(action=>$tag{'type'}, hash=>$tag{'object'})},
git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
} else {
- print "<div class=\"page_nav\">\n" .
- "<br/><br/></div>\n" .
- "<div class=\"title\">".esc_html($hash)."</div>\n";
+ git_end_subhead_html();
+ print "<div class=\"title\">".esc_html($hash)."</div>\n";
}
git_print_page_path($file_name, "blob", $hash_base);
print "<div class=\"page_body\">\n";
chomp $line;
$nr++;
$line = untabify($line);
- printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i</a> %s</div>\n!,
+ printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i </a>%s</div>\n!,
$nr, esc_attr(href(-replay => 1)), $nr, $nr,
$highlight ? sanitize($line) : esc_html($line, -nbsp=>1);
}
git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);
} else {
undef $hash_base;
- print "<div class=\"page_nav\">\n";
- print "<br/><br/></div>\n";
+ git_end_subhead_html();
print "<div class=\"title\">".esc_html($hash)."</div>\n";
}
if (defined $file_name) {
print "<div class=\"title_text\">\n" .
"<table class=\"object_header\">\n";
git_print_authorship_rows(\%co);
- print "<tr><td>commit</td><td class=\"sha1\">$co{'id'}</td></tr>\n";
+ print "<tr><th>commit</th><td class=\"sha1\">$co{'id'}</td></tr>\n";
print "<tr>" .
- "<td>tree</td>" .
+ "<th>tree</th>" .
"<td class=\"sha1\">" .
$cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash),
class => "list"}, $co{'tree'}) .
foreach my $par (@$parents) {
print "<tr>" .
- "<td>parent</td>" .
+ "<th>parent</th>" .
"<td class=\"sha1\">" .
$cgi->a({-href => href(action=>"commit", hash=>$par),
class => "list"}, $par) .
git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
} else {
- print "<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n";
+ print "<div class=\"page_nav\"><br/>$formats_nav</div>\n";
+ git_end_subhead_html();
print "<div class=\"title\">".esc_html("$hash vs $hash_parent")."</div>\n";
}
if (defined $file_name) {
print "<div class=\"page_body\">\n";
if (@{$co{'comment'}} > 1) {
print "<div class=\"log\">\n";
- git_print_log($co{'comment'}, -final_empty_line=> 1, -remove_title => 1);
+ git_print_log($co{'comment'}, -remove_title => 1);
print "</div>\n"; # class="log"
}
}
## ......................................................................
-## feeds (RSS, Atom; OPML)
+## feeds (Atom; OPML)
sub git_feed {
my $format = shift || 'atom';
my $have_blame = gitweb_check_feature('blame');
# Atom: http://www.atomenabled.org/developers/syndication/
- # RSS: http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ
- if ($format ne 'rss' && $format ne 'atom') {
+ if ($format ne 'atom') {
die_error(400, "Unknown web feed format");
}
return if ($cgi->request_method() eq 'HEAD');
# header variables
- my $title = "$site_name - $project/$action";
+ my $title = to_utf8($site_name) . " - $project/$action";
my $feed_type = 'log';
if (defined $hash) {
$title .= " - '$hash'";
if (defined $descr) {
$descr = esc_html($descr);
} else {
- $descr = "$project " .
- ($format eq 'rss' ? 'RSS' : 'Atom') .
- " feed";
+ $descr = "$project Atom feed";
}
my $owner = git_get_project_owner($project);
$owner = esc_html($owner);
}
$alt_url = esc_attr($alt_url);
print qq!<?xml version="1.0" encoding="utf-8"?>\n!;
- if ($format eq 'rss') {
- print <<XML;
-<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
-<channel>
-XML
- print "<title>$title</title>\n" .
- "<link>$alt_url</link>\n" .
- "<description>$descr</description>\n" .
- "<language>en</language>\n" .
- # project owner is responsible for 'editorial' content
- "<managingEditor>$owner</managingEditor>\n";
- if (defined $logo || defined $favicon) {
- # prefer the logo to the favicon, since RSS
- # doesn't allow both
- my $img = esc_url($logo || $favicon);
- print "<image>\n" .
- "<url>$img</url>\n" .
- "<title>$title</title>\n" .
- "<link>$alt_url</link>\n" .
- "</image>\n";
- }
- if (%latest_date) {
- print "<pubDate>$latest_date{'rfc2822'}</pubDate>\n";
- print "<lastBuildDate>$latest_date{'rfc2822'}</lastBuildDate>\n";
- }
- print "<generator>gitweb v.$version/$git_version</generator>\n";
- } elsif ($format eq 'atom') {
- print <<XML;
+ print <<XML;
<feed xmlns="http://www.w3.org/2005/Atom">
XML
- print "<title>$title</title>\n" .
- "<subtitle>$descr</subtitle>\n" .
- '<link rel="alternate" type="text/html" href="' .
- $alt_url . '" />' . "\n" .
- '<link rel="self" type="' . $content_type . '" href="' .
- $cgi->self_url() . '" />' . "\n" .
- "<id>" . esc_url(href(-full=>1)) . "</id>\n" .
- # use project owner for feed author
- "<author><name>$owner</name></author>\n";
- if (defined $favicon) {
- print "<icon>" . esc_url($favicon) . "</icon>\n";
- }
- if (defined $logo) {
- # not twice as wide as tall: 72 x 27 pixels
- print "<logo>" . esc_url($logo) . "</logo>\n";
- }
- if (! %latest_date) {
- # dummy date to keep the feed valid until commits trickle in:
- print "<updated>1970-01-01T00:00:00Z</updated>\n";
- } else {
- print "<updated>$latest_date{'iso-8601'}</updated>\n";
- }
- print "<generator version='$version/$git_version'>gitweb</generator>\n";
+ print "<title>$title</title>\n" .
+ "<subtitle>$descr</subtitle>\n" .
+ '<link rel="alternate" type="text/html" href="' .
+ $alt_url . '" />' . "\n" .
+ '<link rel="self" type="' . $content_type . '" href="' .
+ $cgi->self_url() . '" />' . "\n" .
+ "<id>" . esc_url(href(-full=>1)) . "</id>\n" .
+ # use project owner for feed author
+ "<author><name>$owner</name></author>\n";
+ if (defined $favicon) {
+ print "<icon>" . esc_url($favicon) . "</icon>\n";
+ }
+ if (defined $logo) {
+ # not twice as wide as tall: 72 x 27 pixels
+ print "<logo>" . esc_url($logo) . "</logo>\n";
}
+ if (! %latest_date) {
+ # dummy date to keep the feed valid until commits trickle in:
+ print "<updated>1970-01-01T00:00:00Z</updated>\n";
+ } else {
+ print "<updated>$latest_date{'iso-8601'}</updated>\n";
+ }
+ print "<generator version='$version/$git_version'>gitweb</generator>\n";
# contents
for (my $i = 0; $i <= $#commitlist; $i++) {
# print element (entry, item)
my $co_url = href(-full=>1, action=>"commitdiff", hash=>$commit);
- if ($format eq 'rss') {
- print "<item>\n" .
- "<title>" . esc_html($co{'title'}) . "</title>\n" .
- "<author>" . esc_html($co{'author'}) . "</author>\n" .
- "<pubDate>$cd{'rfc2822'}</pubDate>\n" .
- "<guid isPermaLink=\"true\">$co_url</guid>\n" .
- "<link>" . esc_html($co_url) . "</link>\n" .
- "<description>" . esc_html($co{'title'}) . "</description>\n" .
- "<content:encoded>" .
- "<![CDATA[\n";
- } elsif ($format eq 'atom') {
- print "<entry>\n" .
- "<title type=\"html\">" . esc_html($co{'title'}) . "</title>\n" .
- "<updated>$cd{'iso-8601'}</updated>\n" .
- "<author>\n" .
- " <name>" . esc_html($co{'author_name'}) . "</name>\n";
- if ($co{'author_email'}) {
- print " <email>" . esc_html($co{'author_email'}) . "</email>\n";
- }
- print "</author>\n" .
- # use committer for contributor
- "<contributor>\n" .
- " <name>" . esc_html($co{'committer_name'}) . "</name>\n";
- if ($co{'committer_email'}) {
- print " <email>" . esc_html($co{'committer_email'}) . "</email>\n";
- }
- print "</contributor>\n" .
- "<published>$cd{'iso-8601'}</published>\n" .
- "<link rel=\"alternate\" type=\"text/html\" href=\"" . esc_attr($co_url) . "\" />\n" .
- "<id>" . esc_html($co_url) . "</id>\n" .
- "<content type=\"xhtml\" xml:base=\"" . esc_url($my_url) . "\">\n" .
- "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n";
- }
+ print "<entry>\n" .
+ "<title type=\"html\">" . esc_html($co{'title'}) . "</title>\n" .
+ "<updated>$cd{'iso-8601'}</updated>\n" .
+ "<author>\n" .
+ " <name>" . esc_html($co{'author_name'}) . "</name>\n";
+ if ($co{'author_email'}) {
+ print " <email>" . esc_html($co{'author_email'}) . "</email>\n";
+ }
+ print "</author>\n" .
+ # use committer for contributor
+ "<contributor>\n" .
+ " <name>" . esc_html($co{'committer_name'}) . "</name>\n";
+ if ($co{'committer_email'}) {
+ print " <email>" . esc_html($co{'committer_email'}) . "</email>\n";
+ }
+ print "</contributor>\n" .
+ "<published>$cd{'iso-8601'}</published>\n" .
+ "<link rel=\"alternate\" type=\"text/html\" href=\"" . esc_attr($co_url) . "\" />\n" .
+ "<id>" . esc_html($co_url) . "</id>\n" .
+ "<content type=\"xhtml\" xml:base=\"" . esc_url($my_url) . "\">\n" .
+ "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n";
my $comment = $co{'comment'};
print "<pre>\n";
foreach my $line (@$comment) {
print "] ".
"$file</li>\n";
}
- if ($format eq 'rss') {
- print "</ul>]]>\n" .
- "</content:encoded>\n" .
- "</item>\n";
- } elsif ($format eq 'atom') {
- print "</ul>\n</div>\n" .
- "</content>\n" .
- "</entry>\n";
- }
+ print "</ul>\n</div>\n" .
+ "</content>\n" .
+ "</entry>\n";
}
# end of feed
- if ($format eq 'rss') {
- print "</channel>\n</rss>\n";
- } elsif ($format eq 'atom') {
- print "</feed>\n";
- }
-}
-
-sub git_rss {
- git_feed('rss');
+ print "</feed>\n";
}
sub git_atom {
-charset => 'utf-8',
-content_disposition => 'inline; filename="opml.xml"');
- my $title = esc_html($site_name);
+ my $title = esc_html(to_utf8($site_name));
my $filter = " within subdirectory ";
if (defined $project_filter) {
$filter .= esc_html($project_filter);
<title>$title OPML Export$filter</title>
</head>
<body>
-<outline text="git RSS feeds">
+<outline text="git Atom feeds">
XML
foreach my $pr (@list) {
}
my $path = esc_html(chop_str($proj{'path'}, 25, 5));
- my $rss = esc_attr(href('project' => $proj{'path'}, 'action' => 'rss', -full => 1));
+ my $atom = esc_attr(href('project' => $proj{'path'}, 'action' => 'atom', -full => 1));
my $html = esc_attr(href('project' => $proj{'path'}, 'action' => 'summary', -full => 1));
- print "<outline type=\"rss\" text=\"$path\" title=\"$path\" xmlUrl=\"$rss\" htmlUrl=\"$html\"/>\n";
+ print "<outline type=\"rss\" text=\"$path\" title=\"$path\" xmlUrl=\"$atom\" htmlUrl=\"$html\"/>\n";
}
print <<XML;
</outline>