##// END OF EJS Templates
made graphg ticker, and fixes a paging bug caused grapgh disaligment
marcink -
r322:46b7d108 default
parent child Browse files
Show More
@@ -1,90 +1,90
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # changelog controller for pylons
3 # changelog controller for pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
5
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20 """
20 """
21 Created on April 21, 2010
21 Created on April 21, 2010
22 changelog controller for pylons
22 changelog controller for pylons
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from json import dumps
25 from json import dumps
26 from mercurial.graphmod import colored, CHANGESET, revisions as graph_rev
26 from mercurial.graphmod import colored, CHANGESET, revisions as graph_rev
27 from pylons import request, session, tmpl_context as c
27 from pylons import request, session, tmpl_context as c
28 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
28 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
29 from pylons_app.lib.base import BaseController, render
29 from pylons_app.lib.base import BaseController, render
30 from pylons_app.model.hg_model import HgModel
30 from pylons_app.model.hg_model import HgModel
31 from webhelpers.paginate import Page
31 from webhelpers.paginate import Page
32 import logging
32 import logging
33 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
34
34
35 class ChangelogController(BaseController):
35 class ChangelogController(BaseController):
36
36
37 @LoginRequired()
37 @LoginRequired()
38 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
38 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
39 'repository.admin')
39 'repository.admin')
40 def __before__(self):
40 def __before__(self):
41 super(ChangelogController, self).__before__()
41 super(ChangelogController, self).__before__()
42
42
43 def index(self):
43 def index(self):
44 limit = 100
44 limit = 100
45 default = 20
45 default = 20
46 if request.params.get('size'):
46 if request.params.get('size'):
47 try:
47 try:
48 int_size = int(request.params.get('size'))
48 int_size = int(request.params.get('size'))
49 except ValueError:
49 except ValueError:
50 int_size = default
50 int_size = default
51 int_size = int_size if int_size <= limit else limit
51 int_size = int_size if int_size <= limit else limit
52 c.size = int_size
52 c.size = int_size
53 session['changelog_size'] = c.size
53 session['changelog_size'] = c.size
54 session.save()
54 session.save()
55 else:
55 else:
56 c.size = int(session.get('changelog_size', default))
56 c.size = int(session.get('changelog_size', default))
57
57
58 changesets = HgModel().get_repo(c.repo_name)
58 changesets = HgModel().get_repo(c.repo_name)
59
59
60 p = int(request.params.get('page', 1))
60 p = int(request.params.get('page', 1))
61 c.total_cs = len(changesets)
61 c.total_cs = len(changesets)
62 c.pagination = Page(changesets, page=p, item_count=c.total_cs,
62 c.pagination = Page(changesets, page=p, item_count=c.total_cs,
63 items_per_page=c.size)
63 items_per_page=c.size)
64
64
65 self._graph(changesets, c.size, p)
65 self._graph(changesets, c.size, p)
66
66
67 return render('changelog/changelog.html')
67 return render('changelog/changelog.html')
68
68
69
69
70 def _graph(self, repo, size, p):
70 def _graph(self, repo, size, p):
71 revcount = size
71 revcount = size
72 if not repo.revisions:return dumps([]), 0
72 if not repo.revisions:return dumps([]), 0
73
73
74 max_rev = repo.revisions[-1]
74 max_rev = repo.revisions[-1]
75 offset = 1 if p == 1 else ((p - 1) * revcount)
75 offset = 1 if p == 1 else ((p - 1) * revcount + 1)
76 rev_start = repo.revisions[(-1 * offset)]
76 rev_start = repo.revisions[(-1 * offset)]
77
77
78 revcount = min(max_rev, revcount)
78 revcount = min(max_rev, revcount)
79 rev_end = max(0, rev_start - revcount)
79 rev_end = max(0, rev_start - revcount)
80 dag = graph_rev(repo.repo, rev_start, rev_end)
80 dag = graph_rev(repo.repo, rev_start, rev_end)
81
81
82 c.dag = tree = list(colored(dag))
82 c.dag = tree = list(colored(dag))
83 data = []
83 data = []
84 for (id, type, ctx, vtx, edges) in tree:
84 for (id, type, ctx, vtx, edges) in tree:
85 if type != CHANGESET:
85 if type != CHANGESET:
86 continue
86 continue
87 data.append(('', vtx, edges))
87 data.append(('', vtx, edges))
88
88
89 c.jsdata = dumps(data)
89 c.jsdata = dumps(data)
90
90
@@ -1,946 +1,946
1 /*** Initial Settings ***/
1 /*** Initial Settings ***/
2 #mainhtml {
2 #mainhtml {
3 margin: 15px 50px;
3 margin: 15px 50px;
4 background: #DBD4C6;
4 background: #DBD4C6;
5 font-family: sans-serif;
5 font-family: sans-serif;
6 }
6 }
7
7
8 #mainhtml .breadcrumbs a:HOVER {
8 #mainhtml .breadcrumbs a:HOVER {
9 text-decoration: underline;
9 text-decoration: underline;
10 }
10 }
11
11
12 a {
12 a {
13 color: #556CB5;
13 color: #556CB5;
14 text-decoration: none;
14 text-decoration: none;
15 }
15 }
16
16
17 a:HOVER {
17 a:HOVER {
18 text-decoration: underline;
18 text-decoration: underline;
19 }
19 }
20
20
21 /*** end of Initial Settings ***/
21 /*** end of Initial Settings ***/
22
22
23 /*** ***/
23 /*** ***/
24 .table_disp {
24 .table_disp {
25 border-left: 0px solid #666666;
25 border-left: 0px solid #666666;
26 border-bottom: 1px solid #666666;
26 border-bottom: 1px solid #666666;
27 border-right: 1px solid #666666;
27 border-right: 1px solid #666666;
28 padding: 0px;
28 padding: 0px;
29 margin: 0px;
29 margin: 0px;
30 border-spacing: 0px;
30 border-spacing: 0px;
31 }
31 }
32
32
33 .table_disp .header {
33 .table_disp .header {
34 border-top: 1px solid #666666;
34 border-top: 1px solid #666666;
35 background-color: #556CB5;
35 background-color: #556CB5;
36 font-weight: bold;
36 font-weight: bold;
37 color: white;
37 color: white;
38 vertical-align: middle;
38 vertical-align: middle;
39 padding: 3px 5px;
39 padding: 3px 5px;
40 text-align: left;
40 text-align: left;
41 font-size: 0.9em;
41 font-size: 0.9em;
42 }
42 }
43
43
44 .table_disp .header td {
44 .table_disp .header td {
45 padding: 4px;
45 padding: 4px;
46 vertical-align: middle;
46 vertical-align: middle;
47 border-top: 1px solid #AAAAAA;
47 border-top: 1px solid #AAAAAA;
48 border-bottom: 2px solid #666666;
48 border-bottom: 2px solid #666666;
49 }
49 }
50
50
51 .table_disp td {
51 .table_disp td {
52 border-left: 1px solid #AAAAAA;
52 border-left: 1px solid #AAAAAA;
53 padding-left: 4px;
53 padding-left: 4px;
54 padding-right: 4px;
54 padding-right: 4px;
55 }
55 }
56
56
57 table tr.parity0:hover,table tr.parity1:hover {
57 table tr.parity0:hover,table tr.parity1:hover {
58 background: #D5E1E6;
58 background: #D5E1E6;
59 }
59 }
60
60
61 table tr.parity0 {
61 table tr.parity0 {
62 background: #EAEAE9;
62 background: #EAEAE9;
63 }
63 }
64
64
65 table tr.parity1 {
65 table tr.parity1 {
66 background: #FFFFFF;
66 background: #FFFFFF;
67 }
67 }
68
68
69 /*** ***/
69 /*** ***/
70
70
71 /** COMMON SETTINGS **/
71 /** COMMON SETTINGS **/
72 .add_icon {
72 .add_icon {
73 background: url("/images/icons/add.png") no-repeat scroll 3px;
73 background: url("/images/icons/add.png") no-repeat scroll 3px;
74 height: 16px;
74 height: 16px;
75 padding-left: 20px;
75 padding-left: 20px;
76 padding-top: 0px;
76 padding-top: 0px;
77 text-align: left;
77 text-align: left;
78 }
78 }
79
79
80 .edit_icon {
80 .edit_icon {
81 background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
81 background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
82 height: 16px;
82 height: 16px;
83 padding-left: 20px;
83 padding-left: 20px;
84 padding-top: 0px;
84 padding-top: 0px;
85 text-align: left;
85 text-align: left;
86 }
86 }
87
87
88 .delete_icon {
88 .delete_icon {
89 background: url("/images/icons/delete.png") no-repeat scroll 3px;
89 background: url("/images/icons/delete.png") no-repeat scroll 3px;
90 height: 16px;
90 height: 16px;
91 padding-left: 20px;
91 padding-left: 20px;
92 padding-top: 0px;
92 padding-top: 0px;
93 text-align: left;
93 text-align: left;
94 }
94 }
95
95
96 .action_button {
96 .action_button {
97 border: 0px;
97 border: 0px;
98 display: block;
98 display: block;
99 }
99 }
100
100
101 .action_button:hover {
101 .action_button:hover {
102 border: 0px;
102 border: 0px;
103 font-style: italic;
103 font-style: italic;
104 cursor: pointer;
104 cursor: pointer;
105 }
105 }
106
106
107 .flash_msg ul {
107 .flash_msg ul {
108 margin: 0;
108 margin: 0;
109 padding: 25px 0px 0px 0px;
109 padding: 25px 0px 0px 0px;
110 }
110 }
111
111
112 .error_msg {
112 .error_msg {
113 background-color: #FFCFCF;
113 background-color: #FFCFCF;
114 background-image: url("/images/icons/error_msg.png");
114 background-image: url("/images/icons/error_msg.png");
115 border: 1px solid #FF9595;
115 border: 1px solid #FF9595;
116 color: #CC3300;
116 color: #CC3300;
117 }
117 }
118
118
119 .warning_msg {
119 .warning_msg {
120 background-color: #FFFBCC;
120 background-color: #FFFBCC;
121 background-image: url("/images/icons/warning_msg.png");
121 background-image: url("/images/icons/warning_msg.png");
122 border: 1px solid #FFF35E;
122 border: 1px solid #FFF35E;
123 color: #C69E00;
123 color: #C69E00;
124 }
124 }
125
125
126 .success_msg {
126 .success_msg {
127 background-color: #D5FFCF;
127 background-color: #D5FFCF;
128 background-image: url("/images/icons/success_msg.png");
128 background-image: url("/images/icons/success_msg.png");
129 border: 1px solid #97FF88;
129 border: 1px solid #97FF88;
130 color: #009900;
130 color: #009900;
131 }
131 }
132
132
133 .notice_msg {
133 .notice_msg {
134 background-color: #DCE3FF;
134 background-color: #DCE3FF;
135 background-image: url("/images/icons/notice_msg.png");
135 background-image: url("/images/icons/notice_msg.png");
136 border: 1px solid #93A8FF;
136 border: 1px solid #93A8FF;
137 color: #556CB5;
137 color: #556CB5;
138 }
138 }
139
139
140 .success_msg,.error_msg,.notice_msg,.warning_msg {
140 .success_msg,.error_msg,.notice_msg,.warning_msg {
141 background-position: 10px center;
141 background-position: 10px center;
142 background-repeat: no-repeat;
142 background-repeat: no-repeat;
143 font-size: 12px;
143 font-size: 12px;
144 font-weight: bold;
144 font-weight: bold;
145 min-height: 14px;
145 min-height: 14px;
146 line-height: 14px;
146 line-height: 14px;
147 margin-bottom: 0px;
147 margin-bottom: 0px;
148 margin-top: 0px;
148 margin-top: 0px;
149 padding: 3px 10px 3px 40px;
149 padding: 3px 10px 3px 40px;
150 display: block;
150 display: block;
151 overflow: auto;
151 overflow: auto;
152 }
152 }
153
153
154 #msg_close {
154 #msg_close {
155 background: transparent url("icons/cross_grey_small.png") no-repeat
155 background: transparent url("icons/cross_grey_small.png") no-repeat
156 scroll 0 0;
156 scroll 0 0;
157 cursor: pointer;
157 cursor: pointer;
158 height: 16px;
158 height: 16px;
159 position: absolute;
159 position: absolute;
160 right: 5px;
160 right: 5px;
161 top: 5px;
161 top: 5px;
162 width: 16px;
162 width: 16px;
163 }
163 }
164
164
165 .error-message {
165 .error-message {
166 color: #CC3300;
166 color: #CC3300;
167 }
167 }
168
168
169 /**** TOOLTIP ****/
169 /**** TOOLTIP ****/
170 .yui-overlay,.yui-panel-container {
170 .yui-overlay,.yui-panel-container {
171 visibility: hidden;
171 visibility: hidden;
172 position: absolute;
172 position: absolute;
173 z-index: 2;
173 z-index: 2;
174 }
174 }
175
175
176 .yui-tt {
176 .yui-tt {
177 visibility: hidden;
177 visibility: hidden;
178 position: absolute;
178 position: absolute;
179 color: #666666;
179 color: #666666;
180 background-color: #FFFFFF;
180 background-color: #FFFFFF;
181 font-family: arial, helvetica, verdana, sans-serif;
181 font-family: arial, helvetica, verdana, sans-serif;
182 padding: 8px;
182 padding: 8px;
183 border: 2px solid #556CB5;
183 border: 2px solid #556CB5;
184 font: 100% sans-serif;
184 font: 100% sans-serif;
185 width: auto;
185 width: auto;
186 opacity: 1.0;
186 opacity: 1.0;
187 }
187 }
188
188
189 .yui-tt-shadow {
189 .yui-tt-shadow {
190 display: none;
190 display: none;
191 }
191 }
192
192
193 /** END TOOLTIP **/
193 /** END TOOLTIP **/
194
194
195 /** AUTOCOMPLETE **/
195 /** AUTOCOMPLETE **/
196
196
197 .ac{
197 .ac{
198 vertical-align: top;
198 vertical-align: top;
199
199
200 }
200 }
201 .ac .match {
201 .ac .match {
202 font-weight:bold;
202 font-weight:bold;
203 }
203 }
204
204
205 .ac .yui-ac {
205 .ac .yui-ac {
206 position: relative;
206 position: relative;
207 font-family: arial;
207 font-family: arial;
208 font-size: 100%;
208 font-size: 100%;
209 }
209 }
210
210
211 .ac #perm_ac{
211 .ac #perm_ac{
212 width:15em;
212 width:15em;
213 }
213 }
214 /* styles for input field */
214 /* styles for input field */
215 .ac .yui-ac-input {
215 .ac .yui-ac-input {
216 position: absolute;
216 position: absolute;
217 width: 100%;
217 width: 100%;
218 }
218 }
219
219
220 /* styles for results container */
220 /* styles for results container */
221 .ac .yui-ac-container {
221 .ac .yui-ac-container {
222 position: absolute;
222 position: absolute;
223 top: 1.6em;
223 top: 1.6em;
224 width: 100%;
224 width: 100%;
225 }
225 }
226
226
227 /* styles for header/body/footer wrapper within container */
227 /* styles for header/body/footer wrapper within container */
228 .ac .yui-ac-content {
228 .ac .yui-ac-content {
229 position: absolute;
229 position: absolute;
230 width: 100%;
230 width: 100%;
231 border: 1px solid #808080;
231 border: 1px solid #808080;
232 background: #fff;
232 background: #fff;
233 overflow: hidden;
233 overflow: hidden;
234 z-index: 9050;
234 z-index: 9050;
235 }
235 }
236
236
237 /* styles for container shadow */
237 /* styles for container shadow */
238 .ac .yui-ac-shadow {
238 .ac .yui-ac-shadow {
239 position: absolute;
239 position: absolute;
240 margin: .3em;
240 margin: .3em;
241 width: 100%;
241 width: 100%;
242 background: #000;
242 background: #000;
243 -moz-opacity: 0.10;
243 -moz-opacity: 0.10;
244 opacity: .10;
244 opacity: .10;
245 filter: alpha(opacity = 10);
245 filter: alpha(opacity = 10);
246 z-index: 9049;
246 z-index: 9049;
247 }
247 }
248
248
249 /* styles for results list */
249 /* styles for results list */
250 .ac .yui-ac-content ul {
250 .ac .yui-ac-content ul {
251 margin: 0;
251 margin: 0;
252 padding: 0;
252 padding: 0;
253 width: 100%;
253 width: 100%;
254 }
254 }
255
255
256 /* styles for result item */
256 /* styles for result item */
257 .ac .yui-ac-content li {
257 .ac .yui-ac-content li {
258 margin: 0;
258 margin: 0;
259 padding: 2px 5px;
259 padding: 2px 5px;
260 cursor: default;
260 cursor: default;
261 white-space: nowrap;
261 white-space: nowrap;
262 }
262 }
263
263
264 /* styles for prehighlighted result item */
264 /* styles for prehighlighted result item */
265 .ac .yui-ac-content li.yui-ac-prehighlight {
265 .ac .yui-ac-content li.yui-ac-prehighlight {
266 background: #B3D4FF;
266 background: #B3D4FF;
267 }
267 }
268
268
269 /* styles for highlighted result item */
269 /* styles for highlighted result item */
270 .ac .yui-ac-content li.yui-ac-highlight {
270 .ac .yui-ac-content li.yui-ac-highlight {
271 background: #556CB5;
271 background: #556CB5;
272 color: #FFF;
272 color: #FFF;
273 }
273 }
274
274
275 /** END AUTOCOMPLETE **/
275 /** END AUTOCOMPLETE **/
276 div#main {
276 div#main {
277 padding: 5px;
277 padding: 5px;
278 }
278 }
279
279
280 div#container {
280 div#container {
281 background: #FFFFFF;
281 background: #FFFFFF;
282 position: relative;
282 position: relative;
283 color: #666;
283 color: #666;
284 }
284 }
285
285
286 div.page-header {
286 div.page-header {
287 padding: 50px 20px 0;
287 padding: 50px 20px 0;
288 background: #556cb5 top left repeat-x;
288 background: #556cb5 top left repeat-x;
289 position: relative;
289 position: relative;
290 }
290 }
291
291
292 div.page-header h1 {
292 div.page-header h1 {
293 margin: 10px 0 30px;
293 margin: 10px 0 30px;
294 font-size: 1.8em;
294 font-size: 1.8em;
295 font-weight: bold;
295 font-weight: bold;
296 font-family: sans-serif;
296 font-family: sans-serif;
297 letter-spacing: 1px;
297 letter-spacing: 1px;
298 color: #FFFFFF;
298 color: #FFFFFF;
299 }
299 }
300
300
301 div.page-header h1 a {
301 div.page-header h1 a {
302 font-weight: bold;
302 font-weight: bold;
303 color: #FFFFFF;
303 color: #FFFFFF;
304 }
304 }
305
305
306 div.page-header a {
306 div.page-header a {
307 text-decoration: none;
307 text-decoration: none;
308 }
308 }
309
309
310 div.page-header form {
310 div.page-header form {
311 position: absolute;
311 position: absolute;
312 margin-bottom: 2px;
312 margin-bottom: 2px;
313 bottom: 0;
313 bottom: 0;
314 right: 20px;
314 right: 20px;
315 }
315 }
316
316
317 div.page-header form label {
317 div.page-header form label {
318 color: #DDD;
318 color: #DDD;
319 }
319 }
320
320
321 div.page-header form input {
321 div.page-header form input {
322 padding: 2px;
322 padding: 2px;
323 border: solid 1px #DDD;
323 border: solid 1px #DDD;
324 }
324 }
325
325
326 div.page-header form dl {
326 div.page-header form dl {
327 overflow: hidden;
327 overflow: hidden;
328 }
328 }
329
329
330 div.page-header form dl dt {
330 div.page-header form dl dt {
331 font-size: 1.2em;
331 font-size: 1.2em;
332 }
332 }
333
333
334 div.page-header form dl dt,div.page-header form dl dd {
334 div.page-header form dl dt,div.page-header form dl dd {
335 margin: 0 0 0 5px;
335 margin: 0 0 0 5px;
336 float: left;
336 float: left;
337 height: 24px;
337 height: 24px;
338 line-height: 20px;
338 line-height: 20px;
339 }
339 }
340
340
341 ul.page-nav {
341 ul.page-nav {
342 margin: 10px 0 0 0;
342 margin: 10px 0 0 0;
343 list-style-type: none;
343 list-style-type: none;
344 overflow: hidden;
344 overflow: hidden;
345 width: 800px;
345 width: 800px;
346 padding: 0;
346 padding: 0;
347 }
347 }
348
348
349 ul.page-nav li {
349 ul.page-nav li {
350 margin: 0 4px 0 0;
350 margin: 0 4px 0 0;
351 float: left;
351 float: left;
352 height: 24px;
352 height: 24px;
353 font-size: 1.1em;
353 font-size: 1.1em;
354 line-height: 24px;
354 line-height: 24px;
355 text-align: center;
355 text-align: center;
356 background: #556CB5;
356 background: #556CB5;
357 }
357 }
358
358
359 ul.page-nav li.current {
359 ul.page-nav li.current {
360 background: #FFF;
360 background: #FFF;
361 padding-right: 5px;
361 padding-right: 5px;
362 padding-left: 5px;
362 padding-left: 5px;
363 }
363 }
364
364
365 ul.page-nav li.current a {
365 ul.page-nav li.current a {
366 color: #556CB5;
366 color: #556CB5;
367 }
367 }
368
368
369 ul.page-nav li a {
369 ul.page-nav li a {
370 height: 24px;
370 height: 24px;
371 color: #FFF;
371 color: #FFF;
372 padding-right: 5px;
372 padding-right: 5px;
373 padding-left: 5px;
373 padding-left: 5px;
374 display: block;
374 display: block;
375 text-decoration: none;
375 text-decoration: none;
376 font-weight: bold;
376 font-weight: bold;
377 }
377 }
378
378
379 ul.page-nav li.logout a {
379 ul.page-nav li.logout a {
380 color: #FDAC9D;
380 color: #FDAC9D;
381 }
381 }
382
382
383 ul.page-nav li a:hover {
383 ul.page-nav li a:hover {
384 background: #FFF;
384 background: #FFF;
385 color: #556CB5;
385 color: #556CB5;
386 }
386 }
387
387
388 ul.submenu {
388 ul.submenu {
389 margin: 5px 0px -20px 0px;
389 margin: 5px 0px -20px 0px;
390 list-style-type: none;
390 list-style-type: none;
391 }
391 }
392
392
393 ul.submenu li {
393 ul.submenu li {
394 margin: 0 10px 0 0;
394 margin: 0 10px 0 0;
395 font-size: 0.9em;
395 font-size: 0.9em;
396 font-weight: bold;
396 font-weight: bold;
397 display: inline;
397 display: inline;
398 }
398 }
399
399
400 ul.submenu .repos {
400 ul.submenu .repos {
401 background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
401 background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
402 height: 16px;
402 height: 16px;
403 padding-left: 20px;
403 padding-left: 20px;
404 padding-top: 0px;
404 padding-top: 0px;
405 text-align: left;
405 text-align: left;
406 }
406 }
407
407
408 ul.submenu .users {
408 ul.submenu .users {
409 background: url("/images/icons/user_edit.png") no-repeat scroll 3px;
409 background: url("/images/icons/user_edit.png") no-repeat scroll 3px;
410 height: 16px;
410 height: 16px;
411 padding-left: 20px;
411 padding-left: 20px;
412 padding-top: 0px;
412 padding-top: 0px;
413 text-align: left;
413 text-align: left;
414 }
414 }
415
415
416 ul.submenu .permissions {
416 ul.submenu .permissions {
417 background: url("/images/icons/folder_key.png") no-repeat scroll 3px;
417 background: url("/images/icons/folder_key.png") no-repeat scroll 3px;
418 height: 16px;
418 height: 16px;
419 padding-left: 20px;
419 padding-left: 20px;
420 padding-top: 0px;
420 padding-top: 0px;
421 text-align: left;
421 text-align: left;
422 }
422 }
423
423
424 ul.submenu .current_submenu {
424 ul.submenu .current_submenu {
425 border-bottom: 2px solid #556CB5;
425 border-bottom: 2px solid #556CB5;
426 }
426 }
427
427
428 h2 {
428 h2 {
429 margin: 20px 0 10px;
429 margin: 20px 0 10px;
430 height: 30px;
430 height: 30px;
431 line-height: 30px;
431 line-height: 30px;
432 text-indent: 20px;
432 text-indent: 20px;
433 background: #FFF;
433 background: #FFF;
434 font-size: 1.2em;
434 font-size: 1.2em;
435 border-top: dotted 1px #D5E1E6;
435 border-top: dotted 1px #D5E1E6;
436 font-weight: bold;
436 font-weight: bold;
437 color: #556CB5;
437 color: #556CB5;
438 }
438 }
439
439
440 h2.no-link {
440 h2.no-link {
441 color: #006699;
441 color: #006699;
442 }
442 }
443
443
444 h2.no-border {
444 h2.no-border {
445 color: #FFF;
445 color: #FFF;
446 background: #556CB5;
446 background: #556CB5;
447 border: 0;
447 border: 0;
448 }
448 }
449
449
450 h2 a {
450 h2 a {
451 font-weight: bold;
451 font-weight: bold;
452 color: #006699;
452 color: #006699;
453 }
453 }
454
454
455 div.page-path {
455 div.page-path {
456 text-align: right;
456 text-align: right;
457 padding: 20px 30px 10px 0;
457 padding: 20px 30px 10px 0;
458 border: solid #d9d8d1;
458 border: solid #d9d8d1;
459 border-width: 0px 0px 1px;
459 border-width: 0px 0px 1px;
460 font-size: 1.2em;
460 font-size: 1.2em;
461 }
461 }
462
462
463 div.page-footer {
463 div.page-footer {
464 margin: 50px 0 0;
464 margin: 50px 0 0;
465 position: relative;
465 position: relative;
466 text-align: center;
466 text-align: center;
467 font-weight: bold;
467 font-weight: bold;
468 font-size: 90%;
468 font-size: 90%;
469 }
469 }
470
470
471 div.page-footer p {
471 div.page-footer p {
472 position: relative;
472 position: relative;
473 left: 20px;
473 left: 20px;
474 bottom: 5px;
474 bottom: 5px;
475 font-size: 1.2em;
475 font-size: 1.2em;
476 }
476 }
477
477
478 ul.rss-logo {
478 ul.rss-logo {
479 position: absolute;
479 position: absolute;
480 top: -10px;
480 top: -10px;
481 right: 20px;
481 right: 20px;
482 height: 20px;
482 height: 20px;
483 list-style-type: none;
483 list-style-type: none;
484 }
484 }
485
485
486 ul.rss-logo li {
486 ul.rss-logo li {
487 display: inline;
487 display: inline;
488 }
488 }
489
489
490 ul.rss-logo li a {
490 ul.rss-logo li a {
491 padding: 3px 6px;
491 padding: 3px 6px;
492 line-height: 10px;
492 line-height: 10px;
493 border: 1px solid;
493 border: 1px solid;
494 border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
494 border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
495 color: #ffffff;
495 color: #ffffff;
496 background-color: #ff6600;
496 background-color: #ff6600;
497 font-weight: bold;
497 font-weight: bold;
498 font-family: sans-serif;
498 font-family: sans-serif;
499 font-size: 10px;
499 font-size: 10px;
500 text-align: center;
500 text-align: center;
501 text-decoration: none;
501 text-decoration: none;
502 }
502 }
503
503
504 div.rss-logo li a:hover {
504 div.rss-logo li a:hover {
505 background-color: #ee5500;
505 background-color: #ee5500;
506 }
506 }
507
507
508 p.normal {
508 p.normal {
509 margin: 20px 0 20px 30px;
509 margin: 20px 0 20px 30px;
510 font-size: 1.2em;
510 font-size: 1.2em;
511 }
511 }
512
512
513 span.logtags span {
513 span.logtags span {
514 background-repeat: no-repeat;
514 background-repeat: no-repeat;
515 height: 16px;
515 height: 16px;
516 padding-left: 20px;
516 padding-left: 20px;
517 padding-top: 0px;
517 padding-top: 0px;
518 text-align: left;
518 text-align: left;
519 font-weight: bold;
519 font-weight: bold;
520 }
520 }
521
521
522 span.logtags span.tagtag {
522 span.logtags span.tagtag {
523 background-image: url("/images/icons/tag_green.png");
523 background-image: url("/images/icons/tag_green.png");
524 }
524 }
525
525
526 span.logtags span.branchtag {
526 span.logtags span.branchtag {
527 background-image: url("/images/icons/arrow_branch.png");
527 background-image: url("/images/icons/arrow_branch.png");
528 color: #628F53;
528 color: #628F53;
529 }
529 }
530
530
531 span.logtags span.inbranchtag {
531 span.logtags span.inbranchtag {
532 background-image: url("/images/icons/arrow_branch.png");
532 background-image: url("/images/icons/arrow_branch.png");
533 }
533 }
534
534
535 div.diff pre {
535 div.diff pre {
536 margin: 10px 0 0 0;
536 margin: 10px 0 0 0;
537 }
537 }
538
538
539 div.diff pre span {
539 div.diff pre span {
540 font-family: monospace;
540 font-family: monospace;
541 white-space: pre;
541 white-space: pre;
542 font-size: 1.2em;
542 font-size: 1.2em;
543 padding: 3px 0;
543 padding: 3px 0;
544 }
544 }
545
545
546 td.source {
546 td.source {
547 white-space: pre;
547 white-space: pre;
548 font-family: monospace;
548 font-family: monospace;
549 margin: 10px 30px 0;
549 margin: 10px 30px 0;
550 font-size: 1.2em;
550 font-size: 1.2em;
551 font-family: monospace;
551 font-family: monospace;
552 }
552 }
553
553
554 div.source div.parity0,div.source div.parity1 {
554 div.source div.parity0,div.source div.parity1 {
555 padding: 1px;
555 padding: 1px;
556 font-size: 1.2em;
556 font-size: 1.2em;
557 }
557 }
558
558
559 div.source div.parity0 {
559 div.source div.parity0 {
560 background: #F1F6F7;
560 background: #F1F6F7;
561 }
561 }
562
562
563 div.source div.parity1 {
563 div.source div.parity1 {
564 background: #FFFFFF;
564 background: #FFFFFF;
565 }
565 }
566
566
567 div.parity0:hover,div.parity1:hover {
567 div.parity0:hover,div.parity1:hover {
568 background: #D5E1E6;
568 background: #D5E1E6;
569 }
569 }
570
570
571 .linenr {
571 .linenr {
572 color: #999;
572 color: #999;
573 text-align: right;
573 text-align: right;
574 }
574 }
575
575
576 .lineno {
576 .lineno {
577 text-align: right;
577 text-align: right;
578 }
578 }
579
579
580 .lineno a {
580 .lineno a {
581 color: #999;
581 color: #999;
582 }
582 }
583
583
584 td.linenr {
584 td.linenr {
585 width: 60px;
585 width: 60px;
586 }
586 }
587
587
588 div#powered-by {
588 div#powered-by {
589 position: absolute;
589 position: absolute;
590 width: 75px;
590 width: 75px;
591 top: 15px;
591 top: 15px;
592 right: 20px;
592 right: 20px;
593 font-size: 1.2em;
593 font-size: 1.2em;
594 }
594 }
595
595
596 div#powered-by a {
596 div#powered-by a {
597 color: #EEE;
597 color: #EEE;
598 text-decoration: none;
598 text-decoration: none;
599 }
599 }
600
600
601 div#powered-by a:hover {
601 div#powered-by a:hover {
602 text-decoration: underline;
602 text-decoration: underline;
603 }
603 }
604
604
605 dl.overview {
605 dl.overview {
606 margin: 0 0 0 30px;
606 margin: 0 0 0 30px;
607 font-size: 1.1em;
607 font-size: 1.1em;
608 overflow: hidden;
608 overflow: hidden;
609 }
609 }
610
610
611 dl.overview dt,dl.overview dd {
611 dl.overview dt,dl.overview dd {
612 margin: 5px 0;
612 margin: 5px 0;
613 float: left;
613 float: left;
614 }
614 }
615
615
616 dl.overview dt {
616 dl.overview dt {
617 clear: left;
617 clear: left;
618 font-weight: bold;
618 font-weight: bold;
619 width: 150px;
619 width: 150px;
620 }
620 }
621
621
622 #clone_url {
622 #clone_url {
623 border: 0px;
623 border: 0px;
624 }
624 }
625
625
626 /** end of summary **/ /** chagelog **/
626 /** end of summary **/ /** chagelog **/
627 h3.changelog {
627 h3.changelog {
628 margin: 20px 0 5px 30px;
628 margin: 20px 0 5px 30px;
629 padding: 0 0 2px;
629 padding: 0 0 2px;
630 font-size: 1.4em;
630 font-size: 1.4em;
631 border-bottom: dotted 1px #D5E1E6;
631 border-bottom: dotted 1px #D5E1E6;
632 }
632 }
633
633
634 ul.changelog-entry {
634 ul.changelog-entry {
635 margin: 0 0 10px 30px;
635 margin: 0 0 10px 30px;
636 list-style-type: none;
636 list-style-type: none;
637 position: relative;
637 position: relative;
638 }
638 }
639
639
640 ul.changelog-entry li span.revdate {
640 ul.changelog-entry li span.revdate {
641 font-size: 1.1em;
641 font-size: 1.1em;
642 }
642 }
643
643
644 ul.changelog-entry li.age {
644 ul.changelog-entry li.age {
645 position: absolute;
645 position: absolute;
646 top: -25px;
646 top: -25px;
647 right: 10px;
647 right: 10px;
648 font-size: 1.4em;
648 font-size: 1.4em;
649 color: #CCC;
649 color: #CCC;
650 font-weight: bold;
650 font-weight: bold;
651 font-style: italic;
651 font-style: italic;
652 }
652 }
653
653
654 ul.changelog-entry li span.name {
654 ul.changelog-entry li span.name {
655 font-size: 1.2em;
655 font-size: 1.2em;
656 font-weight: bold;
656 font-weight: bold;
657 }
657 }
658
658
659 ul.changelog-entry li.description {
659 ul.changelog-entry li.description {
660 margin: 10px 0 0;
660 margin: 10px 0 0;
661 font-size: 1.1em;
661 font-size: 1.1em;
662 }
662 }
663
663
664 /** end of changelog **/ /** file **/
664 /** end of changelog **/ /** file **/
665 p.files {
665 p.files {
666 margin: 0 0 0 20px;
666 margin: 0 0 0 20px;
667 font-size: 2.0em;
667 font-size: 2.0em;
668 font-weight: bold;
668 font-weight: bold;
669 }
669 }
670
670
671 /** end of file **/ /** changeset **/
671 /** end of file **/ /** changeset **/
672 #changeset_content {
672 #changeset_content {
673 width: 60%;
673 width: 60%;
674 float: left;
674 float: left;
675 }
675 }
676
676
677 #changeset_content .container .wrapper {
677 #changeset_content .container .wrapper {
678 width: 600px;
678 width: 600px;
679 }
679 }
680
680
681 #changeset_content .container {
681 #changeset_content .container {
682 border: 1px solid #CCCCCC;
682 border: 1px solid #CCCCCC;
683 height: 120px;
683 height: 120px;
684 }
684 }
685
685
686 #changeset_content .container .left {
686 #changeset_content .container .left {
687 float: left;
687 float: left;
688 width: 70%;
688 width: 70%;
689 padding-left: 5px;
689 padding-left: 5px;
690 }
690 }
691
691
692 #changeset_content .container .right {
692 #changeset_content .container .right {
693 float: right;
693 float: right;
694 width: 25%;
694 width: 25%;
695 text-align: right;
695 text-align: right;
696 }
696 }
697
697
698 #changeset_content .container .left .date {
698 #changeset_content .container .left .date {
699 font-weight: bold;
699 font-weight: bold;
700 }
700 }
701
701
702 #changeset_content .container .left .author {
702 #changeset_content .container .left .author {
703
703
704 }
704 }
705
705
706 #changeset_content .container .left .message {
706 #changeset_content .container .left .message {
707 font-style: italic;
707 font-style: italic;
708 color: #556CB5;
708 color: #556CB5;
709 }
709 }
710
710
711 .cs_files {
711 .cs_files {
712 width: 60%;
712 width: 60%;
713 }
713 }
714
714
715 .cs_files .cs_added {
715 .cs_files .cs_added {
716 background: url("/images/icons/page_white_add.png") no-repeat scroll 3px;
716 background: url("/images/icons/page_white_add.png") no-repeat scroll 3px;
717 /*background-color:#BBFFBB;*/
717 /*background-color:#BBFFBB;*/
718 height: 16px;
718 height: 16px;
719 padding-left: 20px;
719 padding-left: 20px;
720 margin-top: 7px;
720 margin-top: 7px;
721 text-align: left;
721 text-align: left;
722 }
722 }
723
723
724 .cs_files .cs_changed {
724 .cs_files .cs_changed {
725 background: url("/images/icons/page_white_edit.png") no-repeat scroll
725 background: url("/images/icons/page_white_edit.png") no-repeat scroll
726 3px;
726 3px;
727 /*background-color: #FFDD88;*/
727 /*background-color: #FFDD88;*/
728 height: 16px;
728 height: 16px;
729 padding-left: 20px;
729 padding-left: 20px;
730 margin-top: 7px;
730 margin-top: 7px;
731 text-align: left;
731 text-align: left;
732 }
732 }
733
733
734 .cs_files .cs_removed {
734 .cs_files .cs_removed {
735 background: url("/images/icons/page_white_delete.png") no-repeat scroll
735 background: url("/images/icons/page_white_delete.png") no-repeat scroll
736 3px;
736 3px;
737 /*background-color: #FF8888;*/
737 /*background-color: #FF8888;*/
738 height: 16px;
738 height: 16px;
739 padding-left: 20px;
739 padding-left: 20px;
740 margin-top: 7px;
740 margin-top: 7px;
741 text-align: left;
741 text-align: left;
742 }
742 }
743
743
744 /** end of changeset **/ /** canvas **/
744 /** end of changeset **/ /** canvas **/
745 #graph_nodes {
746 margin-top: 8px;
747 }
748
745
749 #graph {
746 #graph {
750 overflow: hidden;
747 overflow: hidden;
751 }
748 }
752
749
753 #graph_nodes {
750 #graph_nodes {
754 width: 160px;
751 width: 160px;
755 float: left;
752 float: left;
753 margin-left:-50px;
754 margin-top: 5px;
756 }
755 }
757
756
758 #graph_content {
757 #graph_content {
759 width: 800px;
758 width: 800px;
760 float: left;
759 float: left;
761 }
760 }
762
761
763 #graph_content .container_header {
762 #graph_content .container_header {
764 border: 1px solid #CCCCCC;
763 border: 1px solid #CCCCCC;
765 height: 30px;
764 height: 30px;
766 background: #EEEEEE;
765 background: #EEEEEE;
767 }
766 }
768
767
769 #graph_content .container .wrapper {
768 #graph_content .container .wrapper {
770 width: 600px;
769 width: 600px;
771 }
770 }
772
771
773 #graph_content .container {
772 #graph_content .container {
774 border-bottom: 1px solid #CCCCCC;
773 border-bottom: 1px solid #CCCCCC;
775 border-left: 1px solid #CCCCCC;
774 border-left: 1px solid #CCCCCC;
776 border-right: 1px solid #CCCCCC;
775 border-right: 1px solid #CCCCCC;
777 height: 120px;
776 min-height: 80px;
777 overflow: hidden;
778 }
778 }
779
779
780 #graph_content .container .left {
780 #graph_content .container .left {
781 float: left;
781 float: left;
782 width: 70%;
782 width: 70%;
783 padding-left: 5px;
783 padding-left: 5px;
784 }
784 }
785
785
786 #graph_content .container .right {
786 #graph_content .container .right {
787 float: right;
787 float: right;
788 width: 25%;
788 width: 25%;
789 text-align: right;
789 text-align: right;
790 }
790 }
791
791
792 #graph_content .container .left .date {
792 #graph_content .container .left .date {
793 font-weight: bold;
793 font-weight: bold;
794 }
794 }
795
795
796 #graph_content .container .left .author {
796 #graph_content .container .left .author {
797
797
798 }
798 }
799
799
800 #graph_content .container .left .message {
800 #graph_content .container .left .message {
801 font-size: 80%;
801 font-size: 80%;
802 }
802 }
803
803
804 .right div {
804 .right div {
805 clear: both;
805 clear: both;
806 }
806 }
807
807
808 .right .changes .added,.changed,.removed {
808 .right .changes .added,.changed,.removed {
809 border: 1px solid #DDDDDD;
809 border: 1px solid #DDDDDD;
810 display: block;
810 display: block;
811 float: right;
811 float: right;
812 font-size: 0.75em;
812 font-size: 0.75em;
813 text-align: center;
813 text-align: center;
814 min-width: 15px;
814 min-width: 15px;
815 }
815 }
816
816
817 .right .changes .added {
817 .right .changes .added {
818 background: #BBFFBB;
818 background: #BBFFBB;
819 }
819 }
820
820
821 .right .changes .changed {
821 .right .changes .changed {
822 background: #FFDD88;
822 background: #FFDD88;
823 }
823 }
824
824
825 .right .changes .removed {
825 .right .changes .removed {
826 background: #FF8888;
826 background: #FF8888;
827 }
827 }
828
828
829 .right .merge {
829 .right .merge {
830 vertical-align: top;
830 vertical-align: top;
831 font-size: 60%;
831 font-size: 60%;
832 font-weight: bold;
832 font-weight: bold;
833 }
833 }
834
834
835 .right .merge img {
835 .right .merge img {
836 vertical-align: bottom;
836 vertical-align: bottom;
837 }
837 }
838
838
839 .right .parent {
839 .right .parent {
840 font-size: 90%;
840 font-size: 90%;
841 font-family: monospace;
841 font-family: monospace;
842 }
842 }
843
843
844 /** end of canvas **/ /* FILE BROWSER */
844 /** end of canvas **/ /* FILE BROWSER */
845 div.browserblock {
845 div.browserblock {
846 overflow: hidden;
846 overflow: hidden;
847 padding: 0px;
847 padding: 0px;
848 border: 1px solid #ccc;
848 border: 1px solid #ccc;
849 background: #f8f8f8;
849 background: #f8f8f8;
850 font-size: 100%;
850 font-size: 100%;
851 line-height: 100%;
851 line-height: 100%;
852 /* new */
852 /* new */
853 line-height: 125%;
853 line-height: 125%;
854 }
854 }
855
855
856 div.browserblock .browser-header {
856 div.browserblock .browser-header {
857 border-bottom: 1px solid #CCCCCC;
857 border-bottom: 1px solid #CCCCCC;
858 background: #EEEEEE;
858 background: #EEEEEE;
859 color: blue;
859 color: blue;
860 padding: 10px 0 10px 0;
860 padding: 10px 0 10px 0;
861 }
861 }
862
862
863 div.browserblock .browser-header span {
863 div.browserblock .browser-header span {
864 margin-left: 25px;
864 margin-left: 25px;
865 font-weight: bold;
865 font-weight: bold;
866 }
866 }
867
867
868 div.browserblock .browser-body {
868 div.browserblock .browser-body {
869 background: #EEEEEE;
869 background: #EEEEEE;
870 }
870 }
871
871
872 table.code-browser {
872 table.code-browser {
873 border-collapse: collapse;
873 border-collapse: collapse;
874 width: 100%;
874 width: 100%;
875 }
875 }
876
876
877 table.code-browser tr {
877 table.code-browser tr {
878 margin: 3px;
878 margin: 3px;
879 }
879 }
880
880
881 table.code-browser thead th {
881 table.code-browser thead th {
882 background-color: #EEEEEE;
882 background-color: #EEEEEE;
883 height: 20px;
883 height: 20px;
884 font-size: 1.1em;
884 font-size: 1.1em;
885 font-weight: bold;
885 font-weight: bold;
886 text-align: center;
886 text-align: center;
887 text-align: left;
887 text-align: left;
888 padding-left: 10px;
888 padding-left: 10px;
889 }
889 }
890
890
891 table.code-browser tbody tr {
891 table.code-browser tbody tr {
892
892
893 }
893 }
894
894
895 table.code-browser tbody td {
895 table.code-browser tbody td {
896 padding-left: 10px;
896 padding-left: 10px;
897 height: 20px;
897 height: 20px;
898 }
898 }
899
899
900 .info-table {
900 .info-table {
901 background: none repeat scroll 0 0 #FAFAFA;
901 background: none repeat scroll 0 0 #FAFAFA;
902 border-bottom: 1px solid #DDDDDD;
902 border-bottom: 1px solid #DDDDDD;
903 width: 100%;
903 width: 100%;
904 }
904 }
905
905
906 .rss_logo {
906 .rss_logo {
907 background: url("/images/icons/rss_16.png") no-repeat scroll 3px;
907 background: url("/images/icons/rss_16.png") no-repeat scroll 3px;
908 height: 16px;
908 height: 16px;
909 padding-left: 20px;
909 padding-left: 20px;
910 padding-top: 0px;
910 padding-top: 0px;
911 text-align: left;
911 text-align: left;
912 }
912 }
913
913
914 .atom_logo {
914 .atom_logo {
915 background: url("/images/icons/atom.png") no-repeat scroll 3px;
915 background: url("/images/icons/atom.png") no-repeat scroll 3px;
916 height: 16px;
916 height: 16px;
917 padding-left: 20px;
917 padding-left: 20px;
918 padding-top: 0px;
918 padding-top: 0px;
919 text-align: left;
919 text-align: left;
920 }
920 }
921
921
922 .archive_logo {
922 .archive_logo {
923 background: url("/images/icons/compress.png") no-repeat scroll 3px;
923 background: url("/images/icons/compress.png") no-repeat scroll 3px;
924 height: 16px;
924 height: 16px;
925 padding-left: 20px;
925 padding-left: 20px;
926 text-align: left;
926 text-align: left;
927 }
927 }
928
928
929 .browser-file {
929 .browser-file {
930 background: url("/images/icons/document_16.png") no-repeat scroll 3px;
930 background: url("/images/icons/document_16.png") no-repeat scroll 3px;
931 height: 16px;
931 height: 16px;
932 padding-left: 20px;
932 padding-left: 20px;
933 text-align: left;
933 text-align: left;
934 }
934 }
935
935
936 .browser-dir {
936 .browser-dir {
937 background: url("/images/icons/folder_16.png") no-repeat scroll 3px;
937 background: url("/images/icons/folder_16.png") no-repeat scroll 3px;
938 height: 16px;
938 height: 16px;
939 padding-left: 20px;
939 padding-left: 20px;
940 text-align: left;
940 text-align: left;
941 }
941 }
942
942
943 #repos_list {
943 #repos_list {
944 border: 1px solid #556CB5;
944 border: 1px solid #556CB5;
945 background: #FFFFFF;
945 background: #FFFFFF;
946 } No newline at end of file
946 }
@@ -1,132 +1,135
1 // branch_renderer.js - Rendering of branch DAGs on the client side
1 // branch_renderer.js - Rendering of branch DAGs on the client side
2 //
2 //
3 // Copyright 2010 Marcin Kuzminski <marcin AT python-works DOT com>
3 // Copyright 2008 Jesper Noehr <jesper AT noehr DOT org>
4 // Copyright 2008 Jesper Noehr <jesper AT noehr DOT org>
4 // Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
5 // Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
5 // Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
6 // Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
6 //
7 //
7 // derived from code written by Scott James Remnant <scott@ubuntu.com>
8 // derived from code written by Scott James Remnant <scott@ubuntu.com>
8 // Copyright 2005 Canonical Ltd.
9 // Copyright 2005 Canonical Ltd.
9 //
10 //
10 // This software may be used and distributed according to the terms
11 // This software may be used and distributed according to the terms
11 // of the GNU General Public License, incorporated herein by reference.
12 // of the GNU General Public License, incorporated herein by reference.
12
13
13 var colors = [
14 var colors = [
14 [ 1.0, 0.0, 0.0 ],
15 [ 1.0, 0.0, 0.0 ],
15 [ 1.0, 1.0, 0.0 ],
16 [ 1.0, 1.0, 0.0 ],
16 [ 0.0, 1.0, 0.0 ],
17 [ 0.0, 1.0, 0.0 ],
17 [ 0.0, 1.0, 1.0 ],
18 [ 0.0, 1.0, 1.0 ],
18 [ 0.0, 0.0, 1.0 ],
19 [ 0.0, 0.0, 1.0 ],
19 [ 1.0, 0.0, 1.0 ],
20 [ 1.0, 0.0, 1.0 ],
20 [ 1.0, 1.0, 0.0 ],
21 [ 1.0, 1.0, 0.0 ],
21 [ 0.0, 0.0, 0.0 ]
22 [ 0.0, 0.0, 0.0 ]
22 ];
23 ];
23
24
24 function BranchRenderer() {
25 function BranchRenderer() {
25
26
26 this.canvas = document.getElementById("graph_canvas");
27 this.canvas = document.getElementById("graph_canvas");
27
28
28 if (navigator.userAgent.indexOf('MSIE') >= 0)
29 if (navigator.userAgent.indexOf('MSIE') >= 0)
29 this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
30 this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
30 this.ctx = this.canvas.getContext('2d');
31 this.ctx = this.canvas.getContext('2d');
31 this.ctx.strokeStyle = 'rgb(0, 0, 0)';
32 this.ctx.strokeStyle = 'rgb(0, 0, 0)';
32 this.ctx.fillStyle = 'rgb(0, 0, 0)';
33 this.ctx.fillStyle = 'rgb(0, 0, 0)';
33 this.cur = [0, 0];
34 this.cur = [0, 0];
34 this.max_column = 1;
35 this.max_column = 1;
35 this.line_width = 3;
36 this.line_width = 2.5;
37 this.dot_radius = 5.5;
36 this.bg = [0, 4];
38 this.bg = [0, 4];
37 this.cell = [2, 0];
39 this.cell = [2, 0];
38 this.revlink = '';
40 this.revlink = '';
39
41
40 this.scale = function(height) {
42 this.scale = function(height) {
41 this.box_size = Math.floor(height/1.2);
43 this.box_size = Math.floor(height/1.2);
42 this.cell_height = this.box_size;
44 this.cell_height = this.box_size;
43 this.bg_height = height;
45 this.bg_height = height;
44 }
46 }
45
47
46 this.setColor = function(color, bg, fg) {
48 this.setColor = function(color, bg, fg) {
47 color %= colors.length;
49 color %= colors.length;
48 var red = (colors[color][0] * fg) || bg;
50 var red = (colors[color][0] * fg) || bg;
49 var green = (colors[color][1] * fg) || bg;
51 var green = (colors[color][1] * fg) || bg;
50 var blue = (colors[color][2] * fg) || bg;
52 var blue = (colors[color][2] * fg) || bg;
51 red = Math.round(red * 255);
53 red = Math.round(red * 255);
52 green = Math.round(green * 255);
54 green = Math.round(green * 255);
53 blue = Math.round(blue * 255);
55 blue = Math.round(blue * 255);
54 var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
56 var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
55 this.ctx.strokeStyle = s;
57 this.ctx.strokeStyle = s;
56 this.ctx.fillStyle = s;
58 this.ctx.fillStyle = s;
57 }
59 }
58
60
59 this.render = function(data) {
61 this.render = function(data) {
60 var idx = 1;
62 var idx = 1;
61 var rela = document.getElementById('graph');
63 var rela = document.getElementById('graph');
62 var pad = 160;
64 var pad = 160;
63 var scale = 20;
65 var scale = 22;
64
66
65 for (var i in data) {
67 for (var i in data) {
66 this.scale(scale);
68 this.scale(scale);
67 var row = document.getElementById("chg_"+idx);
69 var row = document.getElementById("chg_"+idx);
68 var next = document.getElementById("chg_"+idx+1);
70 var next = document.getElementById("chg_"+idx+1);
69 var extra = 0;
71 var extra = 0;
70
72
71 //skip this since i don't have DATE in my app
73 //skip this since i don't have DATE in my app
72 //if (next.is('.changesets-date')) {
74 //if (next.is('.changesets-date')) {
73 // extra = next.outerHeight();
75 // extra = next.outerHeight();
74 //}
76 //}
75
77
76
78
77 this.cell[1] += row.clientWidth;
79 this.cell[1] += row.clientWidth;
78 this.bg[1] += this.bg_height;
80 this.bg[1] += this.bg_height;
79
81
80 cur = data[i];
82 cur = data[i];
81 nodeid = cur[0];
83 nodeid = cur[0];
82 node = cur[1];
84 node = cur[1];
83 in_l = cur[2];
85 in_l = cur[2];
84
86
85 for (var j in in_l) {
87 for (var j in in_l) {
86
88
87 line = in_l[j];
89 line = in_l[j];
88 start = line[0];
90 start = line[0];
89 end = line[1];
91 end = line[1];
90 color = line[2];
92 color = line[2];
91
93
92 if (start > this.max_column) {
94 if (start > this.max_column) {
93 this.max_column = start;
95 this.max_column = start;
94 }
96 }
95
97
96 if (end > this.max_column) {
98 if (end > this.max_column) {
97 this.max_column = end;
99 this.max_column = end;
98 }
100 }
99
101
100 this.setColor(color, 0.0, 0.65);
102 this.setColor(color, 0.0, 0.65);
101
103
102
104
103 y = row.offsetTop-rela.offsetTop+4;
105 y = row.offsetTop-rela.offsetTop+4;
104 x = pad-((this.cell[0] + this.box_size * start - 1) + this.bg_height-2);
106 x = pad-((this.cell[0] + this.box_size * start - 1) + this.bg_height-2);
107 this.ctx.lineWidth=this.line_width;
105 this.ctx.beginPath();
108 this.ctx.beginPath();
106 this.ctx.moveTo(x, y);
109 this.ctx.moveTo(x, y);
107
110
108 //i don't know why it's +1 just fixes some drawing graph.
111 //i don't know why it's +1 just fixes some drawing graph.
109 y += row.clientHeight+1;
112 y += row.clientHeight+1;
110 x = pad-((1 + this.box_size * end) + this.bg_height-2);
113 x = pad-((1 + this.box_size * end) + this.bg_height-2);
111 this.ctx.lineTo(x,y+extra);
114 this.ctx.lineTo(x,y+extra,3);
112 this.ctx.stroke();
115 this.ctx.stroke();
113 }
116 }
114
117
115 column = node[0]
118 column = node[0]
116 color = node[1]
119 color = node[1]
117
120
118 radius = 4;
121 radius = this.dot_radius;
119 y = row.offsetTop-rela.offsetTop+4;
122 y = row.offsetTop-rela.offsetTop+4;
120 x = pad-(Math.round(this.cell[0] * scale/2 * column + radius) + 15 - (column*4));
123 x = pad-(Math.round(this.cell[0] * scale/2 * column + radius) + 15 - (column*4));
121
124
122 this.ctx.beginPath();
125 this.ctx.beginPath();
123 this.setColor(color, 0.25, 0.75);
126 this.setColor(color, 0.25, 0.75);
124 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
127 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
125 this.ctx.fill();
128 this.ctx.fill();
126
129
127 idx++;
130 idx++;
128 }
131 }
129
132
130 }
133 }
131
134
132 }
135 }
@@ -1,108 +1,108
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${_('Changelog - %s') % c.repo_name}
4 ${_('Changelog - %s') % c.repo_name}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 ${h.link_to(u'Home',h.url('/'))}
7 ${h.link_to(u'Home',h.url('/'))}
8 /
8 /
9 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
9 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
10 /
10 /
11 ${_('changelog')}
11 ${_('changelog')}
12 </%def>
12 </%def>
13 <%def name="page_nav()">
13 <%def name="page_nav()">
14 ${self.menu('changelog')}
14 ${self.menu('changelog')}
15 </%def>
15 </%def>
16
16
17 <%def name="main()">
17 <%def name="main()">
18
18
19 <h2 class="no-link no-border">${_('Changelog')} - ${_('showing ')}
19 <h2 class="no-link no-border">${_('Changelog')} - ${_('showing ')}
20 ${c.size if c.size <= c.total_cs else c.total_cs}
20 ${c.size if c.size <= c.total_cs else c.total_cs}
21 ${_('out of')} ${c.total_cs} ${_('revisions')}
21 ${_('out of')} ${c.total_cs} ${_('revisions')}
22 </h2>
22 </h2>
23 <noscript>${_('The revision graph only works with JavaScript-enabled browsers.')}</noscript>
23 <noscript>${_('The revision graph only works with JavaScript-enabled browsers.')}</noscript>
24 % if c.pagination:
24 % if c.pagination:
25
25
26 <div id="graph">
26 <div id="graph">
27 <div id="graph_nodes">
27 <div id="graph_nodes">
28 <canvas id="graph_canvas"></canvas>
28 <canvas id="graph_canvas"></canvas>
29 </div>
29 </div>
30 <div id="graph_content">
30 <div id="graph_content">
31 <div class="container_header">
31 <div class="container_header">
32 ${h.form(h.url.current(),method='get')}
32 ${h.form(h.url.current(),method='get')}
33 <div>
33 <div>
34 <span>${_('Show')}: </span>
34 <span>${_('Show')}: </span>
35 <span>${h.text('size',size=2,value=c.size)}</span>
35 <span>${h.text('size',size=2,value=c.size)}</span>
36 <span>${_('revisions')}</span>
36 <span>${_('revisions')}</span>
37 ${h.submit('set',_('set'))}
37 ${h.submit('set',_('set'))}
38 </div>
38 </div>
39 ${h.end_form()}
39 ${h.end_form()}
40 </div>
40 </div>
41 %for cnt,cs in enumerate(c.pagination):
41 %for cnt,cs in enumerate(c.pagination):
42 <div id="chg_${cnt+1}" class="container">
42 <div id="chg_${cnt+1}" class="container">
43 <div class="left">
43 <div class="left">
44 <div class="date">${_('commit')} ${cs.revision}: ${cs.raw_id}@${cs.date}</div>
44 <div class="date">${_('commit')} ${cs.revision}: ${cs.raw_id}@${cs.date}</div>
45 <div class="author">${cs.author}</div>
46 <div class="message">
47 ${h.link_to(h.wrap_paragraphs(cs.message),
48 h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
49 </div>
50 <span class="logtags">
45 <span class="logtags">
51 <span class="branchtag">${cs.branch}</span>
46 <span class="branchtag">${cs.branch}</span>
52 %for tag in cs.tags:
47 %for tag in cs.tags:
53 <span class="tagtag">${tag}</span>
48 <span class="tagtag">${tag}</span>
54 %endfor
49 %endfor
55 </span>
50 </span>
51 <div class="author">${cs.author}</div>
52 <div class="message">
53 ${h.link_to(h.wrap_paragraphs(cs.message),
54 h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
55 </div>
56 </div>
56 </div>
57 <div class="right">
57 <div class="right">
58 <div class="changes">
58 <div class="changes">
59 <span class="removed" title="${_('removed')}">${len(cs.removed)}</span>
59 <span class="removed" title="${_('removed')}">${len(cs.removed)}</span>
60 <span class="changed" title="${_('changed')}">${len(cs.changed)}</span>
60 <span class="changed" title="${_('changed')}">${len(cs.changed)}</span>
61 <span class="added" title="${_('added')}">${len(cs.added)}</span>
61 <span class="added" title="${_('added')}">${len(cs.added)}</span>
62 </div>
62 </div>
63 %if len(cs.parents)>1:
63 %if len(cs.parents)>1:
64 <div class="merge">
64 <div class="merge">
65 ${_('merge')}<img alt="merge" src="/images/icons/arrow_join.png"/>
65 ${_('merge')}<img alt="merge" src="/images/icons/arrow_join.png"/>
66 </div>
66 </div>
67 %endif
67 %endif
68 %for p_cs in reversed(cs.parents):
68 %for p_cs in reversed(cs.parents):
69 <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id,
69 <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id,
70 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
70 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
71 </div>
71 </div>
72 %endfor
72 %endfor
73 </div>
73 </div>
74 </div>
74 </div>
75
75
76 %endfor
76 %endfor
77 </div>
77 </div>
78 </div>
78 </div>
79 <script type="text/javascript" src="/js/graph.js"></script>
79 <script type="text/javascript" src="/js/graph.js"></script>
80
80
81 <script type="text/javascript">
81 <script type="text/javascript">
82 YAHOO.util.Event.onDOMReady(function(){
82 YAHOO.util.Event.onDOMReady(function(){
83 function set_canvas() {
83 function set_canvas() {
84 var c = document.getElementById('graph_nodes');
84 var c = document.getElementById('graph_nodes');
85 var t = document.getElementById('graph_content');
85 var t = document.getElementById('graph_content');
86 canvas = document.getElementById('graph_canvas');
86 canvas = document.getElementById('graph_canvas');
87 var div_h = t.clientHeight;
87 var div_h = t.clientHeight;
88 c.style.height=div_h+'px';
88 c.style.height=div_h+'px';
89 canvas.setAttribute('height',div_h);
89 canvas.setAttribute('height',div_h);
90 canvas.setAttribute('width',160);
90 canvas.setAttribute('width',160);
91 };
91 };
92
92
93 set_canvas();
93 set_canvas();
94
94
95 var jsdata = ${c.jsdata|n};
95 var jsdata = ${c.jsdata|n};
96 var r = new BranchRenderer();
96 var r = new BranchRenderer();
97 r.render(jsdata);
97 r.render(jsdata);
98
98
99 });
99 });
100 </script>
100 </script>
101
101
102 <div>
102 <div>
103 <h2>${c.pagination.pager('$link_previous ~2~ $link_next')}</h2>
103 <h2>${c.pagination.pager('$link_previous ~2~ $link_next')}</h2>
104 </div>
104 </div>
105 %else:
105 %else:
106 ${_('There are no changes yet')}
106 ${_('There are no changes yet')}
107 %endif
107 %endif
108 </%def> No newline at end of file
108 </%def>
General Comments 0
You need to be logged in to leave comments. Login now