commit - c2fe54818e16760dcc5ad3ffa5042f878be1a736
commit + 55e464000af0f8e2e4074d6cb565da76f81fe698
blob - e130603106d591b4bda911dc9ed76dfa7fbfffbe (mode 644)
blob + /dev/null
--- gotweb/TODO
+++ /dev/null
-TODO
-
-- Add Prev/Next to shortlogs/logs that have more entries than
- got_max_commits_display
blob - 509390f5ba90d758227633a69d2955bf03b31c83
blob + d682a07e742bfd803a29726b3d532689d7855d99
--- gotweb/gotweb.c
+++ gotweb/gotweb.c
const char *repo_name;
char *repo_path;
char *commit_id;
+ char *next_id;
+ char *next_prev_id;
+ char *prev_id;
+ char *prev_prev_id;
const char *repo_file;
char *repo_folder;
const char *headref;
KEY_HEADREF,
KEY_PAGE,
KEY_PATH,
+ KEY_PREV_ID,
+ KEY_PREV_PREV_ID,
KEY__ZMAX
};
{ kvalid_stringne, "headref" },
{ kvalid_int, "page" },
{ kvalid_stringne, "path" },
+ { kvalid_stringne, "prev" },
+ { kvalid_stringne, "prev_prev" },
};
static struct gw_header *gw_init_header(void);
{
const struct got_error *error = NULL;
struct gw_header *header = NULL, *n_header = NULL;
- char *age = NULL;
- char *href_diff = NULL, *href_blob = NULL;
+ char *age = NULL, *href_diff = NULL, *href_blob = NULL;
+ char *href_prev = NULL, *href_next = NULL;
enum kcgi_err kerr = KCGI_OK;
if ((header = gw_init_header()) == NULL)
free(age);
age = NULL;
+ }
+
+ if (gw_trans->next_id || gw_trans->page > 0) {
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
+ KATTR_ID, "np_wrapper", KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
+ KATTR_ID, "nav_prev", KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
}
+
+ if (gw_trans->page > 0) {
+ if (asprintf(&href_prev,
+ "?path=%s&page=%d&action=commits&commit=%s&prev=%s",
+ gw_trans->repo_name, gw_trans->page - 1,
+ gw_trans->prev_id ? gw_trans->prev_id : "",
+ gw_trans->prev_prev_id ?
+ gw_trans->prev_prev_id : "") == -1) {
+ error = got_error_from_errno("asprintf");
+ goto done;
+ }
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
+ KATTR_HREF, href_prev, KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_puts(gw_trans->gw_html_req, "Previous");
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
+ if (kerr != KCGI_OK)
+ goto done;
+ }
+
+ if (gw_trans->next_id || gw_trans->page > 0) {
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
+ if (kerr != KCGI_OK)
+ return gw_kcgi_error(kerr);
+ }
+
+ if (gw_trans->next_id) {
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
+ KATTR_ID, "nav_next", KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ if (asprintf(&href_next,
+ "?path=%s&page=%d&action=commits" \
+ "&commit=%s&prev=%s&prev_prev=%s",
+ gw_trans->repo_name, gw_trans->page + 1,
+ gw_trans->next_id,
+ gw_trans->next_prev_id ? gw_trans->next_prev_id : "",
+ gw_trans->prev_id ?
+ gw_trans->prev_id : "") == -1) {
+ error = got_error_from_errno("calloc");
+ goto done;
+ }
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
+ KATTR_HREF, href_next, KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_puts(gw_trans->gw_html_req, "Next");
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
+ if (kerr != KCGI_OK)
+ goto done;
+ }
+
+ if (gw_trans->next_id || gw_trans->page > 0) {
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
+ if (kerr != KCGI_OK)
+ goto done;
+ }
done:
gw_free_header(header);
TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry)
gw_free_header(n_header);
free(age);
+ free(href_next);
+ free(href_prev);
free(href_diff);
free(href_blob);
if (error == NULL && kerr != KCGI_OK)
{
const struct got_error *error = NULL;
struct gw_header *header = NULL, *n_header = NULL;
- char *age = NULL;
- char *href_diff = NULL, *href_blob = NULL;
+ char *age = NULL, *href_diff = NULL, *href_blob = NULL;
+ char *href_prev = NULL, *href_next = NULL;
char *newline, *smallerthan;
enum kcgi_err kerr = KCGI_OK;
href_diff = NULL;
free(href_blob);
href_blob = NULL;
+ }
+
+ if (gw_trans->next_id || gw_trans->page > 0) {
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
+ KATTR_ID, "np_wrapper", KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
+ KATTR_ID, "nav_prev", KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ }
+
+ if (gw_trans->page > 0) {
+ if (asprintf(&href_prev,
+ "?path=%s&page=%d&action=briefs&commit=%s&prev=%s",
+ gw_trans->repo_name, gw_trans->page - 1,
+ gw_trans->prev_id ? gw_trans->prev_id : "",
+ gw_trans->prev_prev_id ?
+ gw_trans->prev_prev_id : "") == -1) {
+ error = got_error_from_errno("asprintf");
+ goto done;
+ }
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
+ KATTR_HREF, href_prev, KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_puts(gw_trans->gw_html_req, "Previous");
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
+ if (kerr != KCGI_OK)
+ goto done;
}
+
+ if (gw_trans->next_id || gw_trans->page > 0) {
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
+ if (kerr != KCGI_OK)
+ return gw_kcgi_error(kerr);
+ }
+
+ if (gw_trans->next_id) {
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
+ KATTR_ID, "nav_next", KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ if (asprintf(&href_next,
+ "?path=%s&page=%d&action=briefs" \
+ "&commit=%s&prev=%s&prev_prev=%s",
+ gw_trans->repo_name, gw_trans->page + 1,
+ gw_trans->next_id,
+ gw_trans->next_prev_id ? gw_trans->next_prev_id : "",
+ gw_trans->prev_id ?
+ gw_trans->prev_id : "") == -1) {
+ error = got_error_from_errno("calloc");
+ goto done;
+ }
+ kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
+ KATTR_HREF, href_next, KATTR__MAX);
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_puts(gw_trans->gw_html_req, "Next");
+ if (kerr != KCGI_OK)
+ goto done;
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
+ if (kerr != KCGI_OK)
+ goto done;
+ }
+
+ if (gw_trans->next_id || gw_trans->page > 0) {
+ kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
+ if (kerr != KCGI_OK)
+ goto done;
+ }
done:
gw_free_header(header);
TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry)
gw_free_header(n_header);
free(age);
+ free(href_next);
+ free(href_prev);
free(href_diff);
free(href_blob);
if (error == NULL && kerr != KCGI_OK)
if ((p = gw_trans->gw_req->fieldmap[KEY_FOLDER])) {
if (asprintf(&gw_trans->repo_folder, "%s",
+ p->parsed.s) == -1)
+ return got_error_from_errno("asprintf");
+ }
+
+ if ((p = gw_trans->gw_req->fieldmap[KEY_PREV_ID])) {
+ if (asprintf(&gw_trans->prev_id, "%s",
+ p->parsed.s) == -1)
+ return got_error_from_errno("asprintf");
+ }
+
+ if ((p = gw_trans->gw_req->fieldmap[KEY_PREV_PREV_ID])) {
+ if (asprintf(&gw_trans->prev_prev_id, "%s",
p->parsed.s) == -1)
return got_error_from_errno("asprintf");
}
const struct got_error *error = NULL;
struct got_commit_graph *graph = NULL;
struct got_commit_object *commit = NULL;
+ int chk_next = 0, chk_multi = 0, prev_set = 0;
error = got_commit_graph_open(&graph, header->path, 0);
if (error)
error = got_object_open_as_commit(&commit, gw_trans->repo, id);
if (error)
goto done;
- if (limit == 1) {
+ if (limit == 1 && chk_multi == 0) {
error = gw_get_commit(gw_trans, header, commit, id);
if (error)
goto done;
} else {
+ chk_multi = 1;
struct gw_header *n_header = NULL;
if ((n_header = gw_init_header()) == NULL) {
error = got_error_from_errno("malloc");
if (error)
goto done;
got_ref_list_free(&n_header->refs);
+
+ /*
+ * we have a commit_id now, so copy it to next_prev_id
+ * for navigation through gw_briefs and gw_commits
+ */
+ if (gw_trans->next_prev_id == NULL && prev_set == 0 &&
+ (gw_trans->action == GW_BRIEFS ||
+ gw_trans->action == GW_COMMITS ||
+ gw_trans->action == GW_SUMMARY)) {
+ prev_set = 1;
+ gw_trans->next_prev_id =
+ strdup(n_header->commit_id);
+ if (gw_trans->next_prev_id == NULL) {
+ error = got_error_from_errno("strdup");
+ goto done;
+ }
+ }
+
+ /*
+ * check for one more commit before breaking,
+ * so we know whether to navicate through gw_briefs
+ * gw_commits and gw_summary
+ */
+ if (chk_next && (gw_trans->action == GW_BRIEFS||
+ gw_trans->action == GW_COMMITS ||
+ gw_trans->action == GW_SUMMARY)) {
+ gw_trans->next_id = strdup(n_header->commit_id);
+ if (gw_trans->next_id == NULL)
+ error = got_error_from_errno("strdup");
+ goto done;
+ }
+
TAILQ_INSERT_TAIL(&gw_trans->gw_headers, n_header,
entry);
}
- if (error || (limit && --limit == 0))
- break;
+ if (error || (limit && --limit == 0)) {
+ if (chk_multi == 0)
+ break;
+ chk_next = 1;
+ }
}
done:
if (commit != NULL)
return error;
} else {
struct got_reference *ref;
+
error = got_ref_open(&ref, gw_trans->repo,
gw_trans->commit_id, 0);
if (error == NULL) {
gw_trans->repos_total = 0;
gw_trans->repo_path = NULL;
gw_trans->commit_id = NULL;
+ gw_trans->next_id = NULL;
+ gw_trans->next_prev_id = NULL;
+ gw_trans->prev_id = NULL;
+ gw_trans->prev_prev_id = NULL;
gw_trans->headref = GOT_REF_HEAD;
gw_trans->mime = KMIME_TEXT_HTML;
gw_trans->gw_tmpl->key = gw_templs;
free(gw_trans->gw_conf->got_logo_url);
free(gw_trans->gw_conf);
free(gw_trans->commit_id);
+ free(gw_trans->next_id);
+ free(gw_trans->next_prev_id);
+ free(gw_trans->prev_id);
+ free(gw_trans->prev_prev_id);
free(gw_trans->repo_path);
if (gw_trans->repo)
got_repo_close(gw_trans->repo);