about summary refs log tree commit diff
path: root/ui-shared.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui-shared.c')
-rw-r--r--ui-shared.c234
1 files changed, 223 insertions, 11 deletions
diff --git a/ui-shared.c b/ui-shared.c
index aba93e8..5c5bcf3 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -57,13 +57,13 @@ char *cgit_repourl(const char *reponame)
 	}
 }
 
-char *cgit_pageurl(const char *reponame, const char *pagename,
-		   const char *query)
+char *cgit_fileurl(const char *reponame, const char *pagename,
+		   const char *filename, const char *query)
 {
 	if (cgit_virtual_root) {
 		if (query)
-			return fmt("%s/%s/%s/?%s", cgit_virtual_root, reponame,
-				   pagename, query);
+			return fmt("%s/%s/%s/%s?%s", cgit_virtual_root, reponame,
+				   pagename, filename?filename:"", query);
 		else
 			return fmt("%s/%s/%s/", cgit_virtual_root, reponame,
 				   pagename);
@@ -75,6 +75,37 @@ char *cgit_pageurl(const char *reponame, const char *pagename,
 	}
 }
 
+char *cgit_pageurl(const char *reponame, const char *pagename,
+		   const char *query)
+{
+	return cgit_fileurl(reponame,pagename,0,query);
+}
+
+const char *cgit_repobasename(const char *reponame)
+{
+	/* I assume we don't need to store more than one repo basename */
+	static char rvbuf[1024];
+	int p;
+	const char *rv;
+	strncpy(rvbuf,reponame,sizeof(rvbuf));
+	if(rvbuf[sizeof(rvbuf)-1])
+		die("cgit_repobasename: truncated repository name '%s'", reponame);
+	p = strlen(rvbuf)-1;
+	/* strip trailing slashes */
+	while(p && rvbuf[p]=='/') rvbuf[p--]=0;
+	/* strip trailing .git */
+	if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) {
+		p -= 3; rvbuf[p--] = 0;
+	}
+	/* strip more trailing slashes if any */
+	while( p && rvbuf[p]=='/') rvbuf[p--]=0;
+	/* find last slash in the remaining string */
+	rv = strrchr(rvbuf,'/');
+	if(rv)
+		return ++rv;
+	return rvbuf;
+}
+
 char *cgit_currurl()
 {
 	if (!cgit_virtual_root)
@@ -87,6 +118,166 @@ char *cgit_currurl()
 		return fmt("%s/", cgit_virtual_root);
 }
 
+static char *repolink(char *title, char *class, char *page, char *head,
+		      char *path)
+{
+	char *delim = "?";
+
+	html("<a");
+	if (title) {
+		html(" title='");
+		html_attr(title);
+		html("'");
+	}
+	if (class) {
+		html(" class='");
+		html_attr(class);
+		html("'");
+	}
+	html(" href='");
+	if (cgit_virtual_root) {
+		html_attr(cgit_virtual_root);
+		if (cgit_virtual_root[strlen(cgit_virtual_root) - 1] != '/')
+			html("/");
+		html_attr(cgit_repo->url);
+		if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/')
+			html("/");
+		if (page) {
+			html(page);
+			html("/");
+			if (path)
+				html_attr(path);
+		}
+	} else {
+		html(cgit_script_name);
+		html("?url=");
+		html_attr(cgit_repo->url);
+		if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/')
+			html("/");
+		if (page) {
+			html(page);
+			html("/");
+			if (path)
+				html_attr(path);
+		}
+		delim = "&amp;";
+	}
+	if (head && strcmp(head, cgit_repo->defbranch)) {
+		html(delim);
+		html("h=");
+		html_attr(head);
+		delim = "&amp;";
+	}
+	return fmt("%s", delim);
+}
+
+static void reporevlink(char *page, char *name, char *title, char *class,
+			char *head, char *rev, char *path)
+{
+	char *delim;
+
+	delim = repolink(title, class, page, head, path);
+	if (rev && strcmp(rev, cgit_query_head)) {
+		html(delim);
+		html("id=");
+		html_attr(rev);
+	}
+	html("'>");
+	html_txt(name);
+	html("</a>");
+}
+
+void cgit_tree_link(char *name, char *title, char *class, char *head,
+		    char *rev, char *path)
+{
+	reporevlink("tree", name, title, class, head, rev, path);
+}
+
+void cgit_log_link(char *name, char *title, char *class, char *head,
+		   char *rev, char *path, int ofs)
+{
+	char *delim;
+
+	delim = repolink(title, class, "log", head, path);
+	if (rev && strcmp(rev, cgit_query_head)) {
+		html(delim);
+		html("id=");
+		html_attr(rev);
+		delim = "&";
+	}
+	if (ofs > 0) {
+		html(delim);
+		html("ofs=");
+		htmlf("%d", ofs);
+	}
+	html("'>");
+	html_txt(name);
+	html("</a>");
+}
+
+void cgit_commit_link(char *name, char *title, char *class, char *head,
+		      char *rev)
+{
+	if (strlen(name) > cgit_max_msg_len && cgit_max_msg_len >= 15) {
+		name[cgit_max_msg_len] = '\0';
+		name[cgit_max_msg_len - 1] = '.';
+		name[cgit_max_msg_len - 2] = '.';
+		name[cgit_max_msg_len - 3] = '.';
+	}
+	reporevlink("commit", name, title, class, head, rev, NULL);
+}
+
+void cgit_snapshot_link(char *name, char *title, char *class, char *head,
+			char *rev, char *archivename)
+{
+	reporevlink("snapshot", name, title, class, head, rev, archivename);
+}
+
+void cgit_diff_link(char *name, char *title, char *class, char *head,
+		    char *new_rev, char *old_rev, char *path)
+{
+	char *delim;
+
+	delim = repolink(title, class, "diff", head, path);
+	if (new_rev && strcmp(new_rev, cgit_query_head)) {
+		html(delim);
+		html("id=");
+		html_attr(new_rev);
+		delim = "&amp;";
+	}
+	if (old_rev) {
+		html(delim);
+		html("id2=");
+		html_attr(old_rev);
+	}
+	html("'>");
+	html_txt(name);
+	html("</a>");
+}
+
+void cgit_object_link(struct object *obj)
+{
+	char *page, *arg, *url;
+
+	if (obj->type == OBJ_COMMIT) {
+                cgit_commit_link(fmt("commit %s", sha1_to_hex(obj->sha1)), NULL, NULL,
+				 cgit_query_head, sha1_to_hex(obj->sha1));
+		return;
+	} else if (obj->type == OBJ_TREE) {
+		page = "tree";
+		arg = "id";
+	} else {
+		page = "blob";
+		arg = "id";
+	}
+
+	url = cgit_pageurl(cgit_query_repo, page,
+			   fmt("%s=%s", arg, sha1_to_hex(obj->sha1)));
+	html_link_open(url, NULL, NULL);
+	htmlf("%s %s", typename(obj->type),
+	      sha1_to_hex(obj->sha1));
+	html_link_close();
+}
 
 void cgit_print_date(time_t secs, char *format)
 {
@@ -152,7 +343,7 @@ void cgit_print_docstart(char *title, struct cacheitem *item)
 	html("<title>");
 	html_txt(title);
 	html("</title>\n");
-	htmlf("<meta name='generator' content='cgit v%s'/>\n", cgit_version);
+	htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version);
 	html("<link rel='stylesheet' type='text/css' href='");
 	html_attr(cgit_css);
 	html("'/>\n");
@@ -169,19 +360,38 @@ void cgit_print_docend()
 void cgit_print_pageheader(char *title, int show_search)
 {
 	html("<table id='layout'>");
-	html("<tr><td id='header'>");
-	html(cgit_root_title);
-	html("</td><td id='logo'>");
+	html("<tr><td id='header'><a href='");
+	html_attr(cgit_rooturl());
+	html("'>");
+	html_txt(cgit_root_title);
+	html("</a></td><td id='logo'>");
 	html("<a href='");
 	html_attr(cgit_logo_link);
 	htmlf("'><img src='%s' alt='logo'/></a>", cgit_logo);
 	html("</td></tr>");
 	html("<tr><td id='crumb'>");
-	htmlf("<a href='%s'>root</a>", cgit_rooturl());
 	if (cgit_query_repo) {
-		htmlf(" : <a href='%s'>", cgit_repourl(cgit_repo->url));
 		html_txt(cgit_repo->name);
-		htmlf("</a> : %s", title);
+		html(" (");
+		html_txt(cgit_query_head);
+		html(") : &nbsp;");
+		reporevlink(NULL, "summary", NULL, NULL, cgit_query_head,
+			    NULL, NULL);
+		html(" ");
+		cgit_log_link("log", NULL, NULL, cgit_query_head,
+			      cgit_query_sha1, cgit_query_path, 0);
+		html(" ");
+		cgit_tree_link("tree", NULL, NULL, cgit_query_head,
+			       cgit_query_sha1, NULL);
+		html(" ");
+		cgit_commit_link("commit", NULL, NULL, cgit_query_head,
+			      cgit_query_sha1);
+		html(" ");
+		cgit_diff_link("diff", NULL, NULL, cgit_query_head,
+			       cgit_query_sha1, cgit_query_sha2,
+			       cgit_query_path);
+	} else {
+		html_txt("Index of repositories");
 	}
 	html("</td>");
 	html("<td id='search'>");
@@ -219,3 +429,5 @@ void cgit_print_snapshot_start(const char *mimetype, const char *filename,
 					 ttl_seconds(item->ttl)));
 	html("\n");
 }
+
+/* vim:set sw=8: */