summaryrefslogtreecommitdiffabout
authorJohan Herland <johan@herland.net>2010-06-09 23:09:29 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2010-06-19 08:40:22 (UTC)
commit24fd7e54c82294efa68ecae5dd9cb8a8986c04bf (patch) (unidiff)
tree5a4824456d046f40717fc50686c1e03b5c6efdf4
parentc93ef96aaf77437abeb552bd9e30973f90365f3a (diff)
downloadcgit-24fd7e54c82294efa68ecae5dd9cb8a8986c04bf.zip
cgit-24fd7e54c82294efa68ecae5dd9cb8a8986c04bf.tar.gz
cgit-24fd7e54c82294efa68ecae5dd9cb8a8986c04bf.tar.bz2
ui-shared: Teach "breadcrumb" navigation to path limit display beneath tab bar
When a path limit is in effect, and displayed directly beneath the tab bar, it should offer breadcrumb navigation (like what the 'tree' page does), to allow changing the path limit easily. Implementing this requires a robust way to link back to the current page with a changed ctx->qry.path, but without losing track of the other query arguments. This is solved by adding the new cgit_self_link() function, which is then invoked repeatedly by the new cgit_print_path_crumbs() function while manipulating ctx->qry.path. Signed-off-by: Johan Herland <johan@herland.net> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--ui-shared.c81
-rw-r--r--ui-shared.h2
2 files changed, 82 insertions, 1 deletions
diff --git a/ui-shared.c b/ui-shared.c
index bc14e70..4fa506f 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -390,24 +390,82 @@ void cgit_diff_link(const char *name, const char *title, const char *class,
390void cgit_patch_link(const char *name, const char *title, const char *class, 390void cgit_patch_link(const char *name, const char *title, const char *class,
391 const char *head, const char *rev) 391 const char *head, const char *rev)
392{ 392{
393 reporevlink("patch", name, title, class, head, rev, NULL); 393 reporevlink("patch", name, title, class, head, rev, NULL);
394} 394}
395 395
396void cgit_stats_link(const char *name, const char *title, const char *class, 396void cgit_stats_link(const char *name, const char *title, const char *class,
397 const char *head, const char *path) 397 const char *head, const char *path)
398{ 398{
399 reporevlink("stats", name, title, class, head, NULL, path); 399 reporevlink("stats", name, title, class, head, NULL, path);
400} 400}
401 401
402void cgit_self_link(char *name, const char *title, const char *class,
403 struct cgit_context *ctx)
404{
405 if (!strcmp(ctx->qry.page, "repolist"))
406 return cgit_index_link(name, title, class, ctx->qry.search,
407 ctx->qry.ofs);
408 else if (!strcmp(ctx->qry.page, "summary"))
409 return cgit_summary_link(name, title, class, ctx->qry.head);
410 else if (!strcmp(ctx->qry.page, "tag"))
411 return cgit_tag_link(name, title, class, ctx->qry.head,
412 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL);
413 else if (!strcmp(ctx->qry.page, "tree"))
414 return cgit_tree_link(name, title, class, ctx->qry.head,
415 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
416 ctx->qry.path);
417 else if (!strcmp(ctx->qry.page, "plain"))
418 return cgit_plain_link(name, title, class, ctx->qry.head,
419 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
420 ctx->qry.path);
421 else if (!strcmp(ctx->qry.page, "log"))
422 return cgit_log_link(name, title, class, ctx->qry.head,
423 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
424 ctx->qry.path, ctx->qry.ofs,
425 ctx->qry.grep, ctx->qry.search,
426 ctx->qry.showmsg);
427 else if (!strcmp(ctx->qry.page, "commit"))
428 return cgit_commit_link(name, title, class, ctx->qry.head,
429 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
430 ctx->qry.path, 0);
431 else if (!strcmp(ctx->qry.page, "patch"))
432 return cgit_patch_link(name, title, class, ctx->qry.head,
433 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
434 ctx->qry.path);
435 else if (!strcmp(ctx->qry.page, "refs"))
436 return cgit_refs_link(name, title, class, ctx->qry.head,
437 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
438 ctx->qry.path);
439 else if (!strcmp(ctx->qry.page, "snapshot"))
440 return cgit_snapshot_link(name, title, class, ctx->qry.head,
441 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
442 ctx->qry.path);
443 else if (!strcmp(ctx->qry.page, "diff"))
444 return cgit_diff_link(name, title, class, ctx->qry.head,
445 ctx->qry.sha1, ctx->qry.sha2,
446 ctx->qry.path, 0);
447 else if (!strcmp(ctx->qry.page, "stats"))
448 return cgit_stats_link(name, title, class, ctx->qry.head,
449 ctx->qry.path);
450
451 /* Don't known how to make link for this page */
452 repolink(title, class, ctx->qry.page, ctx->qry.head, ctx->qry.path);
453 html("><!-- cgit_self_link() doesn't know how to make link for page '");
454 html_txt(ctx->qry.page);
455 html("' -->");
456 html_txt(name);
457 html("</a>");
458}
459
402void cgit_object_link(struct object *obj) 460void cgit_object_link(struct object *obj)
403{ 461{
404 char *page, *shortrev, *fullrev, *name; 462 char *page, *shortrev, *fullrev, *name;
405 463
406 fullrev = sha1_to_hex(obj->sha1); 464 fullrev = sha1_to_hex(obj->sha1);
407 shortrev = xstrdup(fullrev); 465 shortrev = xstrdup(fullrev);
408 shortrev[10] = '\0'; 466 shortrev[10] = '\0';
409 if (obj->type == OBJ_COMMIT) { 467 if (obj->type == OBJ_COMMIT) {
410 cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL, 468 cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,
411 ctx.qry.head, fullrev, 0); 469 ctx.qry.head, fullrev, 0);
412 return; 470 return;
413 } else if (obj->type == OBJ_TREE) 471 } else if (obj->type == OBJ_TREE)
@@ -641,24 +699,45 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search,
641 if (ctx.qry.grep) 699 if (ctx.qry.grep)
642 html_hidden("qt", ctx.qry.grep); 700 html_hidden("qt", ctx.qry.grep);
643 if (ctx.qry.search) 701 if (ctx.qry.search)
644 html_hidden("q", ctx.qry.search); 702 html_hidden("q", ctx.qry.search);
645 } 703 }
646} 704}
647 705
648static const char *hc(struct cgit_context *ctx, const char *page) 706static const char *hc(struct cgit_context *ctx, const char *page)
649{ 707{
650 return strcmp(ctx->qry.page, page) ? NULL : "active"; 708 return strcmp(ctx->qry.page, page) ? NULL : "active";
651} 709}
652 710
711static void cgit_print_path_crumbs(struct cgit_context *ctx, char *path)
712{
713 char *old_path = ctx->qry.path;
714 char *p = path, *q, *end = path + strlen(path);
715
716 ctx->qry.path = NULL;
717 cgit_self_link("root", NULL, NULL, ctx);
718 ctx->qry.path = p = path;
719 while (p < end) {
720 if (!(q = strchr(p, '/')))
721 q = end;
722 *q = '\0';
723 html_txt("/");
724 cgit_self_link(p, NULL, NULL, ctx);
725 if (q < end)
726 *q = '/';
727 p = q + 1;
728 }
729 ctx->qry.path = old_path;
730}
731
653static void print_header(struct cgit_context *ctx) 732static void print_header(struct cgit_context *ctx)
654{ 733{
655 html("<table id='header'>\n"); 734 html("<table id='header'>\n");
656 html("<tr>\n"); 735 html("<tr>\n");
657 736
658 if (ctx->cfg.logo && ctx->cfg.logo[0] != 0) { 737 if (ctx->cfg.logo && ctx->cfg.logo[0] != 0) {
659 html("<td class='logo' rowspan='2'><a href='"); 738 html("<td class='logo' rowspan='2'><a href='");
660 if (ctx->cfg.logo_link) 739 if (ctx->cfg.logo_link)
661 html_attr(ctx->cfg.logo_link); 740 html_attr(ctx->cfg.logo_link);
662 else 741 else
663 html_attr(cgit_rooturl()); 742 html_attr(cgit_rooturl());
664 html("'><img src='"); 743 html("'><img src='");
@@ -751,25 +830,25 @@ void cgit_print_pageheader(struct cgit_context *ctx)
751 html_attr(cgit_rooturl()); 830 html_attr(cgit_rooturl());
752 html("'>\n"); 831 html("'>\n");
753 html("<input type='text' name='q' size='10' value='"); 832 html("<input type='text' name='q' size='10' value='");
754 html_attr(ctx->qry.search); 833 html_attr(ctx->qry.search);
755 html("'/>\n"); 834 html("'/>\n");
756 html("<input type='submit' value='search'/>\n"); 835 html("<input type='submit' value='search'/>\n");
757 html("</form>"); 836 html("</form>");
758 } 837 }
759 html("</td></tr></table>\n"); 838 html("</td></tr></table>\n");
760 if (ctx->qry.vpath) { 839 if (ctx->qry.vpath) {
761 html("<div class='path'>"); 840 html("<div class='path'>");
762 html("path: "); 841 html("path: ");
763 html_txt(ctx->qry.vpath); 842 cgit_print_path_crumbs(ctx, ctx->qry.vpath);
764 html("</div>"); 843 html("</div>");
765 } 844 }
766 html("<div class='content'>"); 845 html("<div class='content'>");
767} 846}
768 847
769void cgit_print_filemode(unsigned short mode) 848void cgit_print_filemode(unsigned short mode)
770{ 849{
771 if (S_ISDIR(mode)) 850 if (S_ISDIR(mode))
772 html("d"); 851 html("d");
773 else if (S_ISLNK(mode)) 852 else if (S_ISLNK(mode))
774 html("l"); 853 html("l");
775 else if (S_ISGITLINK(mode)) 854 else if (S_ISGITLINK(mode))
diff --git a/ui-shared.h b/ui-shared.h
index 308c982..3df5464 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -37,24 +37,26 @@ extern void cgit_refs_link(const char *name, const char *title,
37 const char *class, const char *head, 37 const char *class, const char *head,
38 const char *rev, const char *path); 38 const char *rev, const char *path);
39extern void cgit_snapshot_link(const char *name, const char *title, 39extern void cgit_snapshot_link(const char *name, const char *title,
40 const char *class, const char *head, 40 const char *class, const char *head,
41 const char *rev, const char *archivename); 41 const char *rev, const char *archivename);
42extern void cgit_diff_link(const char *name, const char *title, 42extern void cgit_diff_link(const char *name, const char *title,
43 const char *class, const char *head, 43 const char *class, const char *head,
44 const char *new_rev, const char *old_rev, 44 const char *new_rev, const char *old_rev,
45 const char *path, int toggle_ssdiff); 45 const char *path, int toggle_ssdiff);
46extern void cgit_stats_link(const char *name, const char *title, 46extern void cgit_stats_link(const char *name, const char *title,
47 const char *class, const char *head, 47 const char *class, const char *head,
48 const char *path); 48 const char *path);
49extern void cgit_self_link(char *name, const char *title,
50 const char *class, struct cgit_context *ctx);
49extern void cgit_object_link(struct object *obj); 51extern void cgit_object_link(struct object *obj);
50 52
51extern void cgit_print_error(const char *msg); 53extern void cgit_print_error(const char *msg);
52extern void cgit_print_date(time_t secs, const char *format, int local_time); 54extern void cgit_print_date(time_t secs, const char *format, int local_time);
53extern void cgit_print_age(time_t t, time_t max_relative, const char *format); 55extern void cgit_print_age(time_t t, time_t max_relative, const char *format);
54extern void cgit_print_http_headers(struct cgit_context *ctx); 56extern void cgit_print_http_headers(struct cgit_context *ctx);
55extern void cgit_print_docstart(struct cgit_context *ctx); 57extern void cgit_print_docstart(struct cgit_context *ctx);
56extern void cgit_print_docend(); 58extern void cgit_print_docend();
57extern void cgit_print_pageheader(struct cgit_context *ctx); 59extern void cgit_print_pageheader(struct cgit_context *ctx);
58extern void cgit_print_filemode(unsigned short mode); 60extern void cgit_print_filemode(unsigned short mode);
59extern void cgit_print_snapshot_links(const char *repo, const char *head, 61extern void cgit_print_snapshot_links(const char *repo, const char *head,
60 const char *hex, int snapshots); 62 const char *hex, int snapshots);