summaryrefslogtreecommitdiffabout
path: root/ui-shared.c
Unidiff
Diffstat (limited to 'ui-shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-shared.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/ui-shared.c b/ui-shared.c
index 66d5b82..015c52b 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -440,132 +440,141 @@ void cgit_print_age(time_t t, time_t max_relative, char *format)
440 htmlf("<span class='age-mins'>%.0f min.</span>", 440 htmlf("<span class='age-mins'>%.0f min.</span>",
441 secs * 1.0 / TM_MIN); 441 secs * 1.0 / TM_MIN);
442 return; 442 return;
443 } 443 }
444 if (secs < TM_DAY * 2) { 444 if (secs < TM_DAY * 2) {
445 htmlf("<span class='age-hours'>%.0f hours</span>", 445 htmlf("<span class='age-hours'>%.0f hours</span>",
446 secs * 1.0 / TM_HOUR); 446 secs * 1.0 / TM_HOUR);
447 return; 447 return;
448 } 448 }
449 if (secs < TM_WEEK * 2) { 449 if (secs < TM_WEEK * 2) {
450 htmlf("<span class='age-days'>%.0f days</span>", 450 htmlf("<span class='age-days'>%.0f days</span>",
451 secs * 1.0 / TM_DAY); 451 secs * 1.0 / TM_DAY);
452 return; 452 return;
453 } 453 }
454 if (secs < TM_MONTH * 2) { 454 if (secs < TM_MONTH * 2) {
455 htmlf("<span class='age-weeks'>%.0f weeks</span>", 455 htmlf("<span class='age-weeks'>%.0f weeks</span>",
456 secs * 1.0 / TM_WEEK); 456 secs * 1.0 / TM_WEEK);
457 return; 457 return;
458 } 458 }
459 if (secs < TM_YEAR * 2) { 459 if (secs < TM_YEAR * 2) {
460 htmlf("<span class='age-months'>%.0f months</span>", 460 htmlf("<span class='age-months'>%.0f months</span>",
461 secs * 1.0 / TM_MONTH); 461 secs * 1.0 / TM_MONTH);
462 return; 462 return;
463 } 463 }
464 htmlf("<span class='age-years'>%.0f years</span>", 464 htmlf("<span class='age-years'>%.0f years</span>",
465 secs * 1.0 / TM_YEAR); 465 secs * 1.0 / TM_YEAR);
466} 466}
467 467
468void cgit_print_http_headers(struct cgit_context *ctx) 468void cgit_print_http_headers(struct cgit_context *ctx)
469{ 469{
470 const char *method = getenv("REQUEST_METHOD"); 470 const char *method = getenv("REQUEST_METHOD");
471 471
472 if (ctx->cfg.embedded)
473 return;
474
472 if (ctx->page.status) 475 if (ctx->page.status)
473 htmlf("Status: %d %s\n", ctx->page.status, ctx->page.statusmsg); 476 htmlf("Status: %d %s\n", ctx->page.status, ctx->page.statusmsg);
474 if (ctx->page.mimetype && ctx->page.charset) 477 if (ctx->page.mimetype && ctx->page.charset)
475 htmlf("Content-Type: %s; charset=%s\n", ctx->page.mimetype, 478 htmlf("Content-Type: %s; charset=%s\n", ctx->page.mimetype,
476 ctx->page.charset); 479 ctx->page.charset);
477 else if (ctx->page.mimetype) 480 else if (ctx->page.mimetype)
478 htmlf("Content-Type: %s\n", ctx->page.mimetype); 481 htmlf("Content-Type: %s\n", ctx->page.mimetype);
479 if (ctx->page.size) 482 if (ctx->page.size)
480 htmlf("Content-Length: %ld\n", ctx->page.size); 483 htmlf("Content-Length: %ld\n", ctx->page.size);
481 if (ctx->page.filename) 484 if (ctx->page.filename)
482 htmlf("Content-Disposition: inline; filename=\"%s\"\n", 485 htmlf("Content-Disposition: inline; filename=\"%s\"\n",
483 ctx->page.filename); 486 ctx->page.filename);
484 htmlf("Last-Modified: %s\n", http_date(ctx->page.modified)); 487 htmlf("Last-Modified: %s\n", http_date(ctx->page.modified));
485 htmlf("Expires: %s\n", http_date(ctx->page.expires)); 488 htmlf("Expires: %s\n", http_date(ctx->page.expires));
486 if (ctx->page.etag) 489 if (ctx->page.etag)
487 htmlf("ETag: \"%s\"\n", ctx->page.etag); 490 htmlf("ETag: \"%s\"\n", ctx->page.etag);
488 html("\n"); 491 html("\n");
489 if (method && !strcmp(method, "HEAD")) 492 if (method && !strcmp(method, "HEAD"))
490 exit(0); 493 exit(0);
491} 494}
492 495
493void cgit_print_docstart(struct cgit_context *ctx) 496void cgit_print_docstart(struct cgit_context *ctx)
494{ 497{
498 if (ctx->cfg.embedded)
499 return;
500
495 char *host = cgit_hosturl(); 501 char *host = cgit_hosturl();
496 html(cgit_doctype); 502 html(cgit_doctype);
497 html("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n"); 503 html("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n");
498 html("<head>\n"); 504 html("<head>\n");
499 html("<title>"); 505 html("<title>");
500 html_txt(ctx->page.title); 506 html_txt(ctx->page.title);
501 html("</title>\n"); 507 html("</title>\n");
502 htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version); 508 htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version);
503 if (ctx->cfg.robots && *ctx->cfg.robots) 509 if (ctx->cfg.robots && *ctx->cfg.robots)
504 htmlf("<meta name='robots' content='%s'/>\n", ctx->cfg.robots); 510 htmlf("<meta name='robots' content='%s'/>\n", ctx->cfg.robots);
505 html("<link rel='stylesheet' type='text/css' href='"); 511 html("<link rel='stylesheet' type='text/css' href='");
506 html_attr(ctx->cfg.css); 512 html_attr(ctx->cfg.css);
507 html("'/>\n"); 513 html("'/>\n");
508 if (ctx->cfg.favicon) { 514 if (ctx->cfg.favicon) {
509 html("<link rel='shortcut icon' href='"); 515 html("<link rel='shortcut icon' href='");
510 html_attr(ctx->cfg.favicon); 516 html_attr(ctx->cfg.favicon);
511 html("'/>\n"); 517 html("'/>\n");
512 } 518 }
513 if (host && ctx->repo) { 519 if (host && ctx->repo) {
514 html("<link rel='alternate' title='Atom feed' href='"); 520 html("<link rel='alternate' title='Atom feed' href='");
515 html(cgit_httpscheme()); 521 html(cgit_httpscheme());
516 html_attr(cgit_hosturl()); 522 html_attr(cgit_hosturl());
517 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path, 523 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path,
518 fmt("h=%s", ctx->qry.head))); 524 fmt("h=%s", ctx->qry.head)));
519 html("' type='application/atom+xml'/>\n"); 525 html("' type='application/atom+xml'/>\n");
520 } 526 }
521 if (ctx->cfg.head_include) 527 if (ctx->cfg.head_include)
522 html_include(ctx->cfg.head_include); 528 html_include(ctx->cfg.head_include);
523 html("</head>\n"); 529 html("</head>\n");
524 html("<body>\n"); 530 html("<body>\n");
525 if (ctx->cfg.header) 531 if (ctx->cfg.header)
526 html_include(ctx->cfg.header); 532 html_include(ctx->cfg.header);
527} 533}
528 534
529void cgit_print_docend() 535void cgit_print_docend()
530{ 536{
531 html("</div>"); 537 html("</div>");
532 if (ctx.cfg.footer) 538 if (ctx.cfg.footer)
533 html_include(ctx.cfg.footer); 539 html_include(ctx.cfg.footer);
534 else { 540 else {
535 htmlf("<div class='footer'>generated by cgit %s at ", 541 htmlf("<div class='footer'>generated by cgit %s at ",
536 cgit_version); 542 cgit_version);
537 cgit_print_date(time(NULL), FMT_LONGDATE, ctx.cfg.local_time); 543 cgit_print_date(time(NULL), FMT_LONGDATE, ctx.cfg.local_time);
538 html("</div>\n"); 544 html("</div>\n");
539 } 545 }
546 html("</div>");
547 if (ctx.cfg.embedded)
548 return;
540 html("</body>\n</html>\n"); 549 html("</body>\n</html>\n");
541} 550}
542 551
543int print_branch_option(const char *refname, const unsigned char *sha1, 552int print_branch_option(const char *refname, const unsigned char *sha1,
544 int flags, void *cb_data) 553 int flags, void *cb_data)
545{ 554{
546 char *name = (char *)refname; 555 char *name = (char *)refname;
547 html_option(name, name, ctx.qry.head); 556 html_option(name, name, ctx.qry.head);
548 return 0; 557 return 0;
549} 558}
550 559
551int print_archive_ref(const char *refname, const unsigned char *sha1, 560int print_archive_ref(const char *refname, const unsigned char *sha1,
552 int flags, void *cb_data) 561 int flags, void *cb_data)
553{ 562{
554 struct tag *tag; 563 struct tag *tag;
555 struct taginfo *info; 564 struct taginfo *info;
556 struct object *obj; 565 struct object *obj;
557 char buf[256], *url; 566 char buf[256], *url;
558 unsigned char fileid[20]; 567 unsigned char fileid[20];
559 int *header = (int *)cb_data; 568 int *header = (int *)cb_data;
560 569
561 if (prefixcmp(refname, "refs/archives")) 570 if (prefixcmp(refname, "refs/archives"))
562 return 0; 571 return 0;
563 strncpy(buf, refname+14, sizeof(buf)); 572 strncpy(buf, refname+14, sizeof(buf));
564 obj = parse_object(sha1); 573 obj = parse_object(sha1);
565 if (!obj) 574 if (!obj)
566 return 1; 575 return 1;
567 if (obj->type == OBJ_TAG) { 576 if (obj->type == OBJ_TAG) {
568 tag = lookup_tag(sha1); 577 tag = lookup_tag(sha1);
569 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) 578 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
570 return 0; 579 return 0;
571 hashcpy(fileid, tag->tagged->sha1); 580 hashcpy(fileid, tag->tagged->sha1);
@@ -595,111 +604,118 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page)
595 url = fmt("%s/%s", ctx.qry.repo, page); 604 url = fmt("%s/%s", ctx.qry.repo, page);
596 if (ctx.qry.path) 605 if (ctx.qry.path)
597 url = fmt("%s/%s", url, ctx.qry.path); 606 url = fmt("%s/%s", url, ctx.qry.path);
598 html_hidden("url", url); 607 html_hidden("url", url);
599 } 608 }
600 609
601 if (incl_head && ctx.qry.head && ctx.repo->defbranch && 610 if (incl_head && ctx.qry.head && ctx.repo->defbranch &&
602 strcmp(ctx.qry.head, ctx.repo->defbranch)) 611 strcmp(ctx.qry.head, ctx.repo->defbranch))
603 html_hidden("h", ctx.qry.head); 612 html_hidden("h", ctx.qry.head);
604 613
605 if (ctx.qry.sha1) 614 if (ctx.qry.sha1)
606 html_hidden("id", ctx.qry.sha1); 615 html_hidden("id", ctx.qry.sha1);
607 if (ctx.qry.sha2) 616 if (ctx.qry.sha2)
608 html_hidden("id2", ctx.qry.sha2); 617 html_hidden("id2", ctx.qry.sha2);
609 if (ctx.qry.showmsg) 618 if (ctx.qry.showmsg)
610 html_hidden("showmsg", "1"); 619 html_hidden("showmsg", "1");
611 620
612 if (incl_search) { 621 if (incl_search) {
613 if (ctx.qry.grep) 622 if (ctx.qry.grep)
614 html_hidden("qt", ctx.qry.grep); 623 html_hidden("qt", ctx.qry.grep);
615 if (ctx.qry.search) 624 if (ctx.qry.search)
616 html_hidden("q", ctx.qry.search); 625 html_hidden("q", ctx.qry.search);
617 } 626 }
618} 627}
619 628
620const char *fallback_cmd = "repolist"; 629const char *fallback_cmd = "repolist";
621 630
622char *hc(struct cgit_cmd *cmd, const char *page) 631char *hc(struct cgit_cmd *cmd, const char *page)
623{ 632{
624 return (strcmp(cmd ? cmd->name : fallback_cmd, page) ? NULL : "active"); 633 return (strcmp(cmd ? cmd->name : fallback_cmd, page) ? NULL : "active");
625} 634}
626 635
627void cgit_print_pageheader(struct cgit_context *ctx) 636static void print_header(struct cgit_context *ctx)
628{ 637{
629 struct cgit_cmd *cmd = cgit_get_cmd(ctx);
630
631 if (!cmd && ctx->repo)
632 fallback_cmd = "summary";
633
634 html("<table id='header'>\n"); 638 html("<table id='header'>\n");
635 html("<tr>\n"); 639 html("<tr>\n");
636 html("<td class='logo' rowspan='2'><a href='"); 640 html("<td class='logo' rowspan='2'><a href='");
637 if (ctx->cfg.logo_link) 641 if (ctx->cfg.logo_link)
638 html_attr(ctx->cfg.logo_link); 642 html_attr(ctx->cfg.logo_link);
639 else 643 else
640 html_attr(cgit_rooturl()); 644 html_attr(cgit_rooturl());
641 html("'><img src='"); 645 html("'><img src='");
642 html_attr(ctx->cfg.logo); 646 html_attr(ctx->cfg.logo);
643 html("' alt='cgit logo'/></a></td>\n"); 647 html("' alt='cgit logo'/></a></td>\n");
644 648
645 html("<td class='main'>"); 649 html("<td class='main'>");
646 if (ctx->repo) { 650 if (ctx->repo) {
647 cgit_index_link("index", NULL, NULL, NULL, 0); 651 cgit_index_link("index", NULL, NULL, NULL, 0);
648 html(" : "); 652 html(" : ");
649 cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL); 653 cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL);
650 html("</td><td class='form'>"); 654 html("</td><td class='form'>");
651 html("<form method='get' action=''>\n"); 655 html("<form method='get' action=''>\n");
652 cgit_add_hidden_formfields(0, 1, ctx->qry.page); 656 cgit_add_hidden_formfields(0, 1, ctx->qry.page);
653 html("<select name='h' onchange='this.form.submit();'>\n"); 657 html("<select name='h' onchange='this.form.submit();'>\n");
654 for_each_branch_ref(print_branch_option, ctx->qry.head); 658 for_each_branch_ref(print_branch_option, ctx->qry.head);
655 html("</select> "); 659 html("</select> ");
656 html("<input type='submit' name='' value='switch'/>"); 660 html("<input type='submit' name='' value='switch'/>");
657 html("</form>"); 661 html("</form>");
658 } else 662 } else
659 html_txt(ctx->cfg.root_title); 663 html_txt(ctx->cfg.root_title);
660 html("</td></tr>\n"); 664 html("</td></tr>\n");
661 665
662 html("<tr><td class='sub'>"); 666 html("<tr><td class='sub'>");
663 if (ctx->repo) { 667 if (ctx->repo) {
664 html_txt(ctx->repo->desc); 668 html_txt(ctx->repo->desc);
665 html("</td><td class='sub right'>"); 669 html("</td><td class='sub right'>");
666 html_txt(ctx->repo->owner); 670 html_txt(ctx->repo->owner);
667 } else { 671 } else {
668 if (ctx->cfg.root_desc) 672 if (ctx->cfg.root_desc)
669 html_txt(ctx->cfg.root_desc); 673 html_txt(ctx->cfg.root_desc);
670 else if (ctx->cfg.index_info) 674 else if (ctx->cfg.index_info)
671 html_include(ctx->cfg.index_info); 675 html_include(ctx->cfg.index_info);
672 } 676 }
673 html("</td></tr></table>\n"); 677 html("</td></tr></table>\n");
678}
679
680void cgit_print_pageheader(struct cgit_context *ctx)
681{
682 struct cgit_cmd *cmd = cgit_get_cmd(ctx);
683
684 if (!cmd && ctx->repo)
685 fallback_cmd = "summary";
686
687 html("<div id='cgit'>");
688 if (!ctx->cfg.noheader)
689 print_header(ctx);
674 690
675 html("<table class='tabs'><tr><td>\n"); 691 html("<table class='tabs'><tr><td>\n");
676 if (ctx->repo) { 692 if (ctx->repo) {
677 cgit_summary_link("summary", NULL, hc(cmd, "summary"), 693 cgit_summary_link("summary", NULL, hc(cmd, "summary"),
678 ctx->qry.head); 694 ctx->qry.head);
679 cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head, 695 cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head,
680 ctx->qry.sha1, NULL); 696 ctx->qry.sha1, NULL);
681 cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head, 697 cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head,
682 NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg); 698 NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg);
683 cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head, 699 cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head,
684 ctx->qry.sha1, NULL); 700 ctx->qry.sha1, NULL);
685 cgit_commit_link("commit", NULL, hc(cmd, "commit"), 701 cgit_commit_link("commit", NULL, hc(cmd, "commit"),
686 ctx->qry.head, ctx->qry.sha1); 702 ctx->qry.head, ctx->qry.sha1);
687 cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head, 703 cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head,
688 ctx->qry.sha1, ctx->qry.sha2, NULL); 704 ctx->qry.sha1, ctx->qry.sha2, NULL);
689 if (ctx->repo->max_stats) 705 if (ctx->repo->max_stats)
690 cgit_stats_link("stats", NULL, hc(cmd, "stats"), 706 cgit_stats_link("stats", NULL, hc(cmd, "stats"),
691 ctx->qry.head, NULL); 707 ctx->qry.head, NULL);
692 if (ctx->repo->readme) 708 if (ctx->repo->readme)
693 reporevlink("about", "about", NULL, 709 reporevlink("about", "about", NULL,
694 hc(cmd, "about"), ctx->qry.head, NULL, 710 hc(cmd, "about"), ctx->qry.head, NULL,
695 NULL); 711 NULL);
696 html("</td><td class='form'>"); 712 html("</td><td class='form'>");
697 html("<form class='right' method='get' action='"); 713 html("<form class='right' method='get' action='");
698 if (ctx->cfg.virtual_root) 714 if (ctx->cfg.virtual_root)
699 html_url_path(cgit_fileurl(ctx->qry.repo, "log", 715 html_url_path(cgit_fileurl(ctx->qry.repo, "log",
700 ctx->qry.path, NULL)); 716 ctx->qry.path, NULL));
701 html("'>\n"); 717 html("'>\n");
702 cgit_add_hidden_formfields(1, 0, "log"); 718 cgit_add_hidden_formfields(1, 0, "log");
703 html("<select name='qt'>\n"); 719 html("<select name='qt'>\n");
704 html_option("grep", "log msg", ctx->qry.grep); 720 html_option("grep", "log msg", ctx->qry.grep);
705 html_option("author", "author", ctx->qry.grep); 721 html_option("author", "author", ctx->qry.grep);