author | Lars Hjemli <hjemli@gmail.com> | 2007-10-30 09:47:38 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2007-10-30 12:38:34 (UTC) |
commit | 0c8e184e9cbf4d3a1e907de9125f6d8210c169d6 (patch) (unidiff) | |
tree | 2e82baf582b7ba0b34f498e1e7494800070067f9 | |
parent | 10ac7ad1f30f914dc5ff36ba3651ef6dca11aaf7 (diff) | |
download | cgit-0c8e184e9cbf4d3a1e907de9125f6d8210c169d6.zip cgit-0c8e184e9cbf4d3a1e907de9125f6d8210c169d6.tar.gz cgit-0c8e184e9cbf4d3a1e907de9125f6d8210c169d6.tar.bz2 |
Change the cgit layout
This modifies and hopefully improves the layout of all cgit pages:
* Remove the header from all pages and replace it with a sidebar;
most pages have sufficient width but many needs more height.
* Add a dropdown-box to switch between branches, using a one-liner
javascript to reload the current page in context of the selected branch.
* Include refs found below refs/archives in the sidebar, appearing as a
set of menuitems below a 'download' heading.
* Include the brand new cgit logo
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cgit.css | 149 | ||||
-rw-r--r-- | cgit.h | 2 | ||||
-rw-r--r-- | cgit.png | bin | 0 -> 3790 bytes | |||
-rw-r--r-- | cgitrc | 9 | ||||
-rw-r--r-- | shared.c | 31 | ||||
-rw-r--r-- | ui-shared.c | 172 | ||||
-rw-r--r-- | ui-summary.c | 65 |
7 files changed, 231 insertions, 197 deletions
@@ -1,24 +1,25 @@ | |||
1 | body { | ||
2 | font-family: arial, sans-serif; | ||
3 | font-size: 11pt; | ||
4 | color: black; | ||
5 | background: white; | ||
6 | } | ||
7 | |||
8 | body, table { | 1 | body, table { |
9 | padding: 0em; | 2 | padding: 0em; |
10 | margin: 0em; | 3 | margin: 0em; |
11 | } | 4 | } |
12 | 5 | ||
6 | body { | ||
7 | font-family: sans; | ||
8 | font-size: 10pt; | ||
9 | color: #333; | ||
10 | background: white; | ||
11 | padding-left: 4px; | ||
12 | } | ||
13 | |||
13 | table { | 14 | table { |
14 | border-collapse: collapse; | 15 | border-collapse: collapse; |
15 | } | 16 | } |
16 | 17 | ||
17 | h2 { | 18 | h2 { |
18 | font-size: 120%; | 19 | font-size: 120%; |
19 | font-weight: bold; | 20 | font-weight: bold; |
20 | margin-top: 0em; | 21 | margin-top: 0em; |
21 | margin-bottom: 0.25em; | 22 | margin-bottom: 0.25em; |
22 | } | 23 | } |
23 | 24 | ||
24 | h3 { | 25 | h3 { |
@@ -26,180 +27,157 @@ h3 { | |||
26 | font-size: 100%; | 27 | font-size: 100%; |
27 | font-weight: normal; | 28 | font-weight: normal; |
28 | } | 29 | } |
29 | 30 | ||
30 | h4 { | 31 | h4 { |
31 | margin-top: 1.5em; | 32 | margin-top: 1.5em; |
32 | margin-bottom: 0.1em; | 33 | margin-bottom: 0.1em; |
33 | font-size: 100%; | 34 | font-size: 100%; |
34 | font-weight: bold; | 35 | font-weight: bold; |
35 | } | 36 | } |
36 | 37 | ||
37 | a { | 38 | a { |
38 | color: blue; | 39 | color: #600; |
39 | text-decoration: none; | 40 | text-decoration: none; |
40 | } | 41 | } |
41 | 42 | ||
42 | a:hover { | 43 | a:hover { |
43 | text-decoration: underline; | 44 | background-color: #ddd; |
45 | text-decoration: none; | ||
44 | } | 46 | } |
45 | 47 | ||
46 | table.list { | 48 | table.list { |
47 | border: none; | 49 | border: none; |
48 | border-collapse: collapse; | 50 | border-collapse: collapse; |
49 | } | 51 | } |
50 | 52 | ||
51 | table.list tr { | 53 | table.list tr { |
52 | background: white; | 54 | background: white; |
53 | } | 55 | } |
54 | 56 | ||
55 | table.list tr:hover { | 57 | table.list tr:hover { |
56 | background: #eee; | 58 | background: #f8f8f8; |
57 | } | 59 | } |
58 | 60 | ||
59 | table.list tr.nohover:hover { | 61 | table.list tr.nohover:hover { |
60 | background: white; | 62 | background: white; |
61 | } | 63 | } |
62 | 64 | ||
63 | table.list th { | 65 | table.list th { |
64 | font-weight: bold; | 66 | font-weight: bold; |
65 | border-bottom: solid 1px #777; | 67 | border-bottom: solid 1px #777; |
66 | padding: 0.1em 0.5em 0.1em 0.5em; | 68 | padding: 0.1em 0.5em 0.1em 0.5em; |
67 | vertical-align: baseline; | 69 | vertical-align: baseline; |
68 | } | 70 | } |
69 | 71 | ||
70 | table.list td { | 72 | table.list td { |
71 | border: none; | 73 | border: none; |
72 | padding: 0.1em 0.5em 0.1em 0.5em; | 74 | padding: 0.1em 0.5em 0.1em 0.5em; |
73 | } | 75 | } |
74 | 76 | ||
75 | img { | 77 | img { |
76 | border: none; | 78 | border: none; |
77 | } | 79 | } |
78 | 80 | ||
79 | table#layout { | 81 | div#sidebar { |
80 | width: 100%; | 82 | vertical-align: top; |
81 | border-collapse: collapse; | 83 | width: 162px; |
82 | margin: 0px; | 84 | padding: 0px 0px 0px 0px; |
83 | } | 85 | margin: 4px; |
84 | 86 | float: left; | |
85 | td#header, td#logo { | ||
86 | color: #666; | ||
87 | background-color: #ddd; | ||
88 | border-bottom: solid 1px #000; | ||
89 | } | ||
90 | |||
91 | td#header { | ||
92 | font-size: 150%; | ||
93 | font-weight: bold; | ||
94 | padding: 0.2em 0.5em; | ||
95 | vertical-align: text-bottom; | ||
96 | } | ||
97 | |||
98 | td#header a { | ||
99 | color: #666; | ||
100 | } | ||
101 | |||
102 | td#header a:hover { | ||
103 | text-decoration: underline; | ||
104 | } | 87 | } |
105 | 88 | ||
106 | td#logo { | 89 | div#logo { |
107 | text-align: right; | 90 | margin: 0px; |
108 | vertical-align: middle; | 91 | padding: 4px 0px 4px 0px; |
109 | padding-right: 0.5em; | 92 | text-align: center; |
93 | background-color: #ccc; | ||
94 | border-top: solid 1px #eee; | ||
95 | border-left: solid 1px #eee; | ||
96 | border-right: solid 1px #aaa; | ||
97 | border-bottom: solid 1px #aaa; | ||
110 | } | 98 | } |
111 | 99 | ||
112 | td#crumb, td#search { | 100 | div#sidebar div.infobox { |
113 | color: #ccc; | 101 | margin: 0px 0px 0pax 0px; |
114 | border-top: solid 3px #555; | 102 | padding: 0.5em; |
115 | background-color: #666; | 103 | text-align: left; |
116 | border-bottom: solid 1px #333; | 104 | background-color: #ccc; |
117 | padding: 2px 1em; | 105 | border-top: solid 1px #eee; |
106 | border-left: solid 1px #eee; | ||
107 | border-right: solid 1px #aaa; | ||
108 | border-bottom: solid 1px #aaa; | ||
118 | } | 109 | } |
119 | 110 | ||
120 | td#crumb { | 111 | div#sidebar div.infobox h1 { |
112 | font-size: 11pt; | ||
121 | font-weight: bold; | 113 | font-weight: bold; |
114 | margin: 0px; | ||
122 | } | 115 | } |
123 | 116 | ||
124 | td#crumb a { | 117 | div#sidebar div.infobox a.menu { |
125 | color: #ccc; | 118 | display: block; |
126 | background-color: #666; | ||
127 | padding: 0em 0.5em 0em 0.5em; | ||
128 | } | ||
129 | |||
130 | td#crumb a:hover { | ||
131 | color: #666; | ||
132 | background-color: #ccc; | 119 | background-color: #ccc; |
120 | padding: 0.1em 0.5em; | ||
133 | text-decoration: none; | 121 | text-decoration: none; |
134 | } | 122 | } |
135 | 123 | ||
136 | td#search { | 124 | div#sidebar div.infobox a.menu:hover { |
137 | text-align: right; | 125 | background-color: #bbb; |
138 | vertical-align: middle; | 126 | text-decoration: none; |
139 | padding-right: 0.5em; | ||
140 | } | ||
141 | |||
142 | td#search form { | ||
143 | margin: 0px; | ||
144 | padding: 0px; | ||
145 | } | 127 | } |
146 | 128 | ||
147 | td#search select { | 129 | div#sidebar div.infobox select { |
148 | font-size: 9pt; | 130 | width: 100%; |
131 | border: solid 1px #aaa; | ||
132 | background-color: #bbb; | ||
133 | margin: 2px 0px 0px 0px; | ||
149 | padding: 0px; | 134 | padding: 0px; |
150 | border: solid 1px #333; | ||
151 | color: #333; | ||
152 | background-color: #fff; | ||
153 | } | 135 | } |
154 | 136 | ||
155 | td#search input { | 137 | div#sidebar div.infobox input.txt { |
156 | font-size: 9pt; | 138 | width: 100%; |
157 | padding: 0px; | 139 | border: solid 1px #aaa; |
140 | background-color: #bbb; | ||
141 | margin: 2px 0px 0px 0px; | ||
142 | padding: 0; | ||
158 | } | 143 | } |
159 | 144 | ||
160 | td#search input.txt { | 145 | table#grid { |
161 | width: 8em; | 146 | margin: 0px; |
162 | border: solid 1px #333; | ||
163 | color: #333; | ||
164 | background-color: #fff; | ||
165 | } | 147 | } |
166 | 148 | ||
167 | td#search input.btn { | 149 | td#content { |
168 | border: solid 1px #333; | 150 | vertical-align: top; |
169 | color: #333; | 151 | padding: 1em 2em 1em 1em; |
170 | background-color: #ccc; | 152 | border: none; |
171 | } | 153 | } |
172 | 154 | ||
173 | div#summary { | 155 | div#summary { |
174 | vertical-align: top; | 156 | vertical-align: top; |
175 | margin-bottom: 1em; | 157 | margin-bottom: 1em; |
176 | } | 158 | } |
177 | 159 | ||
178 | table#downloads { | 160 | table#downloads { |
179 | float: right; | 161 | float: right; |
180 | border-collapse: collapse; | 162 | border-collapse: collapse; |
181 | border: solid 1px #777; | 163 | border: solid 1px #777; |
182 | margin-left: 0.5em; | 164 | margin-left: 0.5em; |
183 | margin-bottom: 0.5em; | 165 | margin-bottom: 0.5em; |
184 | } | 166 | } |
185 | 167 | ||
186 | table#downloads th { | 168 | table#downloads th { |
187 | background-color: #ccc; | 169 | background-color: #ccc; |
188 | } | 170 | } |
189 | 171 | ||
190 | td#content { | ||
191 | padding: 1em 0.5em; | ||
192 | } | ||
193 | |||
194 | div#blob { | 172 | div#blob { |
195 | border: solid 1px black; | 173 | border: solid 1px black; |
196 | } | 174 | } |
197 | 175 | ||
198 | div.error { | 176 | div.error { |
199 | color: red; | 177 | color: red; |
200 | font-weight: bold; | 178 | font-weight: bold; |
201 | margin: 1em 2em; | 179 | margin: 1em 2em; |
202 | } | 180 | } |
203 | 181 | ||
204 | a.ls-blob, a.ls-dir, a.ls-mod { | 182 | a.ls-blob, a.ls-dir, a.ls-mod { |
205 | font-family: monospace; | 183 | font-family: monospace; |
@@ -275,25 +253,24 @@ div.commit-subject { | |||
275 | div.commit-msg { | 253 | div.commit-msg { |
276 | white-space: pre; | 254 | white-space: pre; |
277 | font-family: monospace; | 255 | font-family: monospace; |
278 | } | 256 | } |
279 | 257 | ||
280 | div.diffstat-header { | 258 | div.diffstat-header { |
281 | font-weight: bold; | 259 | font-weight: bold; |
282 | padding-top: 1.5em; | 260 | padding-top: 1.5em; |
283 | } | 261 | } |
284 | 262 | ||
285 | table.diffstat { | 263 | table.diffstat { |
286 | border-collapse: collapse; | 264 | border-collapse: collapse; |
287 | width: 100%; | ||
288 | border: solid 1px #aaa; | 265 | border: solid 1px #aaa; |
289 | background-color: #eee; | 266 | background-color: #eee; |
290 | } | 267 | } |
291 | 268 | ||
292 | table.diffstat th { | 269 | table.diffstat th { |
293 | font-weight: normal; | 270 | font-weight: normal; |
294 | text-align: left; | 271 | text-align: left; |
295 | text-decoration: underline; | 272 | text-decoration: underline; |
296 | padding: 0.1em 1em 0.1em 0.1em; | 273 | padding: 0.1em 1em 0.1em 0.1em; |
297 | font-size: 100%; | 274 | font-size: 100%; |
298 | } | 275 | } |
299 | 276 | ||
@@ -316,25 +293,25 @@ table.diffstat td.add a { | |||
316 | color: green; | 293 | color: green; |
317 | } | 294 | } |
318 | 295 | ||
319 | table.diffstat td.del a { | 296 | table.diffstat td.del a { |
320 | color: red; | 297 | color: red; |
321 | } | 298 | } |
322 | 299 | ||
323 | table.diffstat td.upd a { | 300 | table.diffstat td.upd a { |
324 | color: blue; | 301 | color: blue; |
325 | } | 302 | } |
326 | 303 | ||
327 | table.diffstat td.graph { | 304 | table.diffstat td.graph { |
328 | width: 75%; | 305 | width: 500px; |
329 | vertical-align: middle; | 306 | vertical-align: middle; |
330 | } | 307 | } |
331 | 308 | ||
332 | table.diffstat td.graph table { | 309 | table.diffstat td.graph table { |
333 | border: none; | 310 | border: none; |
334 | } | 311 | } |
335 | 312 | ||
336 | table.diffstat td.graph td { | 313 | table.diffstat td.graph td { |
337 | padding: 0px; | 314 | padding: 0px; |
338 | border: 0px; | 315 | border: 0px; |
339 | height: 7pt; | 316 | height: 7pt; |
340 | } | 317 | } |
@@ -172,24 +172,26 @@ extern int htmlfd; | |||
172 | extern int cgit_get_cmd_index(const char *cmd); | 172 | extern int cgit_get_cmd_index(const char *cmd); |
173 | extern struct repoinfo *cgit_get_repoinfo(const char *url); | 173 | extern struct repoinfo *cgit_get_repoinfo(const char *url); |
174 | extern void cgit_global_config_cb(const char *name, const char *value); | 174 | extern void cgit_global_config_cb(const char *name, const char *value); |
175 | extern void cgit_repo_config_cb(const char *name, const char *value); | 175 | extern void cgit_repo_config_cb(const char *name, const char *value); |
176 | extern void cgit_querystring_cb(const char *name, const char *value); | 176 | extern void cgit_querystring_cb(const char *name, const char *value); |
177 | 177 | ||
178 | extern int chk_zero(int result, char *msg); | 178 | extern int chk_zero(int result, char *msg); |
179 | extern int chk_positive(int result, char *msg); | 179 | extern int chk_positive(int result, char *msg); |
180 | extern int chk_non_negative(int result, char *msg); | 180 | extern int chk_non_negative(int result, char *msg); |
181 | 181 | ||
182 | extern int hextoint(char c); | 182 | extern int hextoint(char c); |
183 | extern char *trim_end(const char *str, char c); | 183 | extern char *trim_end(const char *str, char c); |
184 | extern char *strlpart(char *txt, int maxlen); | ||
185 | extern char *strrpart(char *txt, int maxlen); | ||
184 | 186 | ||
185 | extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); | 187 | extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); |
186 | extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, | 188 | extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, |
187 | int flags, void *cb_data); | 189 | int flags, void *cb_data); |
188 | 190 | ||
189 | extern void *cgit_free_commitinfo(struct commitinfo *info); | 191 | extern void *cgit_free_commitinfo(struct commitinfo *info); |
190 | 192 | ||
191 | extern int cgit_diff_files(const unsigned char *old_sha1, | 193 | extern int cgit_diff_files(const unsigned char *old_sha1, |
192 | const unsigned char *new_sha1, | 194 | const unsigned char *new_sha1, |
193 | linediff_fn fn); | 195 | linediff_fn fn); |
194 | 196 | ||
195 | extern void cgit_diff_tree(const unsigned char *old_sha1, | 197 | extern void cgit_diff_tree(const unsigned char *old_sha1, |
diff --git a/cgit.png b/cgit.png new file mode 100644 index 0000000..ee48197 --- a/dev/null +++ b/cgit.png | |||
Binary files differ | |||
@@ -76,26 +76,31 @@ | |||
76 | ## url.rewrite = ( | 76 | ## url.rewrite = ( |
77 | ## "^/git/([^?/]+/[^?]*)?(?:\?(.*))?$" => "/cgit.cgi?url=$1&$2" | 77 | ## "^/git/([^?/]+/[^?]*)?(?:\?(.*))?$" => "/cgit.cgi?url=$1&$2" |
78 | ## ) | 78 | ## ) |
79 | ## | 79 | ## |
80 | ## This setting is disabled by default. | 80 | ## This setting is disabled by default. |
81 | #virtual-root=/git | 81 | #virtual-root=/git |
82 | 82 | ||
83 | 83 | ||
84 | ## Set the title printed on the root page | 84 | ## Set the title printed on the root page |
85 | #root-title=Git repository browser | 85 | #root-title=Git repository browser |
86 | 86 | ||
87 | 87 | ||
88 | ## If specified, the file at this path will be included as HTML in the index | 88 | ## If specified, the file at this path will be included as HTML in the |
89 | ## of repositories | 89 | ## sidebar on the repository index page |
90 | #index-info= | ||
91 | |||
92 | |||
93 | ## If specified, the file at this path will be included as HTML above | ||
94 | ## the repository index | ||
90 | #index-header= | 95 | #index-header= |
91 | 96 | ||
92 | 97 | ||
93 | ## Link to css file | 98 | ## Link to css file |
94 | #css=/cgit/cgit.css | 99 | #css=/cgit/cgit.css |
95 | 100 | ||
96 | 101 | ||
97 | ## Link to logo file | 102 | ## Link to logo file |
98 | #logo=/cgit/git-logo.png | 103 | #logo=/cgit/git-logo.png |
99 | 104 | ||
100 | 105 | ||
101 | ## Url loaded when clicking the logo | 106 | ## Url loaded when clicking the logo |
@@ -294,24 +294,55 @@ char *trim_end(const char *str, char c) | |||
294 | len--; | 294 | len--; |
295 | 295 | ||
296 | if (len == 0) | 296 | if (len == 0) |
297 | return NULL; | 297 | return NULL; |
298 | 298 | ||
299 | c = t[len]; | 299 | c = t[len]; |
300 | t[len] = '\0'; | 300 | t[len] = '\0'; |
301 | s = xstrdup(t); | 301 | s = xstrdup(t); |
302 | t[len] = c; | 302 | t[len] = c; |
303 | return s; | 303 | return s; |
304 | } | 304 | } |
305 | 305 | ||
306 | char *strlpart(char *txt, int maxlen) | ||
307 | { | ||
308 | char *result; | ||
309 | |||
310 | if (!txt) | ||
311 | return txt; | ||
312 | |||
313 | if (strlen(txt) <= maxlen) | ||
314 | return txt; | ||
315 | result = xmalloc(maxlen + 1); | ||
316 | memcpy(result, txt, maxlen - 3); | ||
317 | result[maxlen-1] = result[maxlen-2] = result[maxlen-3] = '.'; | ||
318 | result[maxlen] = '\0'; | ||
319 | return result; | ||
320 | } | ||
321 | |||
322 | char *strrpart(char *txt, int maxlen) | ||
323 | { | ||
324 | char *result; | ||
325 | |||
326 | if (!txt) | ||
327 | return txt; | ||
328 | |||
329 | if (strlen(txt) <= maxlen) | ||
330 | return txt; | ||
331 | result = xmalloc(maxlen + 1); | ||
332 | memcpy(result + 3, txt + strlen(txt) - maxlen + 4, maxlen - 3); | ||
333 | result[0] = result[1] = result[2] = '.'; | ||
334 | return result; | ||
335 | } | ||
336 | |||
306 | void cgit_add_ref(struct reflist *list, struct refinfo *ref) | 337 | void cgit_add_ref(struct reflist *list, struct refinfo *ref) |
307 | { | 338 | { |
308 | size_t size; | 339 | size_t size; |
309 | 340 | ||
310 | if (list->count >= list->alloc) { | 341 | if (list->count >= list->alloc) { |
311 | list->alloc += (list->alloc ? list->alloc : 4); | 342 | list->alloc += (list->alloc ? list->alloc : 4); |
312 | size = list->alloc * sizeof(struct refinfo *); | 343 | size = list->alloc * sizeof(struct refinfo *); |
313 | list->refs = xrealloc(list->refs, size); | 344 | list->refs = xrealloc(list->refs, size); |
314 | } | 345 | } |
315 | list->refs[list->count++] = ref; | 346 | list->refs[list->count++] = ref; |
316 | } | 347 | } |
317 | 348 | ||
diff --git a/ui-shared.c b/ui-shared.c index 1418010..1d66940 100644 --- a/ui-shared.c +++ b/ui-shared.c | |||
@@ -353,95 +353,167 @@ void cgit_print_docstart(char *title, struct cacheitem *item) | |||
353 | html_txt(title); | 353 | html_txt(title); |
354 | html("</title>\n"); | 354 | html("</title>\n"); |
355 | htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version); | 355 | htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version); |
356 | html("<link rel='stylesheet' type='text/css' href='"); | 356 | html("<link rel='stylesheet' type='text/css' href='"); |
357 | html_attr(cgit_css); | 357 | html_attr(cgit_css); |
358 | html("'/>\n"); | 358 | html("'/>\n"); |
359 | html("</head>\n"); | 359 | html("</head>\n"); |
360 | html("<body>\n"); | 360 | html("<body>\n"); |
361 | } | 361 | } |
362 | 362 | ||
363 | void cgit_print_docend() | 363 | void cgit_print_docend() |
364 | { | 364 | { |
365 | html("</td></tr></table>"); | 365 | html("</td>\n</tr>\n<table>\n</body>\n</html>\n"); |
366 | html("</body>\n</html>\n"); | 366 | } |
367 | |||
368 | int print_branch_option(const char *refname, const unsigned char *sha1, | ||
369 | int flags, void *cb_data) | ||
370 | { | ||
371 | char *name = (char *)refname; | ||
372 | html_option(name, name, cgit_query_head); | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | int print_archive_ref(const char *refname, const unsigned char *sha1, | ||
377 | int flags, void *cb_data) | ||
378 | { | ||
379 | struct tag *tag; | ||
380 | struct taginfo *info; | ||
381 | struct object *obj; | ||
382 | char buf[256], *url; | ||
383 | unsigned char fileid[20]; | ||
384 | int *header = (int *)cb_data; | ||
385 | |||
386 | if (prefixcmp(refname, "refs/archives")) | ||
387 | return 0; | ||
388 | strncpy(buf, refname+14, sizeof(buf)); | ||
389 | obj = parse_object(sha1); | ||
390 | if (!obj) | ||
391 | return 1; | ||
392 | if (obj->type == OBJ_TAG) { | ||
393 | tag = lookup_tag(sha1); | ||
394 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) | ||
395 | return 0; | ||
396 | hashcpy(fileid, tag->tagged->sha1); | ||
397 | } else if (obj->type != OBJ_BLOB) { | ||
398 | return 0; | ||
399 | } else { | ||
400 | hashcpy(fileid, sha1); | ||
401 | } | ||
402 | if (!*header) { | ||
403 | html("<p><h1>download</h1>"); | ||
404 | *header = 1; | ||
405 | } | ||
406 | url = cgit_pageurl(cgit_query_repo, "blob", | ||
407 | fmt("id=%s&path=%s", sha1_to_hex(fileid), | ||
408 | buf)); | ||
409 | html_link_open(url, NULL, "menu"); | ||
410 | html_txt(strlpart(buf, 20)); | ||
411 | html_link_close(); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | void add_hidden_formfields(int incl_head, int incl_search) | ||
416 | { | ||
417 | if (!cgit_virtual_root) { | ||
418 | if (cgit_query_repo) | ||
419 | html_hidden("r", cgit_query_repo); | ||
420 | if (cgit_query_page) | ||
421 | html_hidden("p", cgit_query_page); | ||
422 | } | ||
423 | |||
424 | if (incl_head && strcmp(cgit_query_head, cgit_repo->defbranch)) | ||
425 | html_hidden("h", cgit_query_head); | ||
426 | |||
427 | if (cgit_query_sha1) | ||
428 | html_hidden("id", cgit_query_sha1); | ||
429 | if (cgit_query_sha2) | ||
430 | html_hidden("id2", cgit_query_sha2); | ||
431 | |||
432 | if (incl_search) { | ||
433 | if (cgit_query_grep) | ||
434 | html_hidden("qt", cgit_query_grep); | ||
435 | if (cgit_query_search) | ||
436 | html_hidden("q", cgit_query_search); | ||
437 | } | ||
367 | } | 438 | } |
368 | 439 | ||
369 | void cgit_print_pageheader(char *title, int show_search) | 440 | void cgit_print_pageheader(char *title, int show_search) |
370 | { | 441 | { |
371 | html("<table id='layout'>"); | 442 | static const char *default_info = "This is cgit, a fast webinterface for git repositories"; |
372 | html("<tr><td id='header'><a href='"); | 443 | int header = 0; |
373 | html_attr(cgit_rooturl()); | 444 | |
374 | html("'>"); | 445 | html("<div id='sidebar'>\n"); |
375 | html_txt(cgit_root_title); | ||
376 | html("</a></td><td id='logo'>"); | ||
377 | html("<a href='"); | 446 | html("<a href='"); |
378 | html_attr(cgit_logo_link); | 447 | html_attr(cgit_rooturl()); |
379 | htmlf("'><img src='%s' alt='logo'/></a>", cgit_logo); | 448 | htmlf("'><div id='logo'><img src='%s' alt='cgit'/></div></a>\n", |
380 | html("</td></tr>"); | 449 | cgit_logo); |
381 | html("<tr><td id='crumb'>"); | 450 | html("<div class='infobox'>"); |
382 | if (cgit_query_repo) { | 451 | if (cgit_query_repo) { |
383 | html_txt(cgit_repo->name); | 452 | html("<h1>"); |
384 | html(" ("); | 453 | html_txt(strrpart(cgit_repo->name, 20)); |
385 | html_txt(cgit_query_head); | 454 | html("</h1>\n"); |
386 | html(") : "); | 455 | html_txt(cgit_repo->desc); |
387 | reporevlink(NULL, "summary", NULL, NULL, cgit_query_head, | 456 | if (cgit_repo->owner) { |
457 | html("<p>\n<h1>owner</h1>\n"); | ||
458 | html_txt(cgit_repo->owner); | ||
459 | } | ||
460 | html("<p>\n<h1>navigate</h1>\n"); | ||
461 | reporevlink(NULL, "summary", NULL, "menu", cgit_query_head, | ||
388 | NULL, NULL); | 462 | NULL, NULL); |
389 | html(" "); | 463 | cgit_log_link("log", NULL, "menu", cgit_query_head, |
390 | cgit_log_link("log", NULL, NULL, cgit_query_head, | ||
391 | cgit_query_sha1, cgit_query_path, 0); | 464 | cgit_query_sha1, cgit_query_path, 0); |
392 | html(" "); | 465 | cgit_tree_link("tree", NULL, "menu", cgit_query_head, |
393 | cgit_tree_link("tree", NULL, NULL, cgit_query_head, | ||
394 | cgit_query_sha1, NULL); | 466 | cgit_query_sha1, NULL); |
395 | html(" "); | 467 | cgit_commit_link("commit", NULL, "menu", cgit_query_head, |
396 | cgit_commit_link("commit", NULL, NULL, cgit_query_head, | ||
397 | cgit_query_sha1); | 468 | cgit_query_sha1); |
398 | html(" "); | 469 | cgit_diff_link("diff", NULL, "menu", cgit_query_head, |
399 | cgit_diff_link("diff", NULL, NULL, cgit_query_head, | ||
400 | cgit_query_sha1, cgit_query_sha2, | 470 | cgit_query_sha1, cgit_query_sha2, |
401 | cgit_query_path); | 471 | cgit_query_path); |
402 | } else { | 472 | |
403 | html_txt("Index of repositories"); | 473 | for_each_ref(print_archive_ref, &header); |
404 | } | 474 | |
405 | html("</td>"); | 475 | html("<p>\n<h1>branch</h1>\n"); |
406 | html("<td id='search'>"); | 476 | html("<form method='get' action=''>\n"); |
407 | if (show_search) { | 477 | add_hidden_formfields(0, 1); |
478 | html("<select name='h' onchange='this.form.submit();'>\n"); | ||
479 | for_each_branch_ref(print_branch_option, cgit_query_head); | ||
480 | html("</select>\n"); | ||
481 | html("</form>\n"); | ||
482 | |||
483 | html("<p>\n<h1>search</h1>\n"); | ||
408 | html("<form method='get' action='"); | 484 | html("<form method='get' action='"); |
409 | html_attr(cgit_currurl()); | 485 | html_attr(cgit_pageurl(cgit_query_repo, "log", NULL)); |
410 | html("'>"); | 486 | html("'>\n"); |
411 | if (!cgit_virtual_root) { | 487 | add_hidden_formfields(1, 0); |
412 | if (cgit_query_repo) | 488 | html("<select name='qt'>\n"); |
413 | html_hidden("r", cgit_query_repo); | ||
414 | if (cgit_query_page) | ||
415 | html_hidden("p", cgit_query_page); | ||
416 | } | ||
417 | if (cgit_query_head) | ||
418 | html_hidden("h", cgit_query_head); | ||
419 | if (cgit_query_sha1) | ||
420 | html_hidden("id", cgit_query_sha1); | ||
421 | if (cgit_query_sha2) | ||
422 | html_hidden("id2", cgit_query_sha2); | ||
423 | html("<select name='qt'>"); | ||
424 | html_option("grep", "log msg", cgit_query_grep); | 489 | html_option("grep", "log msg", cgit_query_grep); |
425 | html_option("author", "author", cgit_query_grep); | 490 | html_option("author", "author", cgit_query_grep); |
426 | html_option("committer", "committer", cgit_query_grep); | 491 | html_option("committer", "committer", cgit_query_grep); |
427 | html("</select>"); | 492 | html("</select>\n"); |
428 | html("<input class='txt' type='text' name='q' value='"); | 493 | html("<input class='txt' type='text' name='q' value='"); |
429 | html_attr(cgit_query_search); | 494 | html_attr(cgit_query_search); |
430 | html("'/><input class='btn' type='submit' value='...'/></form>"); | 495 | html("'/>\n"); |
496 | html("</form>\n"); | ||
497 | } else { | ||
498 | if (!cgit_index_info || html_include(cgit_index_info)) | ||
499 | html(default_info); | ||
431 | } | 500 | } |
432 | html("</td></tr>"); | 501 | |
433 | html("<tr><td id='content' colspan='2'>"); | 502 | html("</div>\n"); |
503 | |||
504 | html("</div>\n<table class='grid'><tr><td id='content'>\n"); | ||
434 | } | 505 | } |
435 | 506 | ||
507 | |||
436 | void cgit_print_snapshot_start(const char *mimetype, const char *filename, | 508 | void cgit_print_snapshot_start(const char *mimetype, const char *filename, |
437 | struct cacheitem *item) | 509 | struct cacheitem *item) |
438 | { | 510 | { |
439 | htmlf("Content-Type: %s\n", mimetype); | 511 | htmlf("Content-Type: %s\n", mimetype); |
440 | htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename); | 512 | htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename); |
441 | htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); | 513 | htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); |
442 | htmlf("Expires: %s\n", http_date(item->st.st_mtime + | 514 | htmlf("Expires: %s\n", http_date(item->st.st_mtime + |
443 | ttl_seconds(item->ttl))); | 515 | ttl_seconds(item->ttl))); |
444 | html("\n"); | 516 | html("\n"); |
445 | } | 517 | } |
446 | 518 | ||
447 | /* vim:set sw=8: */ | 519 | /* vim:set sw=8: */ |
diff --git a/ui-summary.c b/ui-summary.c index ba90510..39fe330 100644 --- a/ui-summary.c +++ b/ui-summary.c | |||
@@ -111,65 +111,24 @@ static int print_tag(struct refinfo *ref) | |||
111 | } else { | 111 | } else { |
112 | if (!header) | 112 | if (!header) |
113 | print_tag_header(); | 113 | print_tag_header(); |
114 | html("<tr><td>"); | 114 | html("<tr><td>"); |
115 | html_txt(name); | 115 | html_txt(name); |
116 | html("</td><td colspan='2'/><td>"); | 116 | html("</td><td colspan='2'/><td>"); |
117 | cgit_object_link(ref->object); | 117 | cgit_object_link(ref->object); |
118 | html("</td></tr>\n"); | 118 | html("</td></tr>\n"); |
119 | } | 119 | } |
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1, | ||
124 | int flags, void *cb_data) | ||
125 | { | ||
126 | struct tag *tag; | ||
127 | struct taginfo *info; | ||
128 | struct object *obj; | ||
129 | char buf[256], *url; | ||
130 | unsigned char fileid[20]; | ||
131 | |||
132 | if (prefixcmp(refname, "refs/archives")) | ||
133 | return 0; | ||
134 | strncpy(buf, refname+14, sizeof(buf)); | ||
135 | obj = parse_object(sha1); | ||
136 | if (!obj) | ||
137 | return 1; | ||
138 | if (obj->type == OBJ_TAG) { | ||
139 | tag = lookup_tag(sha1); | ||
140 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) | ||
141 | return 0; | ||
142 | hashcpy(fileid, tag->tagged->sha1); | ||
143 | } else if (obj->type != OBJ_BLOB) { | ||
144 | return 0; | ||
145 | } else { | ||
146 | hashcpy(fileid, sha1); | ||
147 | } | ||
148 | if (!header) { | ||
149 | html("<table id='downloads'>"); | ||
150 | html("<tr><th>Downloads</th></tr>"); | ||
151 | header = 1; | ||
152 | } | ||
153 | html("<tr><td>"); | ||
154 | url = cgit_pageurl(cgit_query_repo, "blob", | ||
155 | fmt("id=%s&path=%s", sha1_to_hex(fileid), | ||
156 | buf)); | ||
157 | html_link_open(url, NULL, NULL); | ||
158 | html_txt(buf); | ||
159 | html_link_close(); | ||
160 | html("</td></tr>"); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static void print_refs_link(char *path) | 123 | static void print_refs_link(char *path) |
165 | { | 124 | { |
166 | html("<tr class='nohover'><td colspan='4'>"); | 125 | html("<tr class='nohover'><td colspan='4'>"); |
167 | cgit_refs_link("[...]", NULL, NULL, cgit_query_head, NULL, path); | 126 | cgit_refs_link("[...]", NULL, NULL, cgit_query_head, NULL, path); |
168 | html("</td></tr>"); | 127 | html("</td></tr>"); |
169 | } | 128 | } |
170 | 129 | ||
171 | void cgit_print_branches(int maxcount) | 130 | void cgit_print_branches(int maxcount) |
172 | { | 131 | { |
173 | struct reflist list; | 132 | struct reflist list; |
174 | int i; | 133 | int i; |
175 | 134 | ||
@@ -212,42 +171,30 @@ void cgit_print_tags(int maxcount) | |||
212 | if (!maxcount) | 171 | if (!maxcount) |
213 | maxcount = list.count; | 172 | maxcount = list.count; |
214 | else if (maxcount > list.count) | 173 | else if (maxcount > list.count) |
215 | maxcount = list.count; | 174 | maxcount = list.count; |
216 | print_tag_header(); | 175 | print_tag_header(); |
217 | for(i=0; i<maxcount; i++) | 176 | for(i=0; i<maxcount; i++) |
218 | print_tag(list.refs[i]); | 177 | print_tag(list.refs[i]); |
219 | 178 | ||
220 | if (maxcount < list.count) | 179 | if (maxcount < list.count) |
221 | print_refs_link("tags"); | 180 | print_refs_link("tags"); |
222 | } | 181 | } |
223 | 182 | ||
224 | static void cgit_print_archives() | ||
225 | { | ||
226 | header = 0; | ||
227 | for_each_ref(cgit_print_archive_cb, NULL); | ||
228 | if (header) | ||
229 | html("</table>"); | ||
230 | } | ||
231 | |||
232 | void cgit_print_summary() | 183 | void cgit_print_summary() |
233 | { | 184 | { |
234 | html("<div id='summary'>"); | 185 | if (cgit_repo->readme) { |
235 | cgit_print_archives(); | 186 | html("<div id='summary'>"); |
236 | html("<h2>"); | ||
237 | html_txt(cgit_repo->name); | ||
238 | html(" - "); | ||
239 | html_txt(cgit_repo->desc); | ||
240 | html("</h2>"); | ||
241 | if (cgit_repo->readme) | ||
242 | html_include(cgit_repo->readme); | 187 | html_include(cgit_repo->readme); |
243 | html("</div>"); | 188 | html("</div>"); |
189 | } | ||
244 | if (cgit_summary_log > 0) | 190 | if (cgit_summary_log > 0) |
245 | cgit_print_log(cgit_query_head, 0, cgit_summary_log, NULL, NULL, NULL, 0); | 191 | cgit_print_log(cgit_query_head, 0, cgit_summary_log, NULL, |
192 | NULL, NULL, 0); | ||
246 | html("<table class='list nowrap'>"); | 193 | html("<table class='list nowrap'>"); |
247 | if (cgit_summary_log > 0) | 194 | if (cgit_summary_log > 0) |
248 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); | 195 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); |
249 | cgit_print_branches(cgit_summary_branches); | 196 | cgit_print_branches(cgit_summary_branches); |
250 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); | 197 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); |
251 | cgit_print_tags(cgit_summary_tags); | 198 | cgit_print_tags(cgit_summary_tags); |
252 | html("</table>"); | 199 | html("</table>"); |
253 | } | 200 | } |