summaryrefslogtreecommitdiffabout
path: root/ui-shared.c
Unidiff
Diffstat (limited to 'ui-shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-shared.c81
1 files changed, 80 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
@@ -370,64 +370,122 @@ void cgit_diff_link(const char *name, const char *title, const char *class,
370 html(delim); 370 html(delim);
371 html("id="); 371 html("id=");
372 html_url_arg(new_rev); 372 html_url_arg(new_rev);
373 delim = "&"; 373 delim = "&";
374 } 374 }
375 if (old_rev) { 375 if (old_rev) {
376 html(delim); 376 html(delim);
377 html("id2="); 377 html("id2=");
378 html_url_arg(old_rev); 378 html_url_arg(old_rev);
379 delim = "&"; 379 delim = "&";
380 } 380 }
381 if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) { 381 if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) {
382 html(delim); 382 html(delim);
383 html("ss=1"); 383 html("ss=1");
384 } 384 }
385 html("'>"); 385 html("'>");
386 html_txt(name); 386 html_txt(name);
387 html("</a>"); 387 html("</a>");
388} 388}
389 389
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)
414 page = "tree"; 472 page = "tree";
415 else if (obj->type == OBJ_TAG) 473 else if (obj->type == OBJ_TAG)
416 page = "tag"; 474 page = "tag";
417 else 475 else
418 page = "blob"; 476 page = "blob";
419 name = fmt("%s %s...", typename(obj->type), shortrev); 477 name = fmt("%s %s...", typename(obj->type), shortrev);
420 reporevlink(page, name, NULL, NULL, ctx.qry.head, fullrev, NULL); 478 reporevlink(page, name, NULL, NULL, ctx.qry.head, fullrev, NULL);
421} 479}
422 480
423void cgit_print_date(time_t secs, const char *format, int local_time) 481void cgit_print_date(time_t secs, const char *format, int local_time)
424{ 482{
425 char buf[64]; 483 char buf[64];
426 struct tm *time; 484 struct tm *time;
427 485
428 if (!secs) 486 if (!secs)
429 return; 487 return;
430 if(local_time) 488 if(local_time)
431 time = localtime(&secs); 489 time = localtime(&secs);
432 else 490 else
433 time = gmtime(&secs); 491 time = gmtime(&secs);
@@ -621,64 +679,85 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search,
621 679
622 if (!ctx.cfg.virtual_root) { 680 if (!ctx.cfg.virtual_root) {
623 url = fmt("%s/%s", ctx.qry.repo, page); 681 url = fmt("%s/%s", ctx.qry.repo, page);
624 if (ctx.qry.vpath) 682 if (ctx.qry.vpath)
625 url = fmt("%s/%s", url, ctx.qry.vpath); 683 url = fmt("%s/%s", url, ctx.qry.vpath);
626 html_hidden("url", url); 684 html_hidden("url", url);
627 } 685 }
628 686
629 if (incl_head && ctx.qry.head && ctx.repo->defbranch && 687 if (incl_head && ctx.qry.head && ctx.repo->defbranch &&
630 strcmp(ctx.qry.head, ctx.repo->defbranch)) 688 strcmp(ctx.qry.head, ctx.repo->defbranch))
631 html_hidden("h", ctx.qry.head); 689 html_hidden("h", ctx.qry.head);
632 690
633 if (ctx.qry.sha1) 691 if (ctx.qry.sha1)
634 html_hidden("id", ctx.qry.sha1); 692 html_hidden("id", ctx.qry.sha1);
635 if (ctx.qry.sha2) 693 if (ctx.qry.sha2)
636 html_hidden("id2", ctx.qry.sha2); 694 html_hidden("id2", ctx.qry.sha2);
637 if (ctx.qry.showmsg) 695 if (ctx.qry.showmsg)
638 html_hidden("showmsg", "1"); 696 html_hidden("showmsg", "1");
639 697
640 if (incl_search) { 698 if (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='");
665 html_attr(ctx->cfg.logo); 744 html_attr(ctx->cfg.logo);
666 html("' alt='cgit logo'/></a></td>\n"); 745 html("' alt='cgit logo'/></a></td>\n");
667 } 746 }
668 747
669 html("<td class='main'>"); 748 html("<td class='main'>");
670 if (ctx->repo) { 749 if (ctx->repo) {
671 cgit_index_link("index", NULL, NULL, NULL, 0); 750 cgit_index_link("index", NULL, NULL, NULL, 0);
672 html(" : "); 751 html(" : ");
673 cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL); 752 cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL);
674 html("</td><td class='form'>"); 753 html("</td><td class='form'>");
675 html("<form method='get' action=''>\n"); 754 html("<form method='get' action=''>\n");
676 cgit_add_hidden_formfields(0, 1, ctx->qry.page); 755 cgit_add_hidden_formfields(0, 1, ctx->qry.page);
677 html("<select name='h' onchange='this.form.submit();'>\n"); 756 html("<select name='h' onchange='this.form.submit();'>\n");
678 for_each_branch_ref(print_branch_option, ctx->qry.head); 757 for_each_branch_ref(print_branch_option, ctx->qry.head);
679 html("</select> "); 758 html("</select> ");
680 html("<input type='submit' name='' value='switch'/>"); 759 html("<input type='submit' name='' value='switch'/>");
681 html("</form>"); 760 html("</form>");
682 } else 761 } else
683 html_txt(ctx->cfg.root_title); 762 html_txt(ctx->cfg.root_title);
684 html("</td></tr>\n"); 763 html("</td></tr>\n");
@@ -731,65 +810,65 @@ void cgit_print_pageheader(struct cgit_context *ctx)
731 ctx->qry.vpath, NULL)); 810 ctx->qry.vpath, NULL));
732 html("'>\n"); 811 html("'>\n");
733 cgit_add_hidden_formfields(1, 0, "log"); 812 cgit_add_hidden_formfields(1, 0, "log");
734 html("<select name='qt'>\n"); 813 html("<select name='qt'>\n");
735 html_option("grep", "log msg", ctx->qry.grep); 814 html_option("grep", "log msg", ctx->qry.grep);
736 html_option("author", "author", ctx->qry.grep); 815 html_option("author", "author", ctx->qry.grep);
737 html_option("committer", "committer", ctx->qry.grep); 816 html_option("committer", "committer", ctx->qry.grep);
738 html("</select>\n"); 817 html("</select>\n");
739 html("<input class='txt' type='text' size='10' name='q' value='"); 818 html("<input class='txt' type='text' size='10' name='q' value='");
740 html_attr(ctx->qry.search); 819 html_attr(ctx->qry.search);
741 html("'/>\n"); 820 html("'/>\n");
742 html("<input type='submit' value='search'/>\n"); 821 html("<input type='submit' value='search'/>\n");
743 html("</form>\n"); 822 html("</form>\n");
744 } else { 823 } else {
745 site_link(NULL, "index", NULL, hc(ctx, "repolist"), NULL, 0); 824 site_link(NULL, "index", NULL, hc(ctx, "repolist"), NULL, 0);
746 if (ctx->cfg.root_readme) 825 if (ctx->cfg.root_readme)
747 site_link("about", "about", NULL, hc(ctx, "about"), 826 site_link("about", "about", NULL, hc(ctx, "about"),
748 NULL, 0); 827 NULL, 0);
749 html("</td><td class='form'>"); 828 html("</td><td class='form'>");
750 html("<form method='get' action='"); 829 html("<form method='get' action='");
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))
776 html("m"); 855 html("m");
777 else 856 else
778 html("-"); 857 html("-");
779 html_fileperm(mode >> 6); 858 html_fileperm(mode >> 6);
780 html_fileperm(mode >> 3); 859 html_fileperm(mode >> 3);
781 html_fileperm(mode); 860 html_fileperm(mode);
782} 861}
783 862
784void cgit_print_snapshot_links(const char *repo, const char *head, 863void cgit_print_snapshot_links(const char *repo, const char *head,
785 const char *hex, int snapshots) 864 const char *hex, int snapshots)
786{ 865{
787 const struct cgit_snapshot_format* f; 866 const struct cgit_snapshot_format* f;
788 char *prefix; 867 char *prefix;
789 char *filename; 868 char *filename;
790 unsigned char sha1[20]; 869 unsigned char sha1[20];
791 870
792 if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 && 871 if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 &&
793 (hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1])) 872 (hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1]))
794 hex++; 873 hex++;
795 prefix = xstrdup(fmt("%s-%s", cgit_repobasename(repo), hex)); 874 prefix = xstrdup(fmt("%s-%s", cgit_repobasename(repo), hex));