-rw-r--r-- | ui-shared.c | 288 |
1 files changed, 217 insertions, 71 deletions
diff --git a/ui-shared.c b/ui-shared.c index d1b020b..5aa9119 100644 --- a/ui-shared.c +++ b/ui-shared.c | |||
@@ -26,9 +26,9 @@ static char *http_date(time_t t) | |||
26 | tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, | 26 | tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, |
27 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 27 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
28 | } | 28 | } |
29 | 29 | ||
30 | void cgit_print_error(char *msg) | 30 | void cgit_print_error(const char *msg) |
31 | { | 31 | { |
32 | html("<div class='error'>"); | 32 | html("<div class='error'>"); |
33 | html_txt(msg); | 33 | html_txt(msg); |
34 | html("</div>\n"); | 34 | html("</div>\n"); |
@@ -132,9 +132,9 @@ char *cgit_currurl() | |||
132 | else | 132 | else |
133 | return fmt("%s/", ctx.cfg.virtual_root); | 133 | return fmt("%s/", ctx.cfg.virtual_root); |
134 | } | 134 | } |
135 | 135 | ||
136 | static void site_url(char *page, char *search, int ofs) | 136 | static void site_url(const char *page, const char *search, int ofs) |
137 | { | 137 | { |
138 | char *delim = "?"; | 138 | char *delim = "?"; |
139 | 139 | ||
140 | if (ctx.cfg.virtual_root) { | 140 | if (ctx.cfg.virtual_root) { |
@@ -159,10 +159,10 @@ static void site_url(char *page, char *search, int ofs) | |||
159 | htmlf("ofs=%d", ofs); | 159 | htmlf("ofs=%d", ofs); |
160 | } | 160 | } |
161 | } | 161 | } |
162 | 162 | ||
163 | static void site_link(char *page, char *name, char *title, char *class, | 163 | static void site_link(const char *page, const char *name, const char *title, |
164 | char *search, int ofs) | 164 | const char *class, const char *search, int ofs) |
165 | { | 165 | { |
166 | html("<a"); | 166 | html("<a"); |
167 | if (title) { | 167 | if (title) { |
168 | html(" title='"); | 168 | html(" title='"); |
@@ -180,16 +180,16 @@ static void site_link(char *page, char *name, char *title, char *class, | |||
180 | html_txt(name); | 180 | html_txt(name); |
181 | html("</a>"); | 181 | html("</a>"); |
182 | } | 182 | } |
183 | 183 | ||
184 | void cgit_index_link(char *name, char *title, char *class, char *pattern, | 184 | void cgit_index_link(const char *name, const char *title, const char *class, |
185 | int ofs) | 185 | const char *pattern, int ofs) |
186 | { | 186 | { |
187 | site_link(NULL, name, title, class, pattern, ofs); | 187 | site_link(NULL, name, title, class, pattern, ofs); |
188 | } | 188 | } |
189 | 189 | ||
190 | static char *repolink(char *title, char *class, char *page, char *head, | 190 | static char *repolink(const char *title, const char *class, const char *page, |
191 | char *path) | 191 | const char *head, const char *path) |
192 | { | 192 | { |
193 | char *delim = "?"; | 193 | char *delim = "?"; |
194 | 194 | ||
195 | html("<a"); | 195 | html("<a"); |
@@ -239,10 +239,11 @@ static char *repolink(char *title, char *class, char *page, char *head, | |||
239 | } | 239 | } |
240 | return fmt("%s", delim); | 240 | return fmt("%s", delim); |
241 | } | 241 | } |
242 | 242 | ||
243 | static void reporevlink(char *page, char *name, char *title, char *class, | 243 | static void reporevlink(const char *page, const char *name, const char *title, |
244 | char *head, char *rev, char *path) | 244 | const char *class, const char *head, const char *rev, |
245 | const char *path) | ||
245 | { | 246 | { |
246 | char *delim; | 247 | char *delim; |
247 | 248 | ||
248 | delim = repolink(title, class, page, head, path); | 249 | delim = repolink(title, class, page, head, path); |
@@ -255,34 +256,35 @@ static void reporevlink(char *page, char *name, char *title, char *class, | |||
255 | html_txt(name); | 256 | html_txt(name); |
256 | html("</a>"); | 257 | html("</a>"); |
257 | } | 258 | } |
258 | 259 | ||
259 | void cgit_summary_link(char *name, char *title, char *class, char *head) | 260 | void cgit_summary_link(const char *name, const char *title, const char *class, |
261 | const char *head) | ||
260 | { | 262 | { |
261 | reporevlink(NULL, name, title, class, head, NULL, NULL); | 263 | reporevlink(NULL, name, title, class, head, NULL, NULL); |
262 | } | 264 | } |
263 | 265 | ||
264 | void cgit_tag_link(char *name, char *title, char *class, char *head, | 266 | void cgit_tag_link(const char *name, const char *title, const char *class, |
265 | char *rev) | 267 | const char *head, const char *rev) |
266 | { | 268 | { |
267 | reporevlink("tag", name, title, class, head, rev, NULL); | 269 | reporevlink("tag", name, title, class, head, rev, NULL); |
268 | } | 270 | } |
269 | 271 | ||
270 | void cgit_tree_link(char *name, char *title, char *class, char *head, | 272 | void cgit_tree_link(const char *name, const char *title, const char *class, |
271 | char *rev, char *path) | 273 | const char *head, const char *rev, const char *path) |
272 | { | 274 | { |
273 | reporevlink("tree", name, title, class, head, rev, path); | 275 | reporevlink("tree", name, title, class, head, rev, path); |
274 | } | 276 | } |
275 | 277 | ||
276 | void cgit_plain_link(char *name, char *title, char *class, char *head, | 278 | void cgit_plain_link(const char *name, const char *title, const char *class, |
277 | char *rev, char *path) | 279 | const char *head, const char *rev, const char *path) |
278 | { | 280 | { |
279 | reporevlink("plain", name, title, class, head, rev, path); | 281 | reporevlink("plain", name, title, class, head, rev, path); |
280 | } | 282 | } |
281 | 283 | ||
282 | void cgit_log_link(char *name, char *title, char *class, char *head, | 284 | void cgit_log_link(const char *name, const char *title, const char *class, |
283 | char *rev, char *path, int ofs, char *grep, char *pattern, | 285 | const char *head, const char *rev, const char *path, |
284 | int showmsg) | 286 | int ofs, const char *grep, const char *pattern, int showmsg) |
285 | { | 287 | { |
286 | char *delim; | 288 | char *delim; |
287 | 289 | ||
288 | delim = repolink(title, class, "log", head, path); | 290 | delim = repolink(title, class, "log", head, path); |
@@ -315,34 +317,65 @@ void cgit_log_link(char *name, char *title, char *class, char *head, | |||
315 | html_txt(name); | 317 | html_txt(name); |
316 | html("</a>"); | 318 | html("</a>"); |
317 | } | 319 | } |
318 | 320 | ||
319 | void cgit_commit_link(char *name, char *title, char *class, char *head, | 321 | void cgit_commit_link(char *name, const char *title, const char *class, |
320 | char *rev) | 322 | const char *head, const char *rev, const char *path, |
323 | int toggle_ssdiff) | ||
321 | { | 324 | { |
322 | if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { | 325 | if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { |
323 | name[ctx.cfg.max_msg_len] = '\0'; | 326 | name[ctx.cfg.max_msg_len] = '\0'; |
324 | name[ctx.cfg.max_msg_len - 1] = '.'; | 327 | name[ctx.cfg.max_msg_len - 1] = '.'; |
325 | name[ctx.cfg.max_msg_len - 2] = '.'; | 328 | name[ctx.cfg.max_msg_len - 2] = '.'; |
326 | name[ctx.cfg.max_msg_len - 3] = '.'; | 329 | name[ctx.cfg.max_msg_len - 3] = '.'; |
327 | } | 330 | } |
328 | reporevlink("commit", name, title, class, head, rev, NULL); | 331 | |
332 | char *delim; | ||
333 | |||
334 | delim = repolink(title, class, "commit", head, path); | ||
335 | if (rev && strcmp(rev, ctx.qry.head)) { | ||
336 | html(delim); | ||
337 | html("id="); | ||
338 | html_url_arg(rev); | ||
339 | delim = "&"; | ||
340 | } | ||
341 | if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) { | ||
342 | html(delim); | ||
343 | html("ss=1"); | ||
344 | delim = "&"; | ||
345 | } | ||
346 | if (ctx.qry.context > 0 && ctx.qry.context != 3) { | ||
347 | html(delim); | ||
348 | html("context="); | ||
349 | htmlf("%d", ctx.qry.context); | ||
350 | delim = "&"; | ||
351 | } | ||
352 | if (ctx.qry.ignorews) { | ||
353 | html(delim); | ||
354 | html("ignorews=1"); | ||
355 | delim = "&"; | ||
356 | } | ||
357 | html("'>"); | ||
358 | html_txt(name); | ||
359 | html("</a>"); | ||
329 | } | 360 | } |
330 | 361 | ||
331 | void cgit_refs_link(char *name, char *title, char *class, char *head, | 362 | void cgit_refs_link(const char *name, const char *title, const char *class, |
332 | char *rev, char *path) | 363 | const char *head, const char *rev, const char *path) |
333 | { | 364 | { |
334 | reporevlink("refs", name, title, class, head, rev, path); | 365 | reporevlink("refs", name, title, class, head, rev, path); |
335 | } | 366 | } |
336 | 367 | ||
337 | void cgit_snapshot_link(char *name, char *title, char *class, char *head, | 368 | void cgit_snapshot_link(const char *name, const char *title, const char *class, |
338 | char *rev, char *archivename) | 369 | const char *head, const char *rev, |
370 | const char *archivename) | ||
339 | { | 371 | { |
340 | reporevlink("snapshot", name, title, class, head, rev, archivename); | 372 | reporevlink("snapshot", name, title, class, head, rev, archivename); |
341 | } | 373 | } |
342 | 374 | ||
343 | void cgit_diff_link(char *name, char *title, char *class, char *head, | 375 | void cgit_diff_link(const char *name, const char *title, const char *class, |
344 | char *new_rev, char *old_rev, char *path) | 376 | const char *head, const char *new_rev, const char *old_rev, |
377 | const char *path, int toggle_ssdiff) | ||
345 | { | 378 | { |
346 | char *delim; | 379 | char *delim; |
347 | 380 | ||
348 | delim = repolink(title, class, "diff", head, path); | 381 | delim = repolink(title, class, "diff", head, path); |
@@ -355,26 +388,101 @@ void cgit_diff_link(char *name, char *title, char *class, char *head, | |||
355 | if (old_rev) { | 388 | if (old_rev) { |
356 | html(delim); | 389 | html(delim); |
357 | html("id2="); | 390 | html("id2="); |
358 | html_url_arg(old_rev); | 391 | html_url_arg(old_rev); |
392 | delim = "&"; | ||
393 | } | ||
394 | if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) { | ||
395 | html(delim); | ||
396 | html("ss=1"); | ||
397 | delim = "&"; | ||
398 | } | ||
399 | if (ctx.qry.context > 0 && ctx.qry.context != 3) { | ||
400 | html(delim); | ||
401 | html("context="); | ||
402 | htmlf("%d", ctx.qry.context); | ||
403 | delim = "&"; | ||
404 | } | ||
405 | if (ctx.qry.ignorews) { | ||
406 | html(delim); | ||
407 | html("ignorews=1"); | ||
408 | delim = "&"; | ||
359 | } | 409 | } |
360 | html("'>"); | 410 | html("'>"); |
361 | html_txt(name); | 411 | html_txt(name); |
362 | html("</a>"); | 412 | html("</a>"); |
363 | } | 413 | } |
364 | 414 | ||
365 | void cgit_patch_link(char *name, char *title, char *class, char *head, | 415 | void cgit_patch_link(const char *name, const char *title, const char *class, |
366 | char *rev) | 416 | const char *head, const char *rev, const char *path) |
367 | { | 417 | { |
368 | reporevlink("patch", name, title, class, head, rev, NULL); | 418 | reporevlink("patch", name, title, class, head, rev, path); |
369 | } | 419 | } |
370 | 420 | ||
371 | void cgit_stats_link(char *name, char *title, char *class, char *head, | 421 | void cgit_stats_link(const char *name, const char *title, const char *class, |
372 | char *path) | 422 | const char *head, const char *path) |
373 | { | 423 | { |
374 | reporevlink("stats", name, title, class, head, NULL, path); | 424 | reporevlink("stats", name, title, class, head, NULL, path); |
375 | } | 425 | } |
376 | 426 | ||
427 | void cgit_self_link(char *name, const char *title, const char *class, | ||
428 | struct cgit_context *ctx) | ||
429 | { | ||
430 | if (!strcmp(ctx->qry.page, "repolist")) | ||
431 | return cgit_index_link(name, title, class, ctx->qry.search, | ||
432 | ctx->qry.ofs); | ||
433 | else if (!strcmp(ctx->qry.page, "summary")) | ||
434 | return cgit_summary_link(name, title, class, ctx->qry.head); | ||
435 | else if (!strcmp(ctx->qry.page, "tag")) | ||
436 | return cgit_tag_link(name, title, class, ctx->qry.head, | ||
437 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL); | ||
438 | else if (!strcmp(ctx->qry.page, "tree")) | ||
439 | return cgit_tree_link(name, title, class, ctx->qry.head, | ||
440 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL, | ||
441 | ctx->qry.path); | ||
442 | else if (!strcmp(ctx->qry.page, "plain")) | ||
443 | return cgit_plain_link(name, title, class, ctx->qry.head, | ||
444 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL, | ||
445 | ctx->qry.path); | ||
446 | else if (!strcmp(ctx->qry.page, "log")) | ||
447 | return cgit_log_link(name, title, class, ctx->qry.head, | ||
448 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL, | ||
449 | ctx->qry.path, ctx->qry.ofs, | ||
450 | ctx->qry.grep, ctx->qry.search, | ||
451 | ctx->qry.showmsg); | ||
452 | else if (!strcmp(ctx->qry.page, "commit")) | ||
453 | return cgit_commit_link(name, title, class, ctx->qry.head, | ||
454 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL, | ||
455 | ctx->qry.path, 0); | ||
456 | else if (!strcmp(ctx->qry.page, "patch")) | ||
457 | return cgit_patch_link(name, title, class, ctx->qry.head, | ||
458 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL, | ||
459 | ctx->qry.path); | ||
460 | else if (!strcmp(ctx->qry.page, "refs")) | ||
461 | return cgit_refs_link(name, title, class, ctx->qry.head, | ||
462 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL, | ||
463 | ctx->qry.path); | ||
464 | else if (!strcmp(ctx->qry.page, "snapshot")) | ||
465 | return cgit_snapshot_link(name, title, class, ctx->qry.head, | ||
466 | ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL, | ||
467 | ctx->qry.path); | ||
468 | else if (!strcmp(ctx->qry.page, "diff")) | ||
469 | return cgit_diff_link(name, title, class, ctx->qry.head, | ||
470 | ctx->qry.sha1, ctx->qry.sha2, | ||
471 | ctx->qry.path, 0); | ||
472 | else if (!strcmp(ctx->qry.page, "stats")) | ||
473 | return cgit_stats_link(name, title, class, ctx->qry.head, | ||
474 | ctx->qry.path); | ||
475 | |||
476 | /* Don't known how to make link for this page */ | ||
477 | repolink(title, class, ctx->qry.page, ctx->qry.head, ctx->qry.path); | ||
478 | html("><!-- cgit_self_link() doesn't know how to make link for page '"); | ||
479 | html_txt(ctx->qry.page); | ||
480 | html("' -->"); | ||
481 | html_txt(name); | ||
482 | html("</a>"); | ||
483 | } | ||
484 | |||
377 | void cgit_object_link(struct object *obj) | 485 | void cgit_object_link(struct object *obj) |
378 | { | 486 | { |
379 | char *page, *shortrev, *fullrev, *name; | 487 | char *page, *shortrev, *fullrev, *name; |
380 | 488 | ||
@@ -382,9 +490,9 @@ void cgit_object_link(struct object *obj) | |||
382 | shortrev = xstrdup(fullrev); | 490 | shortrev = xstrdup(fullrev); |
383 | shortrev[10] = '\0'; | 491 | shortrev[10] = '\0'; |
384 | if (obj->type == OBJ_COMMIT) { | 492 | if (obj->type == OBJ_COMMIT) { |
385 | cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL, | 493 | cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL, |
386 | ctx.qry.head, fullrev); | 494 | ctx.qry.head, fullrev, NULL, 0); |
387 | return; | 495 | return; |
388 | } else if (obj->type == OBJ_TREE) | 496 | } else if (obj->type == OBJ_TREE) |
389 | page = "tree"; | 497 | page = "tree"; |
390 | else if (obj->type == OBJ_TAG) | 498 | else if (obj->type == OBJ_TAG) |
@@ -394,9 +502,9 @@ void cgit_object_link(struct object *obj) | |||
394 | name = fmt("%s %s...", typename(obj->type), shortrev); | 502 | name = fmt("%s %s...", typename(obj->type), shortrev); |
395 | reporevlink(page, name, NULL, NULL, ctx.qry.head, fullrev, NULL); | 503 | reporevlink(page, name, NULL, NULL, ctx.qry.head, fullrev, NULL); |
396 | } | 504 | } |
397 | 505 | ||
398 | void cgit_print_date(time_t secs, char *format, int local_time) | 506 | void cgit_print_date(time_t secs, const char *format, int local_time) |
399 | { | 507 | { |
400 | char buf[64]; | 508 | char buf[64]; |
401 | struct tm *time; | 509 | struct tm *time; |
402 | 510 | ||
@@ -409,9 +517,9 @@ void cgit_print_date(time_t secs, char *format, int local_time) | |||
409 | strftime(buf, sizeof(buf)-1, format, time); | 517 | strftime(buf, sizeof(buf)-1, format, time); |
410 | html_txt(buf); | 518 | html_txt(buf); |
411 | } | 519 | } |
412 | 520 | ||
413 | void cgit_print_age(time_t t, time_t max_relative, char *format) | 521 | void cgit_print_age(time_t t, time_t max_relative, const char *format) |
414 | { | 522 | { |
415 | time_t now, secs; | 523 | time_t now, secs; |
416 | 524 | ||
417 | if (!t) | 525 | if (!t) |
@@ -508,9 +616,9 @@ void cgit_print_docstart(struct cgit_context *ctx) | |||
508 | if (host && ctx->repo) { | 616 | if (host && ctx->repo) { |
509 | html("<link rel='alternate' title='Atom feed' href='"); | 617 | html("<link rel='alternate' title='Atom feed' href='"); |
510 | html(cgit_httpscheme()); | 618 | html(cgit_httpscheme()); |
511 | html_attr(cgit_hosturl()); | 619 | html_attr(cgit_hosturl()); |
512 | html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path, | 620 | html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.vpath, |
513 | fmt("h=%s", ctx->qry.head))); | 621 | fmt("h=%s", ctx->qry.head))); |
514 | html("' type='application/atom+xml'/>\n"); | 622 | html("' type='application/atom+xml'/>\n"); |
515 | } | 623 | } |
516 | if (ctx->cfg.head_include) | 624 | if (ctx->cfg.head_include) |
@@ -588,16 +696,17 @@ int print_archive_ref(const char *refname, const unsigned char *sha1, | |||
588 | html_link_close(); | 696 | html_link_close(); |
589 | return 0; | 697 | return 0; |
590 | } | 698 | } |
591 | 699 | ||
592 | void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page) | 700 | void cgit_add_hidden_formfields(int incl_head, int incl_search, |
701 | const char *page) | ||
593 | { | 702 | { |
594 | char *url; | 703 | char *url; |
595 | 704 | ||
596 | if (!ctx.cfg.virtual_root) { | 705 | if (!ctx.cfg.virtual_root) { |
597 | url = fmt("%s/%s", ctx.qry.repo, page); | 706 | url = fmt("%s/%s", ctx.qry.repo, page); |
598 | if (ctx.qry.path) | 707 | if (ctx.qry.vpath) |
599 | url = fmt("%s/%s", url, ctx.qry.path); | 708 | url = fmt("%s/%s", url, ctx.qry.vpath); |
600 | html_hidden("url", url); | 709 | html_hidden("url", url); |
601 | } | 710 | } |
602 | 711 | ||
603 | if (incl_head && ctx.qry.head && ctx.repo->defbranch && | 712 | if (incl_head && ctx.qry.head && ctx.repo->defbranch && |
@@ -618,28 +727,57 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page) | |||
618 | html_hidden("q", ctx.qry.search); | 727 | html_hidden("q", ctx.qry.search); |
619 | } | 728 | } |
620 | } | 729 | } |
621 | 730 | ||
622 | const char *fallback_cmd = "repolist"; | 731 | static const char *hc(struct cgit_context *ctx, const char *page) |
732 | { | ||
733 | return strcmp(ctx->qry.page, page) ? NULL : "active"; | ||
734 | } | ||
623 | 735 | ||
624 | char *hc(struct cgit_cmd *cmd, const char *page) | 736 | static void cgit_print_path_crumbs(struct cgit_context *ctx, char *path) |
625 | { | 737 | { |
626 | return (strcmp(cmd ? cmd->name : fallback_cmd, page) ? NULL : "active"); | 738 | char *old_path = ctx->qry.path; |
739 | char *p = path, *q, *end = path + strlen(path); | ||
740 | |||
741 | ctx->qry.path = NULL; | ||
742 | cgit_self_link("root", NULL, NULL, ctx); | ||
743 | ctx->qry.path = p = path; | ||
744 | while (p < end) { | ||
745 | if (!(q = strchr(p, '/'))) | ||
746 | q = end; | ||
747 | *q = '\0'; | ||
748 | html_txt("/"); | ||
749 | cgit_self_link(p, NULL, NULL, ctx); | ||
750 | if (q < end) | ||
751 | *q = '/'; | ||
752 | p = q + 1; | ||
753 | } | ||
754 | ctx->qry.path = old_path; | ||
627 | } | 755 | } |
628 | 756 | ||
629 | static void print_header(struct cgit_context *ctx) | 757 | static void print_header(struct cgit_context *ctx) |
630 | { | 758 | { |
759 | char *logo = NULL, *logo_link = NULL; | ||
760 | |||
631 | html("<table id='header'>\n"); | 761 | html("<table id='header'>\n"); |
632 | html("<tr>\n"); | 762 | html("<tr>\n"); |
633 | 763 | ||
634 | if (ctx->cfg.logo && ctx->cfg.logo[0] != 0) { | 764 | if (ctx->repo && ctx->repo->logo && *ctx->repo->logo) |
765 | logo = ctx->repo->logo; | ||
766 | else | ||
767 | logo = ctx->cfg.logo; | ||
768 | if (ctx->repo && ctx->repo->logo_link && *ctx->repo->logo_link) | ||
769 | logo_link = ctx->repo->logo_link; | ||
770 | else | ||
771 | logo_link = ctx->cfg.logo_link; | ||
772 | if (logo && *logo) { | ||
635 | html("<td class='logo' rowspan='2'><a href='"); | 773 | html("<td class='logo' rowspan='2'><a href='"); |
636 | if (ctx->cfg.logo_link) | 774 | if (logo_link && *logo_link) |
637 | html_attr(ctx->cfg.logo_link); | 775 | html_attr(logo_link); |
638 | else | 776 | else |
639 | html_attr(cgit_rooturl()); | 777 | html_attr(cgit_rooturl()); |
640 | html("'><img src='"); | 778 | html("'><img src='"); |
641 | html_attr(ctx->cfg.logo); | 779 | html_attr(logo); |
642 | html("' alt='cgit logo'/></a></td>\n"); | 780 | html("' alt='cgit logo'/></a></td>\n"); |
643 | } | 781 | } |
644 | 782 | ||
645 | html("<td class='main'>"); | 783 | html("<td class='main'>"); |
@@ -674,59 +812,56 @@ static void print_header(struct cgit_context *ctx) | |||
674 | } | 812 | } |
675 | 813 | ||
676 | void cgit_print_pageheader(struct cgit_context *ctx) | 814 | void cgit_print_pageheader(struct cgit_context *ctx) |
677 | { | 815 | { |
678 | struct cgit_cmd *cmd = cgit_get_cmd(ctx); | ||
679 | |||
680 | if (!cmd && ctx->repo) | ||
681 | fallback_cmd = "summary"; | ||
682 | |||
683 | html("<div id='cgit'>"); | 816 | html("<div id='cgit'>"); |
684 | if (!ctx->cfg.noheader) | 817 | if (!ctx->cfg.noheader) |
685 | print_header(ctx); | 818 | print_header(ctx); |
686 | 819 | ||
687 | html("<table class='tabs'><tr><td>\n"); | 820 | html("<table class='tabs'><tr><td>\n"); |
688 | if (ctx->repo) { | 821 | if (ctx->repo) { |
689 | cgit_summary_link("summary", NULL, hc(cmd, "summary"), | 822 | cgit_summary_link("summary", NULL, hc(ctx, "summary"), |
690 | ctx->qry.head); | 823 | ctx->qry.head); |
691 | cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head, | 824 | cgit_refs_link("refs", NULL, hc(ctx, "refs"), ctx->qry.head, |
692 | ctx->qry.sha1, NULL); | 825 | ctx->qry.sha1, NULL); |
693 | cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head, | 826 | cgit_log_link("log", NULL, hc(ctx, "log"), ctx->qry.head, |
694 | NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg); | 827 | NULL, ctx->qry.vpath, 0, NULL, NULL, |
695 | cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head, | 828 | ctx->qry.showmsg); |
696 | ctx->qry.sha1, NULL); | 829 | cgit_tree_link("tree", NULL, hc(ctx, "tree"), ctx->qry.head, |
697 | cgit_commit_link("commit", NULL, hc(cmd, "commit"), | 830 | ctx->qry.sha1, ctx->qry.vpath); |
698 | ctx->qry.head, ctx->qry.sha1); | 831 | cgit_commit_link("commit", NULL, hc(ctx, "commit"), |
699 | cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head, | 832 | ctx->qry.head, ctx->qry.sha1, ctx->qry.vpath, 0); |
700 | ctx->qry.sha1, ctx->qry.sha2, NULL); | 833 | cgit_diff_link("diff", NULL, hc(ctx, "diff"), ctx->qry.head, |
834 | ctx->qry.sha1, ctx->qry.sha2, ctx->qry.vpath, 0); | ||
701 | if (ctx->repo->max_stats) | 835 | if (ctx->repo->max_stats) |
702 | cgit_stats_link("stats", NULL, hc(cmd, "stats"), | 836 | cgit_stats_link("stats", NULL, hc(ctx, "stats"), |
703 | ctx->qry.head, NULL); | 837 | ctx->qry.head, ctx->qry.vpath); |
704 | if (ctx->repo->readme) | 838 | if (ctx->repo->readme) |
705 | reporevlink("about", "about", NULL, | 839 | reporevlink("about", "about", NULL, |
706 | hc(cmd, "about"), ctx->qry.head, NULL, | 840 | hc(ctx, "about"), ctx->qry.head, NULL, |
707 | NULL); | 841 | NULL); |
708 | html("</td><td class='form'>"); | 842 | html("</td><td class='form'>"); |
709 | html("<form class='right' method='get' action='"); | 843 | html("<form class='right' method='get' action='"); |
710 | if (ctx->cfg.virtual_root) | 844 | if (ctx->cfg.virtual_root) |
711 | html_url_path(cgit_fileurl(ctx->qry.repo, "log", | 845 | html_url_path(cgit_fileurl(ctx->qry.repo, "log", |
712 | ctx->qry.path, NULL)); | 846 | ctx->qry.vpath, NULL)); |
713 | html("'>\n"); | 847 | html("'>\n"); |
714 | cgit_add_hidden_formfields(1, 0, "log"); | 848 | cgit_add_hidden_formfields(1, 0, "log"); |
715 | html("<select name='qt'>\n"); | 849 | html("<select name='qt'>\n"); |
716 | html_option("grep", "log msg", ctx->qry.grep); | 850 | html_option("grep", "log msg", ctx->qry.grep); |
717 | html_option("author", "author", ctx->qry.grep); | 851 | html_option("author", "author", ctx->qry.grep); |
718 | html_option("committer", "committer", ctx->qry.grep); | 852 | html_option("committer", "committer", ctx->qry.grep); |
853 | html_option("range", "range", ctx->qry.grep); | ||
719 | html("</select>\n"); | 854 | html("</select>\n"); |
720 | html("<input class='txt' type='text' size='10' name='q' value='"); | 855 | html("<input class='txt' type='text' size='10' name='q' value='"); |
721 | html_attr(ctx->qry.search); | 856 | html_attr(ctx->qry.search); |
722 | html("'/>\n"); | 857 | html("'/>\n"); |
723 | html("<input type='submit' value='search'/>\n"); | 858 | html("<input type='submit' value='search'/>\n"); |
724 | html("</form>\n"); | 859 | html("</form>\n"); |
725 | } else { | 860 | } else { |
726 | site_link(NULL, "index", NULL, hc(cmd, "repolist"), NULL, 0); | 861 | site_link(NULL, "index", NULL, hc(ctx, "repolist"), NULL, 0); |
727 | if (ctx->cfg.root_readme) | 862 | if (ctx->cfg.root_readme) |
728 | site_link("about", "about", NULL, hc(cmd, "about"), | 863 | site_link("about", "about", NULL, hc(ctx, "about"), |
729 | NULL, 0); | 864 | NULL, 0); |
730 | html("</td><td class='form'>"); | 865 | html("</td><td class='form'>"); |
731 | html("<form method='get' action='"); | 866 | html("<form method='get' action='"); |
732 | html_attr(cgit_rooturl()); | 867 | html_attr(cgit_rooturl()); |
@@ -737,8 +872,14 @@ void cgit_print_pageheader(struct cgit_context *ctx) | |||
737 | html("<input type='submit' value='search'/>\n"); | 872 | html("<input type='submit' value='search'/>\n"); |
738 | html("</form>"); | 873 | html("</form>"); |
739 | } | 874 | } |
740 | html("</td></tr></table>\n"); | 875 | html("</td></tr></table>\n"); |
876 | if (ctx->qry.vpath) { | ||
877 | html("<div class='path'>"); | ||
878 | html("path: "); | ||
879 | cgit_print_path_crumbs(ctx, ctx->qry.vpath); | ||
880 | html("</div>"); | ||
881 | } | ||
741 | html("<div class='content'>"); | 882 | html("<div class='content'>"); |
742 | } | 883 | } |
743 | 884 | ||
744 | void cgit_print_filemode(unsigned short mode) | 885 | void cgit_print_filemode(unsigned short mode) |
@@ -759,15 +900,20 @@ void cgit_print_filemode(unsigned short mode) | |||
759 | void cgit_print_snapshot_links(const char *repo, const char *head, | 900 | void cgit_print_snapshot_links(const char *repo, const char *head, |
760 | const char *hex, int snapshots) | 901 | const char *hex, int snapshots) |
761 | { | 902 | { |
762 | const struct cgit_snapshot_format* f; | 903 | const struct cgit_snapshot_format* f; |
904 | char *prefix; | ||
763 | char *filename; | 905 | char *filename; |
906 | unsigned char sha1[20]; | ||
764 | 907 | ||
908 | if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 && | ||
909 | (hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1])) | ||
910 | hex++; | ||
911 | prefix = xstrdup(fmt("%s-%s", cgit_repobasename(repo), hex)); | ||
765 | for (f = cgit_snapshot_formats; f->suffix; f++) { | 912 | for (f = cgit_snapshot_formats; f->suffix; f++) { |
766 | if (!(snapshots & f->bit)) | 913 | if (!(snapshots & f->bit)) |
767 | continue; | 914 | continue; |
768 | filename = fmt("%s-%s%s", cgit_repobasename(repo), hex, | 915 | filename = fmt("%s%s", prefix, f->suffix); |
769 | f->suffix); | ||
770 | cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename); | 916 | cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename); |
771 | html("<br/>"); | 917 | html("<br/>"); |
772 | } | 918 | } |
773 | } | 919 | } |