diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Rebuild the page chrome as semantic HTML
The masthead, tab bar, breadcrumb, content region and footer were HTML tables, which cannot reflow and forced the page to scroll sideways on small screens. Class and id names are kept so custom themes keep matching, the tabs gain title hints and the form controls accessible names.
Diffstat (limited to 'source/ui-shared.c')
-rw-r--r--source/ui-shared.c150
1 file changed, 91 insertions, 59 deletions
diff --git a/source/ui-shared.c b/source/ui-shared.c
index eb68ab7..69d2cdf 100644
--- a/source/ui-shared.c
+++ b/source/ui-shared.c
@@ -867,7 +867,7 @@ void cgit_print_docstart(void)
void cgit_print_docend(void)
{
- html("</div> <!-- class=content -->\n");
+ html("</main>\n");
if (ctx.cfg.embedded) {
html("</div> <!-- id=cgit -->\n");
if (ctx.cfg.footer)
@@ -877,10 +877,10 @@ void cgit_print_docend(void)
if (ctx.cfg.footer)
html_include(ctx.cfg.footer);
else {
- htmlf("<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit %s</a> "
+ htmlf("<footer class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit %s</a> "
"(<a href='https://git-scm.com/'>git %s</a>) at ", cgit_version, git_version_string);
html_txt(show_date(time(NULL), 0, cgit_date_mode(DATE_ISO8601)));
- html("</div>\n");
+ html("</footer>\n");
}
html("</div> <!-- id=cgit -->\n");
html("</body>\n</html>\n");
@@ -1015,9 +1015,6 @@ static void print_header(void)
{
char *logo = NULL, *logo_link = NULL;
- html("<table id='header'>\n");
- html("<tr>\n");
-
if (ctx.repo && ctx.repo->logo && *ctx.repo->logo)
logo = ctx.repo->logo;
else
@@ -1026,44 +1023,47 @@ static void print_header(void)
logo_link = ctx.repo->logo_link;
else
logo_link = ctx.cfg.logo_link;
+
+ html("<header id='header'>\n");
if (logo && *logo) {
- html("<td class='logo' rowspan='2'><a href='");
+ html("<a class='logo' href='");
if (logo_link && *logo_link)
html_attr(logo_link);
else
html_attr(cgit_rooturl());
html("'><img src='");
html_attr(logo);
- html("' alt='cgit logo'/></a></td>\n");
+ html("' alt='cgit logo'/></a>\n");
}
- html("<td class='main'>");
+ html("<h1 class='main'>");
if (ctx.repo) {
cgit_index_link("index", NULL, NULL, NULL, NULL, 0, 1);
html(" : ");
cgit_summary_link(ctx.repo->name, NULL, NULL, NULL);
- if (ctx.env.authenticated) {
- html("</td><td class='form'>");
- html("<form method='get'>\n");
- cgit_add_hidden_formfields(0, 1, ctx.qry.page);
- html("<select name='h' onchange='this.form.submit();'>\n");
- refs_for_each_branch_ref(get_main_ref_store(the_repository),
- print_branch_option, ctx.qry.head);
- if (ctx.repo->enable_remote_branches)
- refs_for_each_remote_ref(get_main_ref_store(the_repository),
- print_branch_option, ctx.qry.head);
- html("</select> ");
- html("<input type='submit' value='switch'/>");
- html("</form>");
- }
} else
html_txt(ctx.cfg.root_title);
- html("</td></tr>\n");
+ html("</h1>\n");
+
+ if (ctx.repo && ctx.env.authenticated) {
+ html("<form class='branch-switch' method='get'>\n");
+ cgit_add_hidden_formfields(0, 1, ctx.qry.page);
+ html("<select name='h' aria-label='Branch' onchange='this.form.submit();'>\n");
+ refs_for_each_branch_ref(get_main_ref_store(the_repository),
+ print_branch_option, ctx.qry.head);
+ if (ctx.repo->enable_remote_branches)
+ refs_for_each_remote_ref(get_main_ref_store(the_repository),
+ print_branch_option, ctx.qry.head);
+ html("</select> ");
+ html("<input type='submit' value='switch'/>");
+ html("</form>\n");
+ }
- html("<tr><td class='sub'>");
if (ctx.repo) {
+ html("<p class='sub desc'>");
html_txt(ctx.repo->desc);
- html("</td><td class='sub right'>");
+ html("</p>\n");
+ html("<p class='sub owner'>");
if (ctx.repo->owner_filter) {
cgit_open_filter(ctx.repo->owner_filter);
html_txt(ctx.repo->owner);
@@ -1071,11 +1071,13 @@ static void print_header(void)
} else {
html_txt(ctx.repo->owner);
}
- } else {
- if (ctx.cfg.root_desc)
- html_txt(ctx.cfg.root_desc);
+ html("</p>\n");
+ } else if (ctx.cfg.root_desc) {
+ html("<p class='sub desc'>");
+ html_txt(ctx.cfg.root_desc);
+ html("</p>\n");
}
- html("</td></tr></table>\n");
+ html("</header>\n");
}
void cgit_print_pageheader(void)
@@ -1084,39 +1086,63 @@ void cgit_print_pageheader(void)
if (!ctx.env.authenticated || !ctx.cfg.noheader)
print_header();
- html("<table class='tabs'><tr><td>\n");
+ if (ctx.env.authenticated)
+ html("<nav class='tabs'>\n");
if (ctx.env.authenticated && ctx.repo) {
- if (ctx.repo->readme.nr)
- reporevlink("about", "about", NULL,
+ const char *vp = ctx.qry.vpath;
+ html("<ul>\n");
+ if (ctx.repo->readme.nr) {
+ html("<li>");
+ reporevlink("about", "about", "About this repository",
hc("about"), ctx.qry.head, NULL,
NULL);
- cgit_summary_link("summary", NULL, hc("summary"),
+ html("</li>\n");
+ }
+ html("<li>");
+ cgit_summary_link("summary", "Repository summary", hc("summary"),
ctx.qry.head);
- cgit_refs_link("refs", NULL, hc("refs"), ctx.qry.head,
+ html("</li>\n<li>");
+ cgit_refs_link("refs", "Branches and tags", hc("refs"), ctx.qry.head,
ctx.qry.oid, NULL);
- cgit_log_link("log", NULL, hc("log"), ctx.qry.head,
+ html("</li>\n<li>");
+ cgit_log_link("log",
+ vp && *vp ? fmt("Commit history of %s", vp) : "Commit history",
+ hc("log"), ctx.qry.head,
NULL, ctx.qry.vpath, 0, NULL, NULL,
ctx.qry.showmsg, ctx.qry.follow);
+ html("</li>\n<li>");
if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))
- cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,
+ cgit_blame_link("blame",
+ vp && *vp ? fmt("Line-by-line blame of %s", vp) : "Blame",
+ hc("blame"), ctx.qry.head,
ctx.qry.oid, ctx.qry.vpath);
else
- cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
+ cgit_tree_link("tree",
+ vp && *vp ? fmt("Browse the tree at %s", vp) : "Browse the file tree",
+ hc("tree"), ctx.qry.head,
ctx.qry.oid, ctx.qry.vpath);
- cgit_commit_link("commit", NULL, hc("commit"),
+ html("</li>\n<li>");
+ cgit_commit_link("commit", "The current commit", hc("commit"),
ctx.qry.head, ctx.qry.oid, ctx.qry.vpath);
- cgit_diff_link("diff", NULL, hc("diff"), ctx.qry.head,
+ html("</li>\n<li>");
+ cgit_diff_link("diff",
+ vp && *vp ? fmt("Changes to %s", vp) : "Changes in the current commit",
+ hc("diff"), ctx.qry.head,
ctx.qry.oid, ctx.qry.oid2, ctx.qry.vpath);
- if (ctx.repo->max_stats)
- cgit_stats_link("stats", NULL, hc("stats"),
+ html("</li>\n");
+ if (ctx.repo->max_stats) {
+ html("<li>");
+ cgit_stats_link("stats", "Commit activity", hc("stats"),
ctx.qry.head, ctx.qry.vpath);
+ html("</li>\n");
+ }
if (ctx.repo->homepage) {
- html("<a href='");
+ html("<li><a class='external' href='");
html_attr(ctx.repo->homepage);
- html("'>homepage</a>");
+ html("'>homepage</a></li>\n");
}
- html("</td><td class='form'>");
- html("<form class='right' method='get' action='");
+ html("</ul>\n");
+ html("<form class='search' method='get' action='");
if (ctx.cfg.virtual_root) {
char *fileurl = cgit_fileurl(ctx.qry.repo, "log",
ctx.qry.vpath, NULL);
@@ -1125,37 +1151,43 @@ void cgit_print_pageheader(void)
}
html("'>\n");
cgit_add_hidden_formfields(1, 0, "log");
- html("<select name='qt'>\n");
+ html("<select name='qt' aria-label='Search type'>\n");
html_option("grep", "log msg", ctx.qry.grep);
html_option("author", "author", ctx.qry.grep);
html_option("committer", "committer", ctx.qry.grep);
html_option("range", "range", ctx.qry.grep);
html("</select>\n");
- html("<input class='txt' type='search' size='10' name='q' value='");
+ html("<input class='txt' type='search' name='q' aria-label='Search' value='");
html_attr(ctx.qry.search);
html("'/>\n");
html("<input type='submit' value='search'/>\n");
html("</form>\n");
} else if (ctx.env.authenticated) {
char *currenturl = cgit_currenturl();
- site_link(NULL, "index", NULL, hc("repolist"), NULL, NULL, 0, 1);
- if (ctx.cfg.root_readme)
- site_link("about", "about", NULL, hc("about"),
+ html("<ul>\n<li>");
+ site_link(NULL, "index", "Repository index", hc("repolist"), NULL, NULL, 0, 1);
+ html("</li>\n");
+ if (ctx.cfg.root_readme) {
+ html("<li>");
+ site_link("about", "about", "About this site", hc("about"),
NULL, NULL, 0, 1);
- html("</td><td class='form'>");
- html("<form method='get' action='");
+ html("</li>\n");
+ }
+ html("</ul>\n");
+ html("<form class='search' method='get' action='");
html_attr(currenturl);
html("'>\n");
- html("<input type='search' name='q' size='10' value='");
+ html("<input class='txt' type='search' name='q' aria-label='Search' value='");
html_attr(ctx.qry.search);
html("'/>\n");
html("<input type='submit' value='search'/>\n");
- html("</form>");
+ html("</form>\n");
free(currenturl);
}
- html("</td></tr></table>\n");
+ if (ctx.env.authenticated)
+ html("</nav>\n");
if (ctx.env.authenticated && ctx.repo && ctx.qry.vpath) {
- html("<div class='path'>");
+ html("<nav class='path' aria-label='breadcrumb'>");
html("path: ");
cgit_print_path_crumbs(ctx.qry.vpath);
if (ctx.repo->enable_follow_links && !strcmp(ctx.qry.page, "log")) {
@@ -1166,9 +1198,9 @@ void cgit_print_pageheader(void)
ctx.qry.follow = !ctx.qry.follow;
html(")");
}
- html("</div>");
+ html("</nav>");
}
- html("<div class='content'>");
+ html("<main class='content'>\n");
}
void cgit_print_filemode(unsigned short mode)