##// END OF EJS Templates
Adding the context bar too all pages related to a Repository....
Leonardo -
r3527:87c97fce beta
parent child Browse files
Show More
@@ -0,0 +1,330 b''
1 /**
2 * Stylesheets for the context bar
3 */
4
5 #context-bar button.follow { background-image: url("../images/icons/heart.png"); }
6 #context-bar button.following { background-image: url("../images/icons/heart_delete.png"); }
7 #context-bar a.fork { background-image: url("../images/icons/arrow_divide.png"); }
8 #context-bar a.summary { background-image: url("../images/icons/clipboard_16.png"); }
9 #context-bar a.changelogs { background-image: url("../images/icons/time.png"); }
10 #context-bar a.files { background-image: url("../images/icons/file.png"); }
11 #context-bar a.switch-to { background-image: url("../images/icons/arrow_switch.png"); }
12 #context-bar a.options { background-image: url("../images/icons/table_gear.png"); }
13 #context-bar a.pull-request { background-image: url("../images/icons/arrow_join.png"); }
14 #context-bar a.branches { background-image: url("../images/icons/arrow_branch.png"); }
15 #context-bar a.tags { background-image: url("../images/icons/tag_blue.png"); }
16 #context-bar a.bookmarks { background-image: url("../images/icons/tag_green.png"); }
17 #context-bar a.settings { background-image: url("../images/icons/cog.png"); }
18 #context-bar a.shortlog { background-image: url("../images/icons/time.png"); }
19 #context-bar a.search { background-image: url("../images/icons/search_16.png"); }
20 #context-bar a.admin { background-image: url("../images/icons/cog_edit.png"); }
21
22 #context-bar a.journal { background-image: url("../images/icons/book.png"); }
23 #context-bar a.repos { background-image: url("../images/icons/database_edit.png"); }
24 #context-bar a.repos_groups { background-image: url("../images/icons/database_link.png"); }
25 #context-bar a.users { background-image: url("../images/icons/user_edit.png"); }
26 #context-bar a.groups { background-image: url("../images/icons/group_edit.png"); }
27 #context-bar a.permissions { background-image: url("../images/icons/key.png"); }
28 #context-bar a.ldap { background-image: url("../images/icons/server_key.png"); }
29 #context-bar a.defaults { background-image: url("../images/icons/wrench.png"); }
30 #context-bar a.settings { background-image: url("../images/icons/cog_edit.png"); }
31
32 #content #context-bar {
33 position: relative;
34 background-color: #003B76 !important;
35 padding: 0px;
36 overflow: visible;
37 }
38
39 #content #context-bar,
40 #content #context-bar a,
41 #content #context-bar button {
42 color: #FFFFFF;
43 }
44
45 #content #context-bar a:hover,
46 #content #context-bar button:hover {
47 text-decoration: none;
48 color: #bfe3ff;
49 }
50
51 #content #context-bar .icon {
52 display: inline-block;
53 width: 16px;
54 height: 16px;
55 vertical-align: text-bottom;
56 }
57
58 ul.horizontal-list {
59 display: block;
60 /* overflow: hidden;*/
61 }
62 ul.horizontal-list > li {
63 float: left;
64 padding-right: 5px;
65 position: relative;
66 }
67
68 ul.horizontal-list > li ul {
69 position: absolute;
70 display: none;
71 right: 0;
72 }
73
74 ul.horizontal-list li:hover > ul {
75 display: block;
76 }
77
78 ul.horizontal-list ul li {
79 position: relative;
80 border-bottom: 1px solid rgba(0,0,0,0.1);
81 border-top: 1px solid rgba(255,255,255,0.1);
82 }
83
84 ul.horizontal-list > li ul ul {
85 position: absolute;
86 right: 100%;
87 top: -1px;
88 min-width: 200px;
89 max-height: 400px;
90 overflow-x:hidden;
91 overflow-y:auto;
92 }
93
94 ul.horizontal-list > li a {
95 white-space: nowrap;
96 }
97
98 #breadcrumbs {
99 float:left;
100 padding: 12px 0;
101 font-weight: bold;
102 }
103
104 #breadcrumbs span{
105 font-weight: bold;
106 font-size: 2em;
107 }
108
109 #context-top {
110 position: relative;
111 overflow: hidden;
112 border-bottom: 1px solid #003162;
113 padding: 10px;
114 }
115
116 #revision-changer,
117 #context-pages,
118 #context-pages ul,
119 ul#context-actions {
120 background: #3b6998; /* Old browsers */
121 background: -moz-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* FF3.6+ */
122 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4574a2), color-stop(100%,#2f5d8b)); /* Chrome,Safari4+ */
123 background: -webkit-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* Chrome10+,Safari5.1+ */
124 background: -o-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* Opera 11.10+ */
125 background: -ms-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* IE10+ */
126 background: linear-gradient(to bottom, #4574a2 0%, #2f5d8b 100%); /* W3C */
127 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4574a2', endColorstr='#2f5d8b',GradientType=0 ); /* IE6-9 */
128 }
129
130 #context-actions a,
131 #context-pages a {
132 background-repeat: no-repeat;
133 background-position: 10px 50%;
134 padding-left: 30px;
135 }
136
137 #context-pages ul ul a{
138 padding-left: 10px;
139 }
140
141 ul#context-actions {
142 display: inline-block;
143 float: right;
144 border-radius: 4px;
145 background-color:#3b6998;
146 background-image: linear-gradient(top, #4574a2 0%, #2f5d8b 100%);
147 padding: 5px;
148 }
149
150 #content ul#context-actions li {
151 padding: 0px;
152 border-right: 1px solid rgba(0,0,0,0.1);
153 border-left: 1px solid rgba(255,255,255,0.1);
154 }
155
156 #context-actions button,
157 #context-actions a {
158 display: block;
159 cursor: pointer;
160 background: none;
161 border: none;
162 margin: 0px;
163 height: 13px;
164 padding: 3px 7px;
165 background-repeat: no-repeat;
166 background-position: 50% 3px;
167 padding-top: 24px;
168 }
169
170 #context-actions button{
171 padding-top: 22px;
172 height: 40px;
173 }
174
175 #revision-changer:hover,
176 #context-pages li:hover,
177 #context-actions li:hover,
178 #content #context-actions li:hover {
179 /*background: rgba(255,255,255,0.2);*/
180 background: #6388ad; /* Old browsers */
181 background: -moz-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* FF3.6+ */
182 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
183 background: -webkit-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
184 background: -o-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* Opera 11.10+ */
185 background: -ms-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* IE10+ */
186 background: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* W3C */
187 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#88bfe8', endColorstr='#70b0e0',GradientType=0 ); /* IE6-9 */
188
189 background-image: -webkit-gradient(linear, left top, left bottom, rgb(255,255,255) 0%, rgb(255,255,255) 100%);
190
191 /*border-radius: 4px;*/
192 }
193
194
195 #content #context-actions li:first-child {
196 border-left: none;
197 border-radius:4px 0 0px 4px;
198 }
199
200 #content #context-actions li:last-child {
201 border-right: none;
202 border-radius:0 4px 4px 0;
203 }
204
205 #content #context-actions .icon{
206 margin: auto;
207 margin-bottom: 5px;
208 display: block;
209 clear: both;
210 float: none;
211 }
212
213 #content #context-actions button.follow,
214 #content #context-actions button.following{
215 width: auto;
216 float: none;
217 }
218
219 #content #context-actions button .show-following,
220 #content #context-actions button .show-follow {
221 display: none;
222 }
223
224 #content #context-bar #context-actions button.follow .show-follow {
225 display: block;
226 }
227
228 #content #context-bar #context-actions button.following .show-following {
229 display: block;
230 }
231
232 #context-state {
233 background-color: #336699;
234 border-top: 1px solid #517da8;
235 /* overflow: hidden;*/
236 }
237
238 #context-pages {
239 float: right;
240 border-left: 1px solid rgba(0,0,0,0.1);
241 /* overflow: hidden;*/
242 }
243
244 #context-pages li.current{
245 background: #535353; /* Old browsers */
246 background: -moz-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* FF3.6+ */
247 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#5d5d5d), color-stop(100%,#484848)); /* Chrome,Safari4+ */
248 background: -webkit-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* Chrome10+,Safari5.1+ */
249 background: -o-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* Opera 11.10+ */
250 background: -ms-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* IE10+ */
251 background: linear-gradient(to bottom, #5d5d5d 0%, #484848 100%); /* W3C */
252 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#5d5d5d', endColorstr='#484848',GradientType=0 ); /* IE6-9 */
253 }
254
255 #content #context-pages .icon {
256 margin-right:5px;
257 }
258
259 #content #context-pages li {
260 border-right: 1px solid rgba(0,0,0,0.1);
261 border-left: 1px solid rgba(255,255,255,0.1);
262 padding: 0;
263 }
264
265 #content #context-pages li:last-child {
266 border-right:none;
267 }
268
269 #context-pages a,
270 #context-pages .admin_menu a{
271 display: block;
272 padding: 0px 10px;
273 padding-left: 30px;
274 line-height: 35px;
275 }
276
277 #revision-changer:before,
278 #context-pages a.childs:after,
279 #context-pages a.dropdown:after {
280 content: ' \25BE';
281 }
282 #context-pages a.childs:after{
283 float: right;
284 padding-left: 5px;
285 }
286
287 #revision-changer:before {
288 position: absolute;
289 top: 0px;
290 right: 0px;
291 border-right: 1px solid rgba(0,0,0,0.1);
292 height: 25px;
293 padding-top: 10px;
294 padding-right: 10px;
295 }
296
297 #context-pages li:last-child a {
298 padding-right: 10px;
299 }
300
301 #context-bar #revision-changer {
302 position: relative;
303 cursor: pointer;
304 border: none;
305 padding: 0;
306 margin: 0;
307 color: #FFFFFF;
308 font-size: 0.85em;
309 padding: 2px 15px;
310 padding-bottom: 3px;
311 padding-right: 30px;
312 border-right: 1px solid rgba(255,255,255,0.1);
313 }
314
315 #revision-changer .branch-name,
316 #revision-changer .revision {
317 display: block;
318 text-align: center;
319 line-height: 1.5em;
320 }
321
322 #revision-changer .branch-name {
323 font-weight: bold;
324 }
325
326 #revision-changer .revision{
327 text-transform: uppercase;
328 }
329
330
@@ -1,338 +1,342 b''
1 1 """The base Controller API
2 2
3 3 Provides the BaseController class for subclassing.
4 4 """
5 5 import logging
6 6 import time
7 7 import traceback
8 8
9 9 from paste.auth.basic import AuthBasicAuthenticator
10 10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden
11 11 from paste.httpheaders import WWW_AUTHENTICATE, AUTHORIZATION
12 12
13 13 from pylons import config, tmpl_context as c, request, session, url
14 14 from pylons.controllers import WSGIController
15 15 from pylons.controllers.util import redirect
16 16 from pylons.templating import render_mako as render
17 17
18 18 from rhodecode import __version__, BACKENDS
19 19
20 20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
21 21 safe_str, safe_int
22 22 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
23 23 HasPermissionAnyMiddleware, CookieStoreWrapper
24 24 from rhodecode.lib.utils import get_repo_slug, invalidate_cache
25 25 from rhodecode.model import meta
26 26
27 27 from rhodecode.model.db import Repository, RhodeCodeUi, User, RhodeCodeSetting
28 28 from rhodecode.model.notification import NotificationModel
29 29 from rhodecode.model.scm import ScmModel
30 30 from rhodecode.model.meta import Session
31 31
32 32 log = logging.getLogger(__name__)
33 33
34 34
35 35 def _get_ip_addr(environ):
36 36 proxy_key = 'HTTP_X_REAL_IP'
37 37 proxy_key2 = 'HTTP_X_FORWARDED_FOR'
38 38 def_key = 'REMOTE_ADDR'
39 39
40 40 ip = environ.get(proxy_key)
41 41 if ip:
42 42 return ip
43 43
44 44 ip = environ.get(proxy_key2)
45 45 if ip:
46 46 # HTTP_X_FORWARDED_FOR can have mutliple ips inside
47 47 # the left-most being the original client, and each successive proxy
48 48 # that passed the request adding the IP address where it received the
49 49 # request from.
50 50 if ',' in ip:
51 51 ip = ip.split(',')[0].strip()
52 52 return ip
53 53
54 54 ip = environ.get(def_key, '0.0.0.0')
55 55 return ip
56 56
57 57
58 58 def _get_access_path(environ):
59 59 path = environ.get('PATH_INFO')
60 60 org_req = environ.get('pylons.original_request')
61 61 if org_req:
62 62 path = org_req.environ.get('PATH_INFO')
63 63 return path
64 64
65 65
66 66 class BasicAuth(AuthBasicAuthenticator):
67 67
68 68 def __init__(self, realm, authfunc, auth_http_code=None):
69 69 self.realm = realm
70 70 self.authfunc = authfunc
71 71 self._rc_auth_http_code = auth_http_code
72 72
73 73 def build_authentication(self):
74 74 head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
75 75 if self._rc_auth_http_code and self._rc_auth_http_code == '403':
76 76 # return 403 if alternative http return code is specified in
77 77 # RhodeCode config
78 78 return HTTPForbidden(headers=head)
79 79 return HTTPUnauthorized(headers=head)
80 80
81 81 def authenticate(self, environ):
82 82 authorization = AUTHORIZATION(environ)
83 83 if not authorization:
84 84 return self.build_authentication()
85 85 (authmeth, auth) = authorization.split(' ', 1)
86 86 if 'basic' != authmeth.lower():
87 87 return self.build_authentication()
88 88 auth = auth.strip().decode('base64')
89 89 _parts = auth.split(':', 1)
90 90 if len(_parts) == 2:
91 91 username, password = _parts
92 92 if self.authfunc(environ, username, password):
93 93 return username
94 94 return self.build_authentication()
95 95
96 96 __call__ = authenticate
97 97
98 98
99 99 class BaseVCSController(object):
100 100
101 101 def __init__(self, application, config):
102 102 self.application = application
103 103 self.config = config
104 104 # base path of repo locations
105 105 self.basepath = self.config['base_path']
106 106 #authenticate this mercurial request using authfunc
107 107 self.authenticate = BasicAuth('', authfunc,
108 108 config.get('auth_ret_code'))
109 109 self.ip_addr = '0.0.0.0'
110 110
111 111 def _handle_request(self, environ, start_response):
112 112 raise NotImplementedError()
113 113
114 114 def _get_by_id(self, repo_name):
115 115 """
116 116 Get's a special pattern _<ID> from clone url and tries to replace it
117 117 with a repository_name for support of _<ID> non changable urls
118 118
119 119 :param repo_name:
120 120 """
121 121 try:
122 122 data = repo_name.split('/')
123 123 if len(data) >= 2:
124 124 by_id = data[1].split('_')
125 125 if len(by_id) == 2 and by_id[1].isdigit():
126 126 _repo_name = Repository.get(by_id[1]).repo_name
127 127 data[1] = _repo_name
128 128 except:
129 129 log.debug('Failed to extract repo_name from id %s' % (
130 130 traceback.format_exc()
131 131 )
132 132 )
133 133
134 134 return '/'.join(data)
135 135
136 136 def _invalidate_cache(self, repo_name):
137 137 """
138 138 Set's cache for this repository for invalidation on next access
139 139
140 140 :param repo_name: full repo name, also a cache key
141 141 """
142 142 invalidate_cache('get_repo_cached_%s' % repo_name)
143 143
144 144 def _check_permission(self, action, user, repo_name, ip_addr=None):
145 145 """
146 146 Checks permissions using action (push/pull) user and repository
147 147 name
148 148
149 149 :param action: push or pull action
150 150 :param user: user instance
151 151 :param repo_name: repository name
152 152 """
153 153 #check IP
154 154 authuser = AuthUser(user_id=user.user_id, ip_addr=ip_addr)
155 155 if not authuser.ip_allowed:
156 156 return False
157 157 else:
158 158 log.info('Access for IP:%s allowed' % (ip_addr))
159 159 if action == 'push':
160 160 if not HasPermissionAnyMiddleware('repository.write',
161 161 'repository.admin')(user,
162 162 repo_name):
163 163 return False
164 164
165 165 else:
166 166 #any other action need at least read permission
167 167 if not HasPermissionAnyMiddleware('repository.read',
168 168 'repository.write',
169 169 'repository.admin')(user,
170 170 repo_name):
171 171 return False
172 172
173 173 return True
174 174
175 175 def _get_ip_addr(self, environ):
176 176 return _get_ip_addr(environ)
177 177
178 178 def _check_ssl(self, environ, start_response):
179 179 """
180 180 Checks the SSL check flag and returns False if SSL is not present
181 181 and required True otherwise
182 182 """
183 183 org_proto = environ['wsgi._org_proto']
184 184 #check if we have SSL required ! if not it's a bad request !
185 185 require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value)
186 186 if require_ssl and org_proto == 'http':
187 187 log.debug('proto is %s and SSL is required BAD REQUEST !'
188 188 % org_proto)
189 189 return False
190 190 return True
191 191
192 192 def _check_locking_state(self, environ, action, repo, user_id):
193 193 """
194 194 Checks locking on this repository, if locking is enabled and lock is
195 195 present returns a tuple of make_lock, locked, locked_by.
196 196 make_lock can have 3 states None (do nothing) True, make lock
197 197 False release lock, This value is later propagated to hooks, which
198 198 do the locking. Think about this as signals passed to hooks what to do.
199 199
200 200 """
201 201 locked = False # defines that locked error should be thrown to user
202 202 make_lock = None
203 203 repo = Repository.get_by_repo_name(repo)
204 204 user = User.get(user_id)
205 205
206 206 # this is kind of hacky, but due to how mercurial handles client-server
207 207 # server see all operation on changeset; bookmarks, phases and
208 208 # obsolescence marker in different transaction, we don't want to check
209 209 # locking on those
210 210 obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',]
211 211 locked_by = repo.locked
212 212 if repo and repo.enable_locking and not obsolete_call:
213 213 if action == 'push':
214 214 #check if it's already locked !, if it is compare users
215 215 user_id, _date = repo.locked
216 216 if user.user_id == user_id:
217 217 log.debug('Got push from user %s, now unlocking' % (user))
218 218 # unlock if we have push from user who locked
219 219 make_lock = False
220 220 else:
221 221 # we're not the same user who locked, ban with 423 !
222 222 locked = True
223 223 if action == 'pull':
224 224 if repo.locked[0] and repo.locked[1]:
225 225 locked = True
226 226 else:
227 227 log.debug('Setting lock on repo %s by %s' % (repo, user))
228 228 make_lock = True
229 229
230 230 else:
231 231 log.debug('Repository %s do not have locking enabled' % (repo))
232 232 log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s'
233 233 % (make_lock, locked, locked_by))
234 234 return make_lock, locked, locked_by
235 235
236 236 def __call__(self, environ, start_response):
237 237 start = time.time()
238 238 try:
239 239 return self._handle_request(environ, start_response)
240 240 finally:
241 241 log = logging.getLogger('rhodecode.' + self.__class__.__name__)
242 242 log.debug('Request time: %.3fs' % (time.time() - start))
243 243 meta.Session.remove()
244 244
245 245
246 246 class BaseController(WSGIController):
247 247
248 248 def __before__(self):
249 249 """
250 250 __before__ is called before controller methods and after __call__
251 251 """
252 252 c.rhodecode_version = __version__
253 253 c.rhodecode_instanceid = config.get('instance_id')
254 254 c.rhodecode_name = config.get('rhodecode_title')
255 255 c.use_gravatar = str2bool(config.get('use_gravatar'))
256 256 c.ga_code = config.get('rhodecode_ga_code')
257 257 # Visual options
258 258 c.visual = AttributeDict({})
259 259 rc_config = RhodeCodeSetting.get_app_settings()
260 260
261 261 c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
262 262 c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
263 263 c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
264 264 c.visual.lightweight_dashboard = str2bool(rc_config.get('rhodecode_lightweight_dashboard'))
265 265 c.visual.lightweight_dashboard_items = safe_int(config.get('dashboard_items', 100))
266 266 c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
267 267
268 268 c.repo_name = get_repo_slug(request)
269 269 c.backends = BACKENDS.keys()
270 270 c.unread_notifications = NotificationModel()\
271 271 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
272 272 self.cut_off_limit = int(config.get('cut_off_limit'))
273 273
274 274 self.sa = meta.Session
275 275 self.scm_model = ScmModel(self.sa)
276 276
277 277 def __call__(self, environ, start_response):
278 278 """Invoke the Controller"""
279 279 # WSGIController.__call__ dispatches to the Controller method
280 280 # the request is routed to. This routing information is
281 281 # available in environ['pylons.routes_dict']
282 282 start = time.time()
283 283 try:
284 284 self.ip_addr = _get_ip_addr(environ)
285 285 # make sure that we update permissions each time we call controller
286 286 api_key = request.GET.get('api_key')
287 287 cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
288 288 user_id = cookie_store.get('user_id', None)
289 289 username = get_container_username(environ, config)
290 290 auth_user = AuthUser(user_id, api_key, username, self.ip_addr)
291 291 request.user = auth_user
292 292 self.rhodecode_user = c.rhodecode_user = auth_user
293 293 if not self.rhodecode_user.is_authenticated and \
294 294 self.rhodecode_user.user_id is not None:
295 295 self.rhodecode_user.set_authenticated(
296 296 cookie_store.get('is_authenticated')
297 297 )
298 298 log.info('IP: %s User: %s accessed %s' % (
299 299 self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
300 300 )
301 301 return WSGIController.__call__(self, environ, start_response)
302 302 finally:
303 303 log.info('IP: %s Request to %s time: %.3fs' % (
304 304 _get_ip_addr(environ),
305 305 safe_unicode(_get_access_path(environ)), time.time() - start)
306 306 )
307 307 meta.Session.remove()
308 308
309 309
310 310 class BaseRepoController(BaseController):
311 311 """
312 312 Base class for controllers responsible for loading all needed data for
313 313 repository loaded items are
314 314
315 315 c.rhodecode_repo: instance of scm repository
316 316 c.rhodecode_db_repo: instance of db
317 317 c.repository_followers: number of followers
318 318 c.repository_forks: number of forks
319 c.repository_following: weather the current user is following the current repo
320
319 321 """
320 322
321 323 def __before__(self):
322 324 super(BaseRepoController, self).__before__()
323 325 if c.repo_name:
324 326
325 327 dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
326 328 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
327 329 # update last change according to VCS data
328 330 dbr.update_changeset_cache(dbr.get_changeset())
329 331 if c.rhodecode_repo is None:
330 332 log.error('%s this repository is present in database but it '
331 333 'cannot be created as an scm instance', c.repo_name)
332 334
333 335 redirect(url('home'))
334 336
335 337 # some globals counter for menu
336 338 c.repository_followers = self.scm_model.get_followers(dbr)
337 339 c.repository_forks = self.scm_model.get_forks(dbr)
338 340 c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
341 c.repository_following = self.scm_model.is_following_repo(c.repo_name,
342 self.rhodecode_user.user_id)
@@ -1,1189 +1,1189 b''
1 1 """Helper functions
2 2
3 3 Consists of functions to typically be used within templates, but also
4 4 available to Controllers. This module is available to both as 'h'.
5 5 """
6 6 import random
7 7 import hashlib
8 8 import StringIO
9 9 import urllib
10 10 import math
11 11 import logging
12 12 import re
13 13 import urlparse
14 14 import textwrap
15 15
16 16 from datetime import datetime
17 17 from pygments.formatters.html import HtmlFormatter
18 18 from pygments import highlight as code_highlight
19 19 from pylons import url, request, config
20 20 from pylons.i18n.translation import _, ungettext
21 21 from hashlib import md5
22 22
23 23 from webhelpers.html import literal, HTML, escape
24 24 from webhelpers.html.tools import *
25 25 from webhelpers.html.builder import make_tag
26 26 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
27 27 end_form, file, form, hidden, image, javascript_link, link_to, \
28 28 link_to_if, link_to_unless, ol, required_legend, select, stylesheet_link, \
29 29 submit, text, password, textarea, title, ul, xml_declaration, radio
30 30 from webhelpers.html.tools import auto_link, button_to, highlight, \
31 31 js_obfuscate, mail_to, strip_links, strip_tags, tag_re
32 32 from webhelpers.number import format_byte_size, format_bit_size
33 33 from webhelpers.pylonslib import Flash as _Flash
34 34 from webhelpers.pylonslib.secure_form import secure_form
35 35 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
36 36 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
37 37 replace_whitespace, urlify, truncate, wrap_paragraphs
38 38 from webhelpers.date import time_ago_in_words
39 39 from webhelpers.paginate import Page
40 40 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
41 41 convert_boolean_attrs, NotGiven, _make_safe_id_component
42 42
43 43 from rhodecode.lib.annotate import annotate_highlight
44 44 from rhodecode.lib.utils import repo_name_slug, get_custom_lexer
45 45 from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \
46 46 get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict
47 47 from rhodecode.lib.markup_renderer import MarkupRenderer
48 48 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
49 49 from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyChangeset
50 50 from rhodecode.config.conf import DATE_FORMAT, DATETIME_FORMAT
51 51 from rhodecode.model.changeset_status import ChangesetStatusModel
52 52 from rhodecode.model.db import URL_SEP, Permission
53 53
54 54 log = logging.getLogger(__name__)
55 55
56 56
57 57 html_escape_table = {
58 58 "&": "&amp;",
59 59 '"': "&quot;",
60 60 "'": "&apos;",
61 61 ">": "&gt;",
62 62 "<": "&lt;",
63 63 }
64 64
65 65
66 66 def html_escape(text):
67 67 """Produce entities within text."""
68 68 return "".join(html_escape_table.get(c, c) for c in text)
69 69
70 70
71 71 def shorter(text, size=20):
72 72 postfix = '...'
73 73 if len(text) > size:
74 74 return text[:size - len(postfix)] + postfix
75 75 return text
76 76
77 77
78 78 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
79 79 """
80 80 Reset button
81 81 """
82 82 _set_input_attrs(attrs, type, name, value)
83 83 _set_id_attr(attrs, id, name)
84 84 convert_boolean_attrs(attrs, ["disabled"])
85 85 return HTML.input(**attrs)
86 86
87 87 reset = _reset
88 88 safeid = _make_safe_id_component
89 89
90 90
91 91 def FID(raw_id, path):
92 92 """
93 93 Creates a uniqe ID for filenode based on it's hash of path and revision
94 94 it's safe to use in urls
95 95
96 96 :param raw_id:
97 97 :param path:
98 98 """
99 99
100 100 return 'C-%s-%s' % (short_id(raw_id), md5(safe_str(path)).hexdigest()[:12])
101 101
102 102
103 103 def get_token():
104 104 """Return the current authentication token, creating one if one doesn't
105 105 already exist.
106 106 """
107 107 token_key = "_authentication_token"
108 108 from pylons import session
109 109 if not token_key in session:
110 110 try:
111 111 token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
112 112 except AttributeError: # Python < 2.4
113 113 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
114 114 session[token_key] = token
115 115 if hasattr(session, 'save'):
116 116 session.save()
117 117 return session[token_key]
118 118
119 119
120 120 class _GetError(object):
121 121 """Get error from form_errors, and represent it as span wrapped error
122 122 message
123 123
124 124 :param field_name: field to fetch errors for
125 125 :param form_errors: form errors dict
126 126 """
127 127
128 128 def __call__(self, field_name, form_errors):
129 129 tmpl = """<span class="error_msg">%s</span>"""
130 130 if form_errors and field_name in form_errors:
131 131 return literal(tmpl % form_errors.get(field_name))
132 132
133 133 get_error = _GetError()
134 134
135 135
136 136 class _ToolTip(object):
137 137
138 138 def __call__(self, tooltip_title, trim_at=50):
139 139 """
140 140 Special function just to wrap our text into nice formatted
141 141 autowrapped text
142 142
143 143 :param tooltip_title:
144 144 """
145 145 tooltip_title = escape(tooltip_title)
146 146 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
147 147 return tooltip_title
148 148 tooltip = _ToolTip()
149 149
150 150
151 151 class _FilesBreadCrumbs(object):
152 152
153 153 def __call__(self, repo_name, rev, paths):
154 154 if isinstance(paths, str):
155 155 paths = safe_unicode(paths)
156 156 url_l = [link_to(repo_name, url('files_home',
157 157 repo_name=repo_name,
158 158 revision=rev, f_path=''),
159 159 class_='ypjax-link')]
160 160 paths_l = paths.split('/')
161 161 for cnt, p in enumerate(paths_l):
162 162 if p != '':
163 163 url_l.append(link_to(p,
164 164 url('files_home',
165 165 repo_name=repo_name,
166 166 revision=rev,
167 167 f_path='/'.join(paths_l[:cnt + 1])
168 168 ),
169 169 class_='ypjax-link'
170 170 )
171 171 )
172 172
173 173 return literal('/'.join(url_l))
174 174
175 175 files_breadcrumbs = _FilesBreadCrumbs()
176 176
177 177
178 178 class CodeHtmlFormatter(HtmlFormatter):
179 179 """
180 180 My code Html Formatter for source codes
181 181 """
182 182
183 183 def wrap(self, source, outfile):
184 184 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
185 185
186 186 def _wrap_code(self, source):
187 187 for cnt, it in enumerate(source):
188 188 i, t = it
189 189 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
190 190 yield i, t
191 191
192 192 def _wrap_tablelinenos(self, inner):
193 193 dummyoutfile = StringIO.StringIO()
194 194 lncount = 0
195 195 for t, line in inner:
196 196 if t:
197 197 lncount += 1
198 198 dummyoutfile.write(line)
199 199
200 200 fl = self.linenostart
201 201 mw = len(str(lncount + fl - 1))
202 202 sp = self.linenospecial
203 203 st = self.linenostep
204 204 la = self.lineanchors
205 205 aln = self.anchorlinenos
206 206 nocls = self.noclasses
207 207 if sp:
208 208 lines = []
209 209
210 210 for i in range(fl, fl + lncount):
211 211 if i % st == 0:
212 212 if i % sp == 0:
213 213 if aln:
214 214 lines.append('<a href="#%s%d" class="special">%*d</a>' %
215 215 (la, i, mw, i))
216 216 else:
217 217 lines.append('<span class="special">%*d</span>' % (mw, i))
218 218 else:
219 219 if aln:
220 220 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
221 221 else:
222 222 lines.append('%*d' % (mw, i))
223 223 else:
224 224 lines.append('')
225 225 ls = '\n'.join(lines)
226 226 else:
227 227 lines = []
228 228 for i in range(fl, fl + lncount):
229 229 if i % st == 0:
230 230 if aln:
231 231 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
232 232 else:
233 233 lines.append('%*d' % (mw, i))
234 234 else:
235 235 lines.append('')
236 236 ls = '\n'.join(lines)
237 237
238 238 # in case you wonder about the seemingly redundant <div> here: since the
239 239 # content in the other cell also is wrapped in a div, some browsers in
240 240 # some configurations seem to mess up the formatting...
241 241 if nocls:
242 242 yield 0, ('<table class="%stable">' % self.cssclass +
243 243 '<tr><td><div class="linenodiv" '
244 244 'style="background-color: #f0f0f0; padding-right: 10px">'
245 245 '<pre style="line-height: 125%">' +
246 246 ls + '</pre></div></td><td id="hlcode" class="code">')
247 247 else:
248 248 yield 0, ('<table class="%stable">' % self.cssclass +
249 249 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
250 250 ls + '</pre></div></td><td id="hlcode" class="code">')
251 251 yield 0, dummyoutfile.getvalue()
252 252 yield 0, '</td></tr></table>'
253 253
254 254
255 255 def pygmentize(filenode, **kwargs):
256 256 """
257 257 pygmentize function using pygments
258 258
259 259 :param filenode:
260 260 """
261 261 lexer = get_custom_lexer(filenode.extension) or filenode.lexer
262 262 return literal(code_highlight(filenode.content, lexer,
263 263 CodeHtmlFormatter(**kwargs)))
264 264
265 265
266 266 def pygmentize_annotation(repo_name, filenode, **kwargs):
267 267 """
268 268 pygmentize function for annotation
269 269
270 270 :param filenode:
271 271 """
272 272
273 273 color_dict = {}
274 274
275 275 def gen_color(n=10000):
276 276 """generator for getting n of evenly distributed colors using
277 277 hsv color and golden ratio. It always return same order of colors
278 278
279 279 :returns: RGB tuple
280 280 """
281 281
282 282 def hsv_to_rgb(h, s, v):
283 283 if s == 0.0:
284 284 return v, v, v
285 285 i = int(h * 6.0) # XXX assume int() truncates!
286 286 f = (h * 6.0) - i
287 287 p = v * (1.0 - s)
288 288 q = v * (1.0 - s * f)
289 289 t = v * (1.0 - s * (1.0 - f))
290 290 i = i % 6
291 291 if i == 0:
292 292 return v, t, p
293 293 if i == 1:
294 294 return q, v, p
295 295 if i == 2:
296 296 return p, v, t
297 297 if i == 3:
298 298 return p, q, v
299 299 if i == 4:
300 300 return t, p, v
301 301 if i == 5:
302 302 return v, p, q
303 303
304 304 golden_ratio = 0.618033988749895
305 305 h = 0.22717784590367374
306 306
307 307 for _ in xrange(n):
308 308 h += golden_ratio
309 309 h %= 1
310 310 HSV_tuple = [h, 0.95, 0.95]
311 311 RGB_tuple = hsv_to_rgb(*HSV_tuple)
312 312 yield map(lambda x: str(int(x * 256)), RGB_tuple)
313 313
314 314 cgenerator = gen_color()
315 315
316 316 def get_color_string(cs):
317 317 if cs in color_dict:
318 318 col = color_dict[cs]
319 319 else:
320 320 col = color_dict[cs] = cgenerator.next()
321 321 return "color: rgb(%s)! important;" % (', '.join(col))
322 322
323 323 def url_func(repo_name):
324 324
325 325 def _url_func(changeset):
326 326 author = changeset.author
327 327 date = changeset.date
328 328 message = tooltip(changeset.message)
329 329
330 330 tooltip_html = ("<div style='font-size:0.8em'><b>Author:</b>"
331 331 " %s<br/><b>Date:</b> %s</b><br/><b>Message:"
332 332 "</b> %s<br/></div>")
333 333
334 334 tooltip_html = tooltip_html % (author, date, message)
335 335 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
336 336 short_id(changeset.raw_id))
337 337 uri = link_to(
338 338 lnk_format,
339 339 url('changeset_home', repo_name=repo_name,
340 340 revision=changeset.raw_id),
341 341 style=get_color_string(changeset.raw_id),
342 342 class_='tooltip',
343 343 title=tooltip_html
344 344 )
345 345
346 346 uri += '\n'
347 347 return uri
348 348 return _url_func
349 349
350 350 return literal(annotate_highlight(filenode, url_func(repo_name), **kwargs))
351 351
352 352
353 353 def is_following_repo(repo_name, user_id):
354 354 from rhodecode.model.scm import ScmModel
355 355 return ScmModel().is_following_repo(repo_name, user_id)
356 356
357 357 flash = _Flash()
358 358
359 359 #==============================================================================
360 360 # SCM FILTERS available via h.
361 361 #==============================================================================
362 362 from rhodecode.lib.vcs.utils import author_name, author_email
363 363 from rhodecode.lib.utils2 import credentials_filter, age as _age
364 364 from rhodecode.model.db import User, ChangesetStatus
365 365
366 366 age = lambda x: _age(x)
367 367 capitalize = lambda x: x.capitalize()
368 368 email = author_email
369 369 short_id = lambda x: x[:12]
370 370 hide_credentials = lambda x: ''.join(credentials_filter(x))
371 371
372 372
373 373 def fmt_date(date):
374 374 if date:
375 375 _fmt = _(u"%a, %d %b %Y %H:%M:%S").encode('utf8')
376 376 return date.strftime(_fmt).decode('utf8')
377 377
378 378 return ""
379 379
380 380
381 381 def is_git(repository):
382 382 if hasattr(repository, 'alias'):
383 383 _type = repository.alias
384 384 elif hasattr(repository, 'repo_type'):
385 385 _type = repository.repo_type
386 386 else:
387 387 _type = repository
388 388 return _type == 'git'
389 389
390 390
391 391 def is_hg(repository):
392 392 if hasattr(repository, 'alias'):
393 393 _type = repository.alias
394 394 elif hasattr(repository, 'repo_type'):
395 395 _type = repository.repo_type
396 396 else:
397 397 _type = repository
398 398 return _type == 'hg'
399 399
400 400
401 401 def email_or_none(author):
402 402 # extract email from the commit string
403 403 _email = email(author)
404 404 if _email != '':
405 405 # check it against RhodeCode database, and use the MAIN email for this
406 406 # user
407 407 user = User.get_by_email(_email, case_insensitive=True, cache=True)
408 408 if user is not None:
409 409 return user.email
410 410 return _email
411 411
412 412 # See if it contains a username we can get an email from
413 413 user = User.get_by_username(author_name(author), case_insensitive=True,
414 414 cache=True)
415 415 if user is not None:
416 416 return user.email
417 417
418 418 # No valid email, not a valid user in the system, none!
419 419 return None
420 420
421 421
422 422 def person(author, show_attr="username_and_name"):
423 423 # attr to return from fetched user
424 424 person_getter = lambda usr: getattr(usr, show_attr)
425 425
426 426 # Valid email in the attribute passed, see if they're in the system
427 427 _email = email(author)
428 428 if _email != '':
429 429 user = User.get_by_email(_email, case_insensitive=True, cache=True)
430 430 if user is not None:
431 431 return person_getter(user)
432 432 return _email
433 433
434 434 # Maybe it's a username?
435 435 _author = author_name(author)
436 436 user = User.get_by_username(_author, case_insensitive=True,
437 437 cache=True)
438 438 if user is not None:
439 439 return person_getter(user)
440 440
441 441 # Still nothing? Just pass back the author name then
442 442 return _author
443 443
444 444
445 445 def person_by_id(id_, show_attr="username_and_name"):
446 446 # attr to return from fetched user
447 447 person_getter = lambda usr: getattr(usr, show_attr)
448 448
449 449 #maybe it's an ID ?
450 450 if str(id_).isdigit() or isinstance(id_, int):
451 451 id_ = int(id_)
452 452 user = User.get(id_)
453 453 if user is not None:
454 454 return person_getter(user)
455 455 return id_
456 456
457 457
458 458 def desc_stylize(value):
459 459 """
460 460 converts tags from value into html equivalent
461 461
462 462 :param value:
463 463 """
464 464 value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
465 465 '<div class="metatag" tag="see">see =&gt; \\1 </div>', value)
466 466 value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
467 467 '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', value)
468 468 value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]',
469 469 '<div class="metatag" tag="\\1">\\1 =&gt; <a href="/\\2">\\2</a></div>', value)
470 470 value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+]*)\]',
471 471 '<div class="metatag" tag="lang">\\2</div>', value)
472 472 value = re.sub(r'\[([a-z]+)\]',
473 473 '<div class="metatag" tag="\\1">\\1</div>', value)
474 474
475 475 return value
476 476
477 477
478 478 def bool2icon(value):
479 479 """Returns True/False values represented as small html image of true/false
480 480 icons
481 481
482 482 :param value: bool value
483 483 """
484 484
485 485 if value is True:
486 486 return HTML.tag('img', src=url("/images/icons/accept.png"),
487 487 alt=_('True'))
488 488
489 489 if value is False:
490 490 return HTML.tag('img', src=url("/images/icons/cancel.png"),
491 491 alt=_('False'))
492 492
493 493 return value
494 494
495 495
496 496 def action_parser(user_log, feed=False, parse_cs=False):
497 497 """
498 498 This helper will action_map the specified string action into translated
499 499 fancy names with icons and links
500 500
501 501 :param user_log: user log instance
502 502 :param feed: use output for feeds (no html and fancy icons)
503 503 :param parse_cs: parse Changesets into VCS instances
504 504 """
505 505
506 506 action = user_log.action
507 507 action_params = ' '
508 508
509 509 x = action.split(':')
510 510
511 511 if len(x) > 1:
512 512 action, action_params = x
513 513
514 514 def get_cs_links():
515 515 revs_limit = 3 # display this amount always
516 516 revs_top_limit = 50 # show upto this amount of changesets hidden
517 517 revs_ids = action_params.split(',')
518 518 deleted = user_log.repository is None
519 519 if deleted:
520 520 return ','.join(revs_ids)
521 521
522 522 repo_name = user_log.repository.repo_name
523 523
524 524 def lnk(rev, repo_name):
525 525 if isinstance(rev, BaseChangeset) or isinstance(rev, AttributeDict):
526 526 lazy_cs = True
527 527 if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
528 528 lazy_cs = False
529 529 lbl = '?'
530 530 if rev.op == 'delete_branch':
531 531 lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
532 532 title = ''
533 533 elif rev.op == 'tag':
534 534 lbl = '%s' % _('Created tag: %s') % rev.ref_name
535 535 title = ''
536 536 _url = '#'
537 537
538 538 else:
539 539 lbl = '%s' % (rev.short_id[:8])
540 540 _url = url('changeset_home', repo_name=repo_name,
541 541 revision=rev.raw_id)
542 542 title = tooltip(rev.message)
543 543 else:
544 544 ## changeset cannot be found/striped/removed etc.
545 545 lbl = ('%s' % rev)[:12]
546 546 _url = '#'
547 547 title = _('Changeset not found')
548 548 if parse_cs:
549 549 return link_to(lbl, _url, title=title, class_='tooltip')
550 550 return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
551 551 class_='lazy-cs' if lazy_cs else '')
552 552
553 553 revs = []
554 554 if len(filter(lambda v: v != '', revs_ids)) > 0:
555 555 repo = None
556 556 for rev in revs_ids[:revs_top_limit]:
557 557 _op = _name = None
558 558 if len(rev.split('=>')) == 2:
559 559 _op, _name = rev.split('=>')
560 560
561 561 # we want parsed changesets, or new log store format is bad
562 562 if parse_cs:
563 563 try:
564 564 if repo is None:
565 565 repo = user_log.repository.scm_instance
566 566 _rev = repo.get_changeset(rev)
567 567 revs.append(_rev)
568 568 except ChangesetDoesNotExistError:
569 569 log.error('cannot find revision %s in this repo' % rev)
570 570 revs.append(rev)
571 571 continue
572 572 else:
573 573 _rev = AttributeDict({
574 574 'short_id': rev[:12],
575 575 'raw_id': rev,
576 576 'message': '',
577 577 'op': _op,
578 578 'ref_name': _name
579 579 })
580 580 revs.append(_rev)
581 581 cs_links = []
582 582 cs_links.append(" " + ', '.join(
583 583 [lnk(rev, repo_name) for rev in revs[:revs_limit]]
584 584 )
585 585 )
586 586
587 587 compare_view = (
588 588 ' <div class="compare_view tooltip" title="%s">'
589 589 '<a href="%s">%s</a> </div>' % (
590 590 _('Show all combined changesets %s->%s') % (
591 591 revs_ids[0][:12], revs_ids[-1][:12]
592 592 ),
593 593 url('changeset_home', repo_name=repo_name,
594 594 revision='%s...%s' % (revs_ids[0], revs_ids[-1])
595 595 ),
596 596 _('compare view')
597 597 )
598 598 )
599 599
600 600 # if we have exactly one more than normally displayed
601 601 # just display it, takes less space than displaying
602 602 # "and 1 more revisions"
603 603 if len(revs_ids) == revs_limit + 1:
604 604 rev = revs[revs_limit]
605 605 cs_links.append(", " + lnk(rev, repo_name))
606 606
607 607 # hidden-by-default ones
608 608 if len(revs_ids) > revs_limit + 1:
609 609 uniq_id = revs_ids[0]
610 610 html_tmpl = (
611 611 '<span> %s <a class="show_more" id="_%s" '
612 612 'href="#more">%s</a> %s</span>'
613 613 )
614 614 if not feed:
615 615 cs_links.append(html_tmpl % (
616 616 _('and'),
617 617 uniq_id, _('%s more') % (len(revs_ids) - revs_limit),
618 618 _('revisions')
619 619 )
620 620 )
621 621
622 622 if not feed:
623 623 html_tmpl = '<span id="%s" style="display:none">, %s </span>'
624 624 else:
625 625 html_tmpl = '<span id="%s"> %s </span>'
626 626
627 627 morelinks = ', '.join(
628 628 [lnk(rev, repo_name) for rev in revs[revs_limit:]]
629 629 )
630 630
631 631 if len(revs_ids) > revs_top_limit:
632 632 morelinks += ', ...'
633 633
634 634 cs_links.append(html_tmpl % (uniq_id, morelinks))
635 635 if len(revs) > 1:
636 636 cs_links.append(compare_view)
637 637 return ''.join(cs_links)
638 638
639 639 def get_fork_name():
640 640 repo_name = action_params
641 641 _url = url('summary_home', repo_name=repo_name)
642 642 return _('fork name %s') % link_to(action_params, _url)
643 643
644 644 def get_user_name():
645 645 user_name = action_params
646 646 return user_name
647 647
648 648 def get_users_group():
649 649 group_name = action_params
650 650 return group_name
651 651
652 652 def get_pull_request():
653 653 pull_request_id = action_params
654 654 deleted = user_log.repository is None
655 655 if deleted:
656 656 repo_name = user_log.repository_name
657 657 else:
658 658 repo_name = user_log.repository.repo_name
659 659 return link_to(_('Pull request #%s') % pull_request_id,
660 660 url('pullrequest_show', repo_name=repo_name,
661 661 pull_request_id=pull_request_id))
662 662
663 663 # action : translated str, callback(extractor), icon
664 664 action_map = {
665 665 'user_deleted_repo': (_('[deleted] repository'),
666 666 None, 'database_delete.png'),
667 667 'user_created_repo': (_('[created] repository'),
668 668 None, 'database_add.png'),
669 669 'user_created_fork': (_('[created] repository as fork'),
670 670 None, 'arrow_divide.png'),
671 671 'user_forked_repo': (_('[forked] repository'),
672 672 get_fork_name, 'arrow_divide.png'),
673 673 'user_updated_repo': (_('[updated] repository'),
674 674 None, 'database_edit.png'),
675 675 'admin_deleted_repo': (_('[delete] repository'),
676 676 None, 'database_delete.png'),
677 677 'admin_created_repo': (_('[created] repository'),
678 678 None, 'database_add.png'),
679 679 'admin_forked_repo': (_('[forked] repository'),
680 680 None, 'arrow_divide.png'),
681 681 'admin_updated_repo': (_('[updated] repository'),
682 682 None, 'database_edit.png'),
683 683 'admin_created_user': (_('[created] user'),
684 684 get_user_name, 'user_add.png'),
685 685 'admin_updated_user': (_('[updated] user'),
686 686 get_user_name, 'user_edit.png'),
687 687 'admin_created_users_group': (_('[created] users group'),
688 688 get_users_group, 'group_add.png'),
689 689 'admin_updated_users_group': (_('[updated] users group'),
690 690 get_users_group, 'group_edit.png'),
691 691 'user_commented_revision': (_('[commented] on revision in repository'),
692 692 get_cs_links, 'comment_add.png'),
693 693 'user_commented_pull_request': (_('[commented] on pull request for'),
694 694 get_pull_request, 'comment_add.png'),
695 695 'user_closed_pull_request': (_('[closed] pull request for'),
696 696 get_pull_request, 'tick.png'),
697 697 'push': (_('[pushed] into'),
698 698 get_cs_links, 'script_add.png'),
699 699 'push_local': (_('[committed via RhodeCode] into repository'),
700 700 get_cs_links, 'script_edit.png'),
701 701 'push_remote': (_('[pulled from remote] into repository'),
702 702 get_cs_links, 'connect.png'),
703 703 'pull': (_('[pulled] from'),
704 704 None, 'down_16.png'),
705 705 'started_following_repo': (_('[started following] repository'),
706 706 None, 'heart_add.png'),
707 707 'stopped_following_repo': (_('[stopped following] repository'),
708 708 None, 'heart_delete.png'),
709 709 }
710 710
711 711 action_str = action_map.get(action, action)
712 712 if feed:
713 713 action = action_str[0].replace('[', '').replace(']', '')
714 714 else:
715 715 action = action_str[0]\
716 716 .replace('[', '<span class="journal_highlight">')\
717 717 .replace(']', '</span>')
718 718
719 719 action_params_func = lambda: ""
720 720
721 721 if callable(action_str[1]):
722 722 action_params_func = action_str[1]
723 723
724 724 def action_parser_icon():
725 725 action = user_log.action
726 726 action_params = None
727 727 x = action.split(':')
728 728
729 729 if len(x) > 1:
730 730 action, action_params = x
731 731
732 732 tmpl = """<img src="%s%s" alt="%s"/>"""
733 733 ico = action_map.get(action, ['', '', ''])[2]
734 734 return literal(tmpl % ((url('/images/icons/')), ico, action))
735 735
736 736 # returned callbacks we need to call to get
737 737 return [lambda: literal(action), action_params_func, action_parser_icon]
738 738
739 739
740 740
741 741 #==============================================================================
742 742 # PERMS
743 743 #==============================================================================
744 744 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
745 745 HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \
746 746 HasReposGroupPermissionAny
747 747
748 748
749 749 #==============================================================================
750 750 # GRAVATAR URL
751 751 #==============================================================================
752 752
753 753 def gravatar_url(email_address, size=30):
754 754 from pylons import url # doh, we need to re-import url to mock it later
755 755 _def = 'anonymous@rhodecode.org'
756 756 use_gravatar = str2bool(config['app_conf'].get('use_gravatar'))
757 757 email_address = email_address or _def
758 758 if (not use_gravatar or not email_address or email_address == _def):
759 759 f = lambda a, l: min(l, key=lambda x: abs(x - a))
760 760 return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30]))
761 761
762 762 if use_gravatar and config['app_conf'].get('alternative_gravatar_url'):
763 763 tmpl = config['app_conf'].get('alternative_gravatar_url', '')
764 764 parsed_url = urlparse.urlparse(url.current(qualified=True))
765 765 tmpl = tmpl.replace('{email}', email_address)\
766 766 .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \
767 767 .replace('{netloc}', parsed_url.netloc)\
768 768 .replace('{scheme}', parsed_url.scheme)\
769 769 .replace('{size}', str(size))
770 770 return tmpl
771 771
772 772 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
773 773 default = 'identicon'
774 774 baseurl_nossl = "http://www.gravatar.com/avatar/"
775 775 baseurl_ssl = "https://secure.gravatar.com/avatar/"
776 776 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
777 777
778 778 if isinstance(email_address, unicode):
779 779 #hashlib crashes on unicode items
780 780 email_address = safe_str(email_address)
781 781 # construct the url
782 782 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
783 783 gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
784 784
785 785 return gravatar_url
786 786
787 787
788 788 #==============================================================================
789 789 # REPO PAGER, PAGER FOR REPOSITORY
790 790 #==============================================================================
791 791 class RepoPage(Page):
792 792
793 793 def __init__(self, collection, page=1, items_per_page=20,
794 794 item_count=None, url=None, **kwargs):
795 795
796 796 """Create a "RepoPage" instance. special pager for paging
797 797 repository
798 798 """
799 799 self._url_generator = url
800 800
801 801 # Safe the kwargs class-wide so they can be used in the pager() method
802 802 self.kwargs = kwargs
803 803
804 804 # Save a reference to the collection
805 805 self.original_collection = collection
806 806
807 807 self.collection = collection
808 808
809 809 # The self.page is the number of the current page.
810 810 # The first page has the number 1!
811 811 try:
812 812 self.page = int(page) # make it int() if we get it as a string
813 813 except (ValueError, TypeError):
814 814 self.page = 1
815 815
816 816 self.items_per_page = items_per_page
817 817
818 818 # Unless the user tells us how many items the collections has
819 819 # we calculate that ourselves.
820 820 if item_count is not None:
821 821 self.item_count = item_count
822 822 else:
823 823 self.item_count = len(self.collection)
824 824
825 825 # Compute the number of the first and last available page
826 826 if self.item_count > 0:
827 827 self.first_page = 1
828 828 self.page_count = int(math.ceil(float(self.item_count) /
829 829 self.items_per_page))
830 830 self.last_page = self.first_page + self.page_count - 1
831 831
832 832 # Make sure that the requested page number is the range of
833 833 # valid pages
834 834 if self.page > self.last_page:
835 835 self.page = self.last_page
836 836 elif self.page < self.first_page:
837 837 self.page = self.first_page
838 838
839 839 # Note: the number of items on this page can be less than
840 840 # items_per_page if the last page is not full
841 841 self.first_item = max(0, (self.item_count) - (self.page *
842 842 items_per_page))
843 843 self.last_item = ((self.item_count - 1) - items_per_page *
844 844 (self.page - 1))
845 845
846 846 self.items = list(self.collection[self.first_item:self.last_item + 1])
847 847
848 848 # Links to previous and next page
849 849 if self.page > self.first_page:
850 850 self.previous_page = self.page - 1
851 851 else:
852 852 self.previous_page = None
853 853
854 854 if self.page < self.last_page:
855 855 self.next_page = self.page + 1
856 856 else:
857 857 self.next_page = None
858 858
859 859 # No items available
860 860 else:
861 861 self.first_page = None
862 862 self.page_count = 0
863 863 self.last_page = None
864 864 self.first_item = None
865 865 self.last_item = None
866 866 self.previous_page = None
867 867 self.next_page = None
868 868 self.items = []
869 869
870 870 # This is a subclass of the 'list' type. Initialise the list now.
871 871 list.__init__(self, reversed(self.items))
872 872
873 873
874 874 def changed_tooltip(nodes):
875 875 """
876 876 Generates a html string for changed nodes in changeset page.
877 877 It limits the output to 30 entries
878 878
879 879 :param nodes: LazyNodesGenerator
880 880 """
881 881 if nodes:
882 882 pref = ': <br/> '
883 883 suf = ''
884 884 if len(nodes) > 30:
885 885 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
886 886 return literal(pref + '<br/> '.join([safe_unicode(x.path)
887 887 for x in nodes[:30]]) + suf)
888 888 else:
889 889 return ': ' + _('No Files')
890 890
891 891
892 892 def repo_link(groups_and_repos, last_url=None):
893 893 """
894 894 Makes a breadcrumbs link to repo within a group
895 895 joins &raquo; on each group to create a fancy link
896 896
897 897 ex::
898 898 group >> subgroup >> repo
899 899
900 900 :param groups_and_repos:
901 901 :param last_url:
902 902 """
903 903 groups, repo_name = groups_and_repos
904 904 last_link = link_to(repo_name, last_url) if last_url else repo_name
905 905
906 906 if not groups:
907 907 if last_url:
908 return last_link
909 return repo_name
908 return literal('<span>%s</span>' % last_link)
909 return literal('<span>%s</span>' % repo_name)
910 910 else:
911 911 def make_link(group):
912 912 return link_to(group.name,
913 913 url('repos_group_home', group_name=group.group_name))
914 return literal(' &raquo; '.join(map(make_link, groups) + [last_link]))
914 return literal(' &raquo; '.join(map(make_link, groups) + ['<span>' + last_link + '</span>']))
915 915
916 916
917 917 def fancy_file_stats(stats):
918 918 """
919 919 Displays a fancy two colored bar for number of added/deleted
920 920 lines of code on file
921 921
922 922 :param stats: two element list of added/deleted lines of code
923 923 """
924 924 def cgen(l_type, a_v, d_v):
925 925 mapping = {'tr': 'top-right-rounded-corner-mid',
926 926 'tl': 'top-left-rounded-corner-mid',
927 927 'br': 'bottom-right-rounded-corner-mid',
928 928 'bl': 'bottom-left-rounded-corner-mid'}
929 929 map_getter = lambda x: mapping[x]
930 930
931 931 if l_type == 'a' and d_v:
932 932 #case when added and deleted are present
933 933 return ' '.join(map(map_getter, ['tl', 'bl']))
934 934
935 935 if l_type == 'a' and not d_v:
936 936 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
937 937
938 938 if l_type == 'd' and a_v:
939 939 return ' '.join(map(map_getter, ['tr', 'br']))
940 940
941 941 if l_type == 'd' and not a_v:
942 942 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
943 943
944 944 a, d = stats[0], stats[1]
945 945 width = 100
946 946
947 947 if a == 'b':
948 948 #binary mode
949 949 b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
950 950 b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
951 951 return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
952 952
953 953 t = stats[0] + stats[1]
954 954 unit = float(width) / (t or 1)
955 955
956 956 # needs > 9% of width to be visible or 0 to be hidden
957 957 a_p = max(9, unit * a) if a > 0 else 0
958 958 d_p = max(9, unit * d) if d > 0 else 0
959 959 p_sum = a_p + d_p
960 960
961 961 if p_sum > width:
962 962 #adjust the percentage to be == 100% since we adjusted to 9
963 963 if a_p > d_p:
964 964 a_p = a_p - (p_sum - width)
965 965 else:
966 966 d_p = d_p - (p_sum - width)
967 967
968 968 a_v = a if a > 0 else ''
969 969 d_v = d if d > 0 else ''
970 970
971 971 d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
972 972 cgen('a', a_v, d_v), a_p, a_v
973 973 )
974 974 d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
975 975 cgen('d', a_v, d_v), d_p, d_v
976 976 )
977 977 return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
978 978
979 979
980 980 def urlify_text(text_):
981 981 """
982 982 Extrac urls from text and make html links out of them
983 983
984 984 :param text_:
985 985 """
986 986
987 987 url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
988 988 '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
989 989
990 990 def url_func(match_obj):
991 991 url_full = match_obj.groups()[0]
992 992 return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
993 993
994 994 return literal(url_pat.sub(url_func, text_))
995 995
996 996
997 997 def urlify_changesets(text_, repository):
998 998 """
999 999 Extract revision ids from changeset and make link from them
1000 1000
1001 1001 :param text_:
1002 1002 :param repository: repo name to build the URL with
1003 1003 """
1004 1004 from pylons import url # doh, we need to re-import url to mock it later
1005 1005 URL_PAT = re.compile(r'(?:^|\s)([0-9a-fA-F]{12,40})(?:$|\s)')
1006 1006
1007 1007 def url_func(match_obj):
1008 1008 rev = match_obj.groups()[0]
1009 1009 pref = ''
1010 1010 suf = ''
1011 1011 if match_obj.group().startswith(' '):
1012 1012 pref = ' '
1013 1013 if match_obj.group().endswith(' '):
1014 1014 suf = ' '
1015 1015 tmpl = (
1016 1016 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1017 1017 '%(rev)s'
1018 1018 '</a>'
1019 1019 '%(suf)s'
1020 1020 )
1021 1021 return tmpl % {
1022 1022 'pref': pref,
1023 1023 'cls': 'revision-link',
1024 1024 'url': url('changeset_home', repo_name=repository, revision=rev),
1025 1025 'rev': rev,
1026 1026 'suf': suf
1027 1027 }
1028 1028
1029 1029 newtext = URL_PAT.sub(url_func, text_)
1030 1030
1031 1031 return newtext
1032 1032
1033 1033
1034 1034 def urlify_commit(text_, repository=None, link_=None):
1035 1035 """
1036 1036 Parses given text message and makes proper links.
1037 1037 issues are linked to given issue-server, and rest is a changeset link
1038 1038 if link_ is given, in other case it's a plain text
1039 1039
1040 1040 :param text_:
1041 1041 :param repository:
1042 1042 :param link_: changeset link
1043 1043 """
1044 1044 import traceback
1045 1045 from pylons import url # doh, we need to re-import url to mock it later
1046 1046
1047 1047 def escaper(string):
1048 1048 return string.replace('<', '&lt;').replace('>', '&gt;')
1049 1049
1050 1050 def linkify_others(t, l):
1051 1051 urls = re.compile(r'(\<a.*?\<\/a\>)',)
1052 1052 links = []
1053 1053 for e in urls.split(t):
1054 1054 if not urls.match(e):
1055 1055 links.append('<a class="message-link" href="%s">%s</a>' % (l, e))
1056 1056 else:
1057 1057 links.append(e)
1058 1058
1059 1059 return ''.join(links)
1060 1060
1061 1061 # urlify changesets - extrac revisions and make link out of them
1062 1062 newtext = urlify_changesets(escaper(text_), repository)
1063 1063
1064 1064 # extract http/https links and make them real urls
1065 1065 newtext = urlify_text(newtext)
1066 1066
1067 1067 try:
1068 1068 from rhodecode import CONFIG
1069 1069 conf = CONFIG
1070 1070
1071 1071 # allow multiple issue servers to be used
1072 1072 valid_indices = [
1073 1073 x.group(1)
1074 1074 for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys())
1075 1075 if x and 'issue_server_link%s' % x.group(1) in conf
1076 1076 and 'issue_prefix%s' % x.group(1) in conf
1077 1077 ]
1078 1078
1079 1079 log.debug('found issue server suffixes `%s` during valuation of: %s'
1080 1080 % (','.join(valid_indices), newtext))
1081 1081
1082 1082 for pattern_index in valid_indices:
1083 1083 ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index)
1084 1084 ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index)
1085 1085 ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index)
1086 1086
1087 1087 log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s'
1088 1088 % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK,
1089 1089 ISSUE_PREFIX))
1090 1090
1091 1091 URL_PAT = re.compile(r'%s' % ISSUE_PATTERN)
1092 1092
1093 1093 def url_func(match_obj):
1094 1094 pref = ''
1095 1095 if match_obj.group().startswith(' '):
1096 1096 pref = ' '
1097 1097
1098 1098 issue_id = ''.join(match_obj.groups())
1099 1099 tmpl = (
1100 1100 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1101 1101 '%(issue-prefix)s%(id-repr)s'
1102 1102 '</a>'
1103 1103 )
1104 1104 url = ISSUE_SERVER_LNK.replace('{id}', issue_id)
1105 1105 if repository:
1106 1106 url = url.replace('{repo}', repository)
1107 1107 repo_name = repository.split(URL_SEP)[-1]
1108 1108 url = url.replace('{repo_name}', repo_name)
1109 1109
1110 1110 return tmpl % {
1111 1111 'pref': pref,
1112 1112 'cls': 'issue-tracker-link',
1113 1113 'url': url,
1114 1114 'id-repr': issue_id,
1115 1115 'issue-prefix': ISSUE_PREFIX,
1116 1116 'serv': ISSUE_SERVER_LNK,
1117 1117 }
1118 1118 newtext = URL_PAT.sub(url_func, newtext)
1119 1119 log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext))
1120 1120
1121 1121 # if we actually did something above
1122 1122 if link_:
1123 1123 # wrap not links into final link => link_
1124 1124 newtext = linkify_others(newtext, link_)
1125 1125 except:
1126 1126 log.error(traceback.format_exc())
1127 1127 pass
1128 1128
1129 1129 return literal(newtext)
1130 1130
1131 1131
1132 1132 def rst(source):
1133 1133 return literal('<div class="rst-block">%s</div>' %
1134 1134 MarkupRenderer.rst(source))
1135 1135
1136 1136
1137 1137 def rst_w_mentions(source):
1138 1138 """
1139 1139 Wrapped rst renderer with @mention highlighting
1140 1140
1141 1141 :param source:
1142 1142 """
1143 1143 return literal('<div class="rst-block">%s</div>' %
1144 1144 MarkupRenderer.rst_with_mentions(source))
1145 1145
1146 1146
1147 1147 def changeset_status(repo, revision):
1148 1148 return ChangesetStatusModel().get_status(repo, revision)
1149 1149
1150 1150
1151 1151 def changeset_status_lbl(changeset_status):
1152 1152 return dict(ChangesetStatus.STATUSES).get(changeset_status)
1153 1153
1154 1154
1155 1155 def get_permission_name(key):
1156 1156 return dict(Permission.PERMS).get(key)
1157 1157
1158 1158
1159 1159 def journal_filter_help():
1160 1160 return _(textwrap.dedent('''
1161 1161 Example filter terms:
1162 1162 repository:vcs
1163 1163 username:marcin
1164 1164 action:*push*
1165 1165 ip:127.0.0.1
1166 1166 date:20120101
1167 1167 date:[20120101100000 TO 20120102]
1168 1168
1169 1169 Generate wildcards using '*' character:
1170 1170 "repositroy:vcs*" - search everything starting with 'vcs'
1171 1171 "repository:*vcs*" - search for repository containing 'vcs'
1172 1172
1173 1173 Optional AND / OR operators in queries
1174 1174 "repository:vcs OR repository:test"
1175 1175 "username:test AND repository:test*"
1176 1176 '''))
1177 1177
1178 1178
1179 1179 def not_mapped_error(repo_name):
1180 1180 flash(_('%s repository is not mapped to db perhaps'
1181 1181 ' it was created or renamed from the filesystem'
1182 1182 ' please run the application again'
1183 1183 ' in order to rescan repositories') % repo_name, category='error')
1184 1184
1185 1185
1186 1186 def ip_range(ip_addr):
1187 1187 from rhodecode.model.db import UserIpMap
1188 1188 s, e = UserIpMap._get_ip_range(ip_addr)
1189 1189 return '%s - %s' % (s, e)
@@ -1,4830 +1,4830 b''
1 1 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td {
2 2 border: 0;
3 3 outline: 0;
4 4 font-size: 100%;
5 5 vertical-align: baseline;
6 6 background: transparent;
7 7 margin: 0;
8 8 padding: 0;
9 9 }
10 10
11 11 body {
12 12 line-height: 1;
13 13 height: 100%;
14 14 background: url("../images/background.png") repeat scroll 0 0 #B0B0B0;
15 15 font-family: Lucida Grande, Verdana, Lucida Sans Regular,
16 16 Lucida Sans Unicode, Arial, sans-serif; font-size : 12px;
17 17 color: #000;
18 18 margin: 0;
19 19 padding: 0;
20 20 font-size: 12px;
21 21 }
22 22
23 23 ol, ul {
24 24 list-style: none;
25 25 }
26 26
27 27 blockquote, q {
28 28 quotes: none;
29 29 }
30 30
31 31 blockquote:before, blockquote:after, q:before, q:after {
32 32 content: none;
33 33 }
34 34
35 35 :focus {
36 36 outline: 0;
37 37 }
38 38
39 39 del {
40 40 text-decoration: line-through;
41 41 }
42 42
43 43 table {
44 44 border-collapse: collapse;
45 45 border-spacing: 0;
46 46 }
47 47
48 48 html {
49 49 height: 100%;
50 50 }
51 51
52 52 a {
53 53 color: #003367;
54 54 text-decoration: none;
55 55 cursor: pointer;
56 56 }
57 57
58 58 a:hover {
59 59 color: #316293;
60 60 text-decoration: underline;
61 61 }
62 62
63 63 h1, h2, h3, h4, h5, h6,
64 64 div.h1, div.h2, div.h3, div.h4, div.h5, div.h6 {
65 65 color: #292929;
66 66 font-weight: 700;
67 67 }
68 68
69 69 h1, div.h1 {
70 70 font-size: 22px;
71 71 }
72 72
73 73 h2, div.h2 {
74 74 font-size: 20px;
75 75 }
76 76
77 77 h3, div.h3 {
78 78 font-size: 18px;
79 79 }
80 80
81 81 h4, div.h4 {
82 82 font-size: 16px;
83 83 }
84 84
85 85 h5, div.h5 {
86 86 font-size: 14px;
87 87 }
88 88
89 89 h6, div.h6 {
90 90 font-size: 11px;
91 91 }
92 92
93 93 ul.circle {
94 94 list-style-type: circle;
95 95 }
96 96
97 97 ul.disc {
98 98 list-style-type: disc;
99 99 }
100 100
101 101 ul.square {
102 102 list-style-type: square;
103 103 }
104 104
105 105 ol.lower-roman {
106 106 list-style-type: lower-roman;
107 107 }
108 108
109 109 ol.upper-roman {
110 110 list-style-type: upper-roman;
111 111 }
112 112
113 113 ol.lower-alpha {
114 114 list-style-type: lower-alpha;
115 115 }
116 116
117 117 ol.upper-alpha {
118 118 list-style-type: upper-alpha;
119 119 }
120 120
121 121 ol.decimal {
122 122 list-style-type: decimal;
123 123 }
124 124
125 125 div.color {
126 126 clear: both;
127 127 overflow: hidden;
128 128 position: absolute;
129 129 background: #FFF;
130 130 margin: 7px 0 0 60px;
131 131 padding: 1px 1px 1px 0;
132 132 }
133 133
134 134 div.color a {
135 135 width: 15px;
136 136 height: 15px;
137 137 display: block;
138 138 float: left;
139 139 margin: 0 0 0 1px;
140 140 padding: 0;
141 141 }
142 142
143 143 div.options {
144 144 clear: both;
145 145 overflow: hidden;
146 146 position: absolute;
147 147 background: #FFF;
148 148 margin: 7px 0 0 162px;
149 149 padding: 0;
150 150 }
151 151
152 152 div.options a {
153 153 height: 1%;
154 154 display: block;
155 155 text-decoration: none;
156 156 margin: 0;
157 157 padding: 3px 8px;
158 158 }
159 159
160 160 .top-left-rounded-corner {
161 161 -webkit-border-top-left-radius: 8px;
162 162 -khtml-border-radius-topleft: 8px;
163 163 -moz-border-radius-topleft: 8px;
164 164 border-top-left-radius: 8px;
165 165 }
166 166
167 167 .top-right-rounded-corner {
168 168 -webkit-border-top-right-radius: 8px;
169 169 -khtml-border-radius-topright: 8px;
170 170 -moz-border-radius-topright: 8px;
171 171 border-top-right-radius: 8px;
172 172 }
173 173
174 174 .bottom-left-rounded-corner {
175 175 -webkit-border-bottom-left-radius: 8px;
176 176 -khtml-border-radius-bottomleft: 8px;
177 177 -moz-border-radius-bottomleft: 8px;
178 178 border-bottom-left-radius: 8px;
179 179 }
180 180
181 181 .bottom-right-rounded-corner {
182 182 -webkit-border-bottom-right-radius: 8px;
183 183 -khtml-border-radius-bottomright: 8px;
184 184 -moz-border-radius-bottomright: 8px;
185 185 border-bottom-right-radius: 8px;
186 186 }
187 187
188 188 .top-left-rounded-corner-mid {
189 189 -webkit-border-top-left-radius: 4px;
190 190 -khtml-border-radius-topleft: 4px;
191 191 -moz-border-radius-topleft: 4px;
192 192 border-top-left-radius: 4px;
193 193 }
194 194
195 195 .top-right-rounded-corner-mid {
196 196 -webkit-border-top-right-radius: 4px;
197 197 -khtml-border-radius-topright: 4px;
198 198 -moz-border-radius-topright: 4px;
199 199 border-top-right-radius: 4px;
200 200 }
201 201
202 202 .bottom-left-rounded-corner-mid {
203 203 -webkit-border-bottom-left-radius: 4px;
204 204 -khtml-border-radius-bottomleft: 4px;
205 205 -moz-border-radius-bottomleft: 4px;
206 206 border-bottom-left-radius: 4px;
207 207 }
208 208
209 209 .bottom-right-rounded-corner-mid {
210 210 -webkit-border-bottom-right-radius: 4px;
211 211 -khtml-border-radius-bottomright: 4px;
212 212 -moz-border-radius-bottomright: 4px;
213 213 border-bottom-right-radius: 4px;
214 214 }
215 215
216 216 .help-block {
217 217 color: #999999;
218 218 display: block;
219 219 margin-bottom: 0;
220 220 margin-top: 5px;
221 221 }
222 222
223 223 .empty_data {
224 224 color:#B9B9B9;
225 225 }
226 226
227 227 a.permalink {
228 228 visibility: hidden;
229 229 }
230 230
231 231 a.permalink:hover {
232 232 text-decoration: none;
233 233 }
234 234
235 235 h1:hover > a.permalink,
236 236 h2:hover > a.permalink,
237 237 h3:hover > a.permalink,
238 238 h4:hover > a.permalink,
239 239 h5:hover > a.permalink,
240 240 h6:hover > a.permalink,
241 241 div:hover > a.permalink {
242 242 visibility: visible;
243 243 }
244 244
245 245 #header {
246 246 }
247 247
248 248 #header ul#logged-user {
249 249 margin-bottom: 5px !important;
250 250 -webkit-border-radius: 0px 0px 8px 8px;
251 251 -khtml-border-radius: 0px 0px 8px 8px;
252 252 -moz-border-radius: 0px 0px 8px 8px;
253 253 border-radius: 0px 0px 8px 8px;
254 254 height: 37px;
255 255 background-color: #003B76;
256 256 background-repeat: repeat-x;
257 257 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
258 258 background-image: -moz-linear-gradient(top, #003b76, #00376e);
259 259 background-image: -ms-linear-gradient(top, #003b76, #00376e);
260 260 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
261 261 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
262 262 background-image: -o-linear-gradient(top, #003b76, #00376e);
263 263 background-image: linear-gradient(top, #003b76, #00376e);
264 264 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
265 265 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
266 266 }
267 267
268 268 #header ul#logged-user li {
269 269 list-style: none;
270 270 float: left;
271 271 margin: 8px 0 0;
272 272 padding: 4px 12px;
273 273 border-left: 1px solid #316293;
274 274 }
275 275
276 276 #header ul#logged-user li.first {
277 277 border-left: none;
278 278 margin: 4px;
279 279 }
280 280
281 281 #header ul#logged-user li.first div.gravatar {
282 282 margin-top: -2px;
283 283 }
284 284
285 285 #header ul#logged-user li.first div.account {
286 286 padding-top: 4px;
287 287 float: left;
288 288 }
289 289
290 290 #header ul#logged-user li.last {
291 291 border-right: none;
292 292 }
293 293
294 294 #header ul#logged-user li a {
295 295 color: #fff;
296 296 font-weight: 700;
297 297 text-decoration: none;
298 298 }
299 299
300 300 #header ul#logged-user li a:hover {
301 301 text-decoration: underline;
302 302 }
303 303
304 304 #header ul#logged-user li.highlight a {
305 305 color: #fff;
306 306 }
307 307
308 308 #header ul#logged-user li.highlight a:hover {
309 309 color: #FFF;
310 310 }
311 311 #header-dd {
312 312 clear: both;
313 313 position: fixed !important;
314 314 background-color: #003B76;
315 315 opacity: 0.01;
316 316 cursor: pointer;
317 317 min-height: 10px;
318 318 width: 100% !important;
319 319 -webkit-border-radius: 0px 0px 4px 4px;
320 320 -khtml-border-radius: 0px 0px 4px 4px;
321 321 -moz-border-radius: 0px 0px 4px 4px;
322 322 border-radius: 0px 0px 4px 4px;
323 323 }
324 324
325 325 #header-dd:hover{
326 326 opacity: 0.2;
327 327 -webkit-transition: opacity 0.5s ease-in-out;
328 328 -moz-transition: opacity 0.5s ease-in-out;
329 329 transition: opacity 0.5s ease-in-out;
330 330 }
331 331
332 332 #header #header-inner {
333 333 min-height: 44px;
334 334 clear: both;
335 335 position: relative;
336 336 background-color: #003B76;
337 337 background-repeat: repeat-x;
338 338 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
339 339 background-image: -moz-linear-gradient(top, #003b76, #00376e);
340 340 background-image: -ms-linear-gradient(top, #003b76, #00376e);
341 341 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) );
342 342 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
343 343 background-image: -o-linear-gradient(top, #003b76, #00376e);
344 344 background-image: linear-gradient(top, #003b76, #00376e);
345 345 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
346 346 margin: 0;
347 347 padding: 0;
348 348 display: block;
349 349 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
350 350 -webkit-border-radius: 0px 0px 4px 4px;
351 351 -khtml-border-radius: 0px 0px 4px 4px;
352 352 -moz-border-radius: 0px 0px 4px 4px;
353 353 border-radius: 0px 0px 4px 4px;
354 354 }
355 355 #header #header-inner.hover {
356 356 width: 100% !important;
357 357 -webkit-border-radius: 0px 0px 0px 0px;
358 358 -khtml-border-radius: 0px 0px 0px 0px;
359 359 -moz-border-radius: 0px 0px 0px 0px;
360 360 border-radius: 0px 0px 0px 0px;
361 361 position: fixed !important;
362 362 z-index: 10000;
363 363 }
364 364
365 365 .ie7 #header #header-inner.hover,
366 366 .ie8 #header #header-inner.hover,
367 367 .ie9 #header #header-inner.hover
368 368 {
369 369 z-index: auto !important;
370 370 }
371 371
372 372 .header-pos-fix, .anchor {
373 373 margin-top: -46px;
374 374 padding-top: 46px;
375 375 }
376 376
377 377 #header #header-inner #home a {
378 378 height: 40px;
379 379 width: 46px;
380 380 display: block;
381 381 background: url("../images/button_home.png");
382 382 background-position: 0 0;
383 383 margin: 0;
384 384 padding: 0;
385 385 }
386 386
387 387 #header #header-inner #home a:hover {
388 388 background-position: 0 -40px;
389 389 }
390 390
391 391 #header #header-inner #logo {
392 392 float: left;
393 393 position: absolute;
394 394 }
395 395
396 396 #header #header-inner #logo h1 {
397 397 color: #FFF;
398 398 font-size: 20px;
399 399 margin: 12px 0 0 13px;
400 400 padding: 0;
401 401 }
402 402
403 403 #header #header-inner #logo a {
404 404 color: #fff;
405 405 text-decoration: none;
406 406 }
407 407
408 408 #header #header-inner #logo a:hover {
409 409 color: #bfe3ff;
410 410 }
411 411
412 412 #header #header-inner #quick, #header #header-inner #quick ul {
413 413 position: relative;
414 414 float: right;
415 415 list-style-type: none;
416 416 list-style-position: outside;
417 417 margin: 8px 8px 0 0;
418 418 padding: 0;
419 419 }
420 420
421 421 #header #header-inner #quick li {
422 422 position: relative;
423 423 float: left;
424 424 margin: 0 5px 0 0;
425 425 padding: 0;
426 426 }
427 427
428 428 #header #header-inner #quick li a.menu_link {
429 429 top: 0;
430 430 left: 0;
431 431 height: 1%;
432 432 display: block;
433 433 clear: both;
434 434 overflow: hidden;
435 435 color: #FFF;
436 436 font-weight: 700;
437 437 text-decoration: none;
438 438 background: #369;
439 439 padding: 0;
440 440 -webkit-border-radius: 4px 4px 4px 4px;
441 441 -khtml-border-radius: 4px 4px 4px 4px;
442 442 -moz-border-radius: 4px 4px 4px 4px;
443 443 border-radius: 4px 4px 4px 4px;
444 444 }
445 445
446 446 #header #header-inner #quick li span.short {
447 447 padding: 9px 6px 8px 6px;
448 448 }
449 449
450 450 #header #header-inner #quick li span {
451 451 top: 0;
452 452 right: 0;
453 453 height: 1%;
454 454 display: block;
455 455 float: left;
456 456 border-left: 1px solid #3f6f9f;
457 457 margin: 0;
458 458 padding: 10px 12px 8px 10px;
459 459 }
460 460
461 461 #header #header-inner #quick li span.normal {
462 462 border: none;
463 463 padding: 10px 12px 8px;
464 464 }
465 465
466 466 #header #header-inner #quick li span.icon {
467 467 top: 0;
468 468 left: 0;
469 469 border-left: none;
470 470 border-right: 1px solid #2e5c89;
471 471 padding: 8px 6px 4px;
472 472 min-width: 16px;
473 473 min-height: 16px;
474 474 }
475 475
476 476 #header #header-inner #quick li span.icon_short {
477 477 top: 0;
478 478 left: 0;
479 479 border-left: none;
480 480 border-right: 1px solid #2e5c89;
481 481 padding: 8px 6px 4px;
482 482 }
483 483
484 484 #header #header-inner #quick li span.icon img, #header #header-inner #quick li span.icon_short img {
485 485 margin: 0px -2px 0px 0px;
486 486 }
487 487
488 488 #header #header-inner #quick li.current a,
489 489 #header #header-inner #quick li a:hover {
490 490 background: #4e4e4e no-repeat top left;
491 491 }
492 492
493 493 #header #header-inner #quick li.current a span,
494 494 #header #header-inner #quick li a:hover span {
495 495 border-left: 1px solid #545454;
496 496 }
497 497
498 498 #header #header-inner #quick li.current a span.icon,
499 499 #header #header-inner #quick li.current a span.icon_short,
500 500 #header #header-inner #quick li a:hover span.icon,
501 501 #header #header-inner #quick li a:hover span.icon_short {
502 502 border-left: none;
503 503 border-right: 1px solid #464646;
504 504 }
505 505
506 506 #header #header-inner #quick ul {
507 507 top: 29px;
508 508 right: 0;
509 509 min-width: 200px;
510 510 display: none;
511 511 position: absolute;
512 512 background: #FFF;
513 513 border: 1px solid #666;
514 514 border-top: 1px solid #003367;
515 515 z-index: 100;
516 516 margin: 0px 0px 0px 0px;
517 517 padding: 0;
518 518 }
519 519
520 520 #header #header-inner #quick ul.repo_switcher {
521 521 max-height: 275px;
522 522 overflow-x: hidden;
523 523 overflow-y: auto;
524 524 }
525 525
526 526 #header #header-inner #quick ul.repo_switcher li.qfilter_rs {
527 527 float: none;
528 528 margin: 0;
529 529 border-bottom: 2px solid #003367;
530 530 }
531 531
532 532 #header #header-inner #quick .repo_switcher_type {
533 533 position: absolute;
534 534 left: 0;
535 535 top: 9px;
536 536 }
537 537
538 538 #header #header-inner #quick li ul li {
539 539 border-bottom: 1px solid #ddd;
540 540 }
541 541
542 542 #header #header-inner #quick li ul li a {
543 543 width: 182px;
544 544 height: auto;
545 545 display: block;
546 546 float: left;
547 547 background: #FFF;
548 548 color: #003367;
549 549 font-weight: 400;
550 550 margin: 0;
551 551 padding: 7px 9px;
552 552 }
553 553
554 554 #header #header-inner #quick li ul li a:hover {
555 555 color: #000;
556 556 background: #FFF;
557 557 }
558 558
559 559 #header #header-inner #quick ul ul {
560 560 top: auto;
561 561 }
562 562
563 563 #header #header-inner #quick li ul ul {
564 564 right: 200px;
565 565 max-height: 290px;
566 566 overflow: auto;
567 567 overflow-x: hidden;
568 568 white-space: normal;
569 569 }
570 570
571 571 #header #header-inner #quick li ul li a.journal, #header #header-inner #quick li ul li a.journal:hover {
572 572 background: url("../images/icons/book.png") no-repeat scroll 4px 9px
573 573 #FFF;
574 574 width: 167px;
575 575 margin: 0;
576 576 padding: 12px 9px 7px 24px;
577 577 }
578 578
579 579 #header #header-inner #quick li ul li a.private_repo, #header #header-inner #quick li ul li a.private_repo:hover {
580 580 background: url("../images/icons/lock.png") no-repeat scroll 4px 9px
581 581 #FFF;
582 582 min-width: 167px;
583 583 margin: 0;
584 584 padding: 12px 9px 7px 24px;
585 585 }
586 586
587 587 #header #header-inner #quick li ul li a.public_repo, #header #header-inner #quick li ul li a.public_repo:hover {
588 588 background: url("../images/icons/lock_open.png") no-repeat scroll 4px
589 589 9px #FFF;
590 590 min-width: 167px;
591 591 margin: 0;
592 592 padding: 12px 9px 7px 24px;
593 593 }
594 594
595 595 #header #header-inner #quick li ul li a.hg, #header #header-inner #quick li ul li a.hg:hover {
596 596 background: url("../images/icons/hgicon.png") no-repeat scroll 4px 9px
597 597 #FFF;
598 598 min-width: 167px;
599 599 margin: 0 0 0 14px;
600 600 padding: 12px 9px 7px 24px;
601 601 }
602 602
603 603 #header #header-inner #quick li ul li a.git, #header #header-inner #quick li ul li a.git:hover {
604 604 background: url("../images/icons/giticon.png") no-repeat scroll 4px 9px
605 605 #FFF;
606 606 min-width: 167px;
607 607 margin: 0 0 0 14px;
608 608 padding: 12px 9px 7px 24px;
609 609 }
610 610
611 611 #header #header-inner #quick li ul li a.repos, #header #header-inner #quick li ul li a.repos:hover {
612 612 background: url("../images/icons/database_edit.png") no-repeat scroll
613 613 4px 9px #FFF;
614 614 width: 167px;
615 615 margin: 0;
616 616 padding: 12px 9px 7px 24px;
617 617 }
618 618
619 619 #header #header-inner #quick li ul li a.repos_groups, #header #header-inner #quick li ul li a.repos_groups:hover {
620 620 background: url("../images/icons/database_link.png") no-repeat scroll
621 621 4px 9px #FFF;
622 622 width: 167px;
623 623 margin: 0;
624 624 padding: 12px 9px 7px 24px;
625 625 }
626 626
627 627 #header #header-inner #quick li ul li a.users, #header #header-inner #quick li ul li a.users:hover {
628 628 background: #FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
629 629 width: 167px;
630 630 margin: 0;
631 631 padding: 12px 9px 7px 24px;
632 632 }
633 633
634 634 #header #header-inner #quick li ul li a.groups, #header #header-inner #quick li ul li a.groups:hover {
635 635 background: #FFF url("../images/icons/group_edit.png") no-repeat 4px 9px;
636 636 width: 167px;
637 637 margin: 0;
638 638 padding: 12px 9px 7px 24px;
639 639 }
640 640
641 641 #header #header-inner #quick li ul li a.defaults, #header #header-inner #quick li ul li a.defaults:hover {
642 642 background: #FFF url("../images/icons/wrench.png") no-repeat 4px 9px;
643 643 width: 167px;
644 644 margin: 0;
645 645 padding: 12px 9px 7px 24px;
646 646 }
647 647
648 648 #header #header-inner #quick li ul li a.settings, #header #header-inner #quick li ul li a.settings:hover {
649 649 background: #FFF url("../images/icons/cog.png") no-repeat 4px 9px;
650 650 width: 167px;
651 651 margin: 0;
652 652 padding: 12px 9px 7px 24px;
653 653 }
654 654
655 655 #header #header-inner #quick li ul li a.permissions, #header #header-inner #quick li ul li a.permissions:hover {
656 656 background: #FFF url("../images/icons/key.png") no-repeat 4px 9px;
657 657 width: 167px;
658 658 margin: 0;
659 659 padding: 12px 9px 7px 24px;
660 660 }
661 661
662 662 #header #header-inner #quick li ul li a.ldap, #header #header-inner #quick li ul li a.ldap:hover {
663 663 background: #FFF url("../images/icons/server_key.png") no-repeat 4px 9px;
664 664 width: 167px;
665 665 margin: 0;
666 666 padding: 12px 9px 7px 24px;
667 667 }
668 668
669 669 #header #header-inner #quick li ul li a.fork, #header #header-inner #quick li ul li a.fork:hover {
670 670 background: #FFF url("../images/icons/arrow_divide.png") no-repeat 4px
671 671 9px;
672 672 width: 167px;
673 673 margin: 0;
674 674 padding: 12px 9px 7px 24px;
675 675 }
676 676
677 677 #header #header-inner #quick li ul li a.locking_add, #header #header-inner #quick li ul li a.locking_add:hover {
678 678 background: #FFF url("../images/icons/lock_add.png") no-repeat 4px
679 679 9px;
680 680 width: 167px;
681 681 margin: 0;
682 682 padding: 12px 9px 7px 24px;
683 683 }
684 684
685 685 #header #header-inner #quick li ul li a.locking_del, #header #header-inner #quick li ul li a.locking_del:hover {
686 686 background: #FFF url("../images/icons/lock_delete.png") no-repeat 4px
687 687 9px;
688 688 width: 167px;
689 689 margin: 0;
690 690 padding: 12px 9px 7px 24px;
691 691 }
692 692
693 693 #header #header-inner #quick li ul li a.pull_request, #header #header-inner #quick li ul li a.pull_request:hover {
694 694 background: #FFF url("../images/icons/arrow_join.png") no-repeat 4px
695 695 9px;
696 696 width: 167px;
697 697 margin: 0;
698 698 padding: 12px 9px 7px 24px;
699 699 }
700 700
701 701 #header #header-inner #quick li ul li a.compare_request, #header #header-inner #quick li ul li a.compare_request:hover {
702 702 background: #FFF url("../images/icons/arrow_inout.png") no-repeat 4px
703 703 9px;
704 704 width: 167px;
705 705 margin: 0;
706 706 padding: 12px 9px 7px 24px;
707 707 }
708 708
709 709 #header #header-inner #quick li ul li a.search, #header #header-inner #quick li ul li a.search:hover {
710 710 background: #FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
711 711 width: 167px;
712 712 margin: 0;
713 713 padding: 12px 9px 7px 24px;
714 714 }
715 715
716 716 #header #header-inner #quick li ul li a.shortlog, #header #header-inner #quick li ul li a.shortlog:hover {
717 717 background: #FFF url("../images/icons/clock_16.png") no-repeat 4px 9px;
718 718 width: 167px;
719 719 margin: 0;
720 720 padding: 12px 9px 7px 24px;
721 721 }
722 722
723 723
724 724 #header #header-inner #quick li ul li a.delete, #header #header-inner #quick li ul li a.delete:hover {
725 725 background: #FFF url("../images/icons/delete.png") no-repeat 4px 9px;
726 726 width: 167px;
727 727 margin: 0;
728 728 padding: 12px 9px 7px 24px;
729 729 }
730 730
731 731 #header #header-inner #quick li ul li a.branches, #header #header-inner #quick li ul li a.branches:hover {
732 732 background: #FFF url("../images/icons/arrow_branch.png") no-repeat 4px
733 733 9px;
734 734 width: 167px;
735 735 margin: 0;
736 736 padding: 12px 9px 7px 24px;
737 737 }
738 738
739 739 #header #header-inner #quick li ul li a.tags,
740 740 #header #header-inner #quick li ul li a.tags:hover {
741 741 background: #FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
742 742 width: 167px;
743 743 margin: 0;
744 744 padding: 12px 9px 7px 24px;
745 745 }
746 746
747 747 #header #header-inner #quick li ul li a.bookmarks,
748 748 #header #header-inner #quick li ul li a.bookmarks:hover {
749 749 background: #FFF url("../images/icons/tag_green.png") no-repeat 4px 9px;
750 750 width: 167px;
751 751 margin: 0;
752 752 padding: 12px 9px 7px 24px;
753 753 }
754 754
755 755 #header #header-inner #quick li ul li a.admin,
756 756 #header #header-inner #quick li ul li a.admin:hover {
757 757 background: #FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
758 758 width: 167px;
759 759 margin: 0;
760 760 padding: 12px 9px 7px 24px;
761 761 }
762 762
763 763 .groups_breadcrumbs a {
764 764 color: #fff;
765 765 }
766 766
767 767 .groups_breadcrumbs a:hover {
768 768 color: #bfe3ff;
769 769 text-decoration: none;
770 770 }
771 771
772 772 td.quick_repo_menu {
773 773 background: #FFF url("../images/vertical-indicator.png") 8px 50% no-repeat !important;
774 774 cursor: pointer;
775 775 width: 8px;
776 776 border: 1px solid transparent;
777 777 }
778 778
779 779 td.quick_repo_menu.active {
780 780 background: url("../images/dt-arrow-dn.png") no-repeat scroll 5px 50% #FFFFFF !important;
781 781 border: 1px solid #003367;
782 782 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
783 783 cursor: pointer;
784 784 }
785 785
786 786 td.quick_repo_menu .menu_items {
787 787 margin-top: 10px;
788 788 margin-left:-6px;
789 789 width: 150px;
790 790 position: absolute;
791 791 background-color: #FFF;
792 792 background: none repeat scroll 0 0 #FFFFFF;
793 793 border-color: #003367 #666666 #666666;
794 794 border-right: 1px solid #666666;
795 795 border-style: solid;
796 796 border-width: 1px;
797 797 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
798 798 border-top-style: none;
799 799 }
800 800
801 801 td.quick_repo_menu .menu_items li {
802 802 padding: 0 !important;
803 803 }
804 804
805 805 td.quick_repo_menu .menu_items a {
806 806 display: block;
807 807 padding: 4px 12px 4px 8px;
808 808 }
809 809
810 810 td.quick_repo_menu .menu_items a:hover {
811 811 background-color: #EEE;
812 812 text-decoration: none;
813 813 }
814 814
815 815 td.quick_repo_menu .menu_items .icon img {
816 816 margin-bottom: -2px;
817 817 }
818 818
819 819 td.quick_repo_menu .menu_items.hidden {
820 820 display: none;
821 821 }
822 822
823 823 .yui-dt-first th {
824 824 text-align: left;
825 825 }
826 826
827 827 /*
828 828 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
829 829 Code licensed under the BSD License:
830 830 http://developer.yahoo.com/yui/license.html
831 831 version: 2.9.0
832 832 */
833 833 .yui-skin-sam .yui-dt-mask {
834 834 position: absolute;
835 835 z-index: 9500;
836 836 }
837 837 .yui-dt-tmp {
838 838 position: absolute;
839 839 left: -9000px;
840 840 }
841 841 .yui-dt-scrollable .yui-dt-bd { overflow: auto }
842 842 .yui-dt-scrollable .yui-dt-hd {
843 843 overflow: hidden;
844 844 position: relative;
845 845 }
846 846 .yui-dt-scrollable .yui-dt-bd thead tr,
847 847 .yui-dt-scrollable .yui-dt-bd thead th {
848 848 position: absolute;
849 849 left: -1500px;
850 850 }
851 851 .yui-dt-scrollable tbody { -moz-outline: 0 }
852 852 .yui-skin-sam thead .yui-dt-sortable { cursor: pointer }
853 853 .yui-skin-sam thead .yui-dt-draggable { cursor: move }
854 854 .yui-dt-coltarget {
855 855 position: absolute;
856 856 z-index: 999;
857 857 }
858 858 .yui-dt-hd { zoom: 1 }
859 859 th.yui-dt-resizeable .yui-dt-resizerliner { position: relative }
860 860 .yui-dt-resizer {
861 861 position: absolute;
862 862 right: 0;
863 863 bottom: 0;
864 864 height: 100%;
865 865 cursor: e-resize;
866 866 cursor: col-resize;
867 867 background-color: #CCC;
868 868 opacity: 0;
869 869 filter: alpha(opacity=0);
870 870 }
871 871 .yui-dt-resizerproxy {
872 872 visibility: hidden;
873 873 position: absolute;
874 874 z-index: 9000;
875 875 background-color: #CCC;
876 876 opacity: 0;
877 877 filter: alpha(opacity=0);
878 878 }
879 879 th.yui-dt-hidden .yui-dt-liner,
880 880 td.yui-dt-hidden .yui-dt-liner,
881 881 th.yui-dt-hidden .yui-dt-resizer { display: none }
882 882 .yui-dt-editor,
883 883 .yui-dt-editor-shim {
884 884 position: absolute;
885 885 z-index: 9000;
886 886 }
887 887 .yui-skin-sam .yui-dt table {
888 888 margin: 0;
889 889 padding: 0;
890 890 font-family: arial;
891 891 font-size: inherit;
892 892 border-collapse: separate;
893 893 *border-collapse: collapse;
894 894 border-spacing: 0;
895 895 border: 1px solid #7f7f7f;
896 896 }
897 897 .yui-skin-sam .yui-dt thead { border-spacing: 0 }
898 898 .yui-skin-sam .yui-dt caption {
899 899 color: #000;
900 900 font-size: 85%;
901 901 font-weight: normal;
902 902 font-style: italic;
903 903 line-height: 1;
904 904 padding: 1em 0;
905 905 text-align: center;
906 906 }
907 907 .yui-skin-sam .yui-dt th { background: #d8d8da url(../images/sprite.png) repeat-x 0 0 }
908 908 .yui-skin-sam .yui-dt th,
909 909 .yui-skin-sam .yui-dt th a {
910 910 font-weight: normal;
911 911 text-decoration: none;
912 912 color: #000;
913 913 vertical-align: bottom;
914 914 }
915 915 .yui-skin-sam .yui-dt th {
916 916 margin: 0;
917 917 padding: 0;
918 918 border: 0;
919 919 border-right: 1px solid #cbcbcb;
920 920 }
921 921 .yui-skin-sam .yui-dt tr.yui-dt-first td { border-top: 1px solid #7f7f7f }
922 922 .yui-skin-sam .yui-dt th .yui-dt-liner { white-space: nowrap }
923 923 .yui-skin-sam .yui-dt-liner {
924 924 margin: 0;
925 925 padding: 0;
926 926 }
927 927 .yui-skin-sam .yui-dt-coltarget {
928 928 width: 5px;
929 929 background-color: red;
930 930 }
931 931 .yui-skin-sam .yui-dt td {
932 932 margin: 0;
933 933 padding: 0;
934 934 border: 0;
935 935 border-right: 1px solid #cbcbcb;
936 936 text-align: left;
937 937 }
938 938 .yui-skin-sam .yui-dt-list td { border-right: 0 }
939 939 .yui-skin-sam .yui-dt-resizer { width: 6px }
940 940 .yui-skin-sam .yui-dt-mask {
941 941 background-color: #000;
942 942 opacity: .25;
943 943 filter: alpha(opacity=25);
944 944 }
945 945 .yui-skin-sam .yui-dt-message { background-color: #FFF }
946 946 .yui-skin-sam .yui-dt-scrollable table { border: 0 }
947 947 .yui-skin-sam .yui-dt-scrollable .yui-dt-hd {
948 948 border-left: 1px solid #7f7f7f;
949 949 border-top: 1px solid #7f7f7f;
950 950 border-right: 1px solid #7f7f7f;
951 951 }
952 952 .yui-skin-sam .yui-dt-scrollable .yui-dt-bd {
953 953 border-left: 1px solid #7f7f7f;
954 954 border-bottom: 1px solid #7f7f7f;
955 955 border-right: 1px solid #7f7f7f;
956 956 background-color: #FFF;
957 957 }
958 958 .yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td { border-bottom: 1px solid #7f7f7f }
959 959 .yui-skin-sam th.yui-dt-asc,
960 960 .yui-skin-sam th.yui-dt-desc { background: url(../images/sprite.png) repeat-x 0 -100px }
961 961 .yui-skin-sam th.yui-dt-sortable .yui-dt-label { margin-right: 10px }
962 962 .yui-skin-sam th.yui-dt-asc .yui-dt-liner { background: url(../images/dt-arrow-up.png) no-repeat right }
963 963 .yui-skin-sam th.yui-dt-desc .yui-dt-liner { background: url(../images/dt-arrow-dn.png) no-repeat right }
964 964 tbody .yui-dt-editable { cursor: pointer }
965 965 .yui-dt-editor {
966 966 text-align: left;
967 967 background-color: #f2f2f2;
968 968 border: 1px solid #808080;
969 969 padding: 6px;
970 970 }
971 971 .yui-dt-editor label {
972 972 padding-left: 4px;
973 973 padding-right: 6px;
974 974 }
975 975 .yui-dt-editor .yui-dt-button {
976 976 padding-top: 6px;
977 977 text-align: right;
978 978 }
979 979 .yui-dt-editor .yui-dt-button button {
980 980 background: url(../images/sprite.png) repeat-x 0 0;
981 981 border: 1px solid #999;
982 982 width: 4em;
983 983 height: 1.8em;
984 984 margin-left: 6px;
985 985 }
986 986 .yui-dt-editor .yui-dt-button button.yui-dt-default {
987 987 background: url(../images/sprite.png) repeat-x 0 -1400px;
988 988 background-color: #5584e0;
989 989 border: 1px solid #304369;
990 990 color: #FFF;
991 991 }
992 992 .yui-dt-editor .yui-dt-button button:hover {
993 993 background: url(../images/sprite.png) repeat-x 0 -1300px;
994 994 color: #000;
995 995 }
996 996 .yui-dt-editor .yui-dt-button button:active {
997 997 background: url(../images/sprite.png) repeat-x 0 -1700px;
998 998 color: #000;
999 999 }
1000 1000 .yui-skin-sam tr.yui-dt-even { background-color: #FFF }
1001 1001 .yui-skin-sam tr.yui-dt-odd { background-color: #edf5ff }
1002 1002 .yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
1003 1003 .yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
1004 1004 .yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
1005 1005 .yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color: #dbeaff }
1006 1006 .yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color: #FFF }
1007 1007 .yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color: #FFF }
1008 1008 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
1009 1009 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
1010 1010 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
1011 1011 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color: #edf5ff }
1012 1012 .yui-skin-sam th.yui-dt-highlighted,
1013 1013 .yui-skin-sam th.yui-dt-highlighted a { background-color: #b2d2ff }
1014 1014 .yui-skin-sam tr.yui-dt-highlighted,
1015 1015 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
1016 1016 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
1017 1017 .yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
1018 1018 .yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
1019 1019 cursor: pointer;
1020 1020 background-color: #b2d2ff;
1021 1021 }
1022 1022 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted,
1023 1023 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted a { background-color: #b2d2ff }
1024 1024 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
1025 1025 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
1026 1026 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
1027 1027 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
1028 1028 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
1029 1029 cursor: pointer;
1030 1030 background-color: #b2d2ff;
1031 1031 }
1032 1032 .yui-skin-sam th.yui-dt-selected,
1033 1033 .yui-skin-sam th.yui-dt-selected a { background-color: #446cd7 }
1034 1034 .yui-skin-sam tr.yui-dt-selected td,
1035 1035 .yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
1036 1036 .yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
1037 1037 background-color: #426fd9;
1038 1038 color: #FFF;
1039 1039 }
1040 1040 .yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
1041 1041 .yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
1042 1042 background-color: #446cd7;
1043 1043 color: #FFF;
1044 1044 }
1045 1045 .yui-skin-sam .yui-dt-list th.yui-dt-selected,
1046 1046 .yui-skin-sam .yui-dt-list th.yui-dt-selected a { background-color: #446cd7 }
1047 1047 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
1048 1048 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
1049 1049 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
1050 1050 background-color: #426fd9;
1051 1051 color: #FFF;
1052 1052 }
1053 1053 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
1054 1054 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
1055 1055 background-color: #446cd7;
1056 1056 color: #FFF;
1057 1057 }
1058 1058 .yui-skin-sam .yui-dt-paginator {
1059 1059 display: block;
1060 1060 margin: 6px 0;
1061 1061 white-space: nowrap;
1062 1062 }
1063 1063 .yui-skin-sam .yui-dt-paginator .yui-dt-first,
1064 1064 .yui-skin-sam .yui-dt-paginator .yui-dt-last,
1065 1065 .yui-skin-sam .yui-dt-paginator .yui-dt-selected { padding: 2px 6px }
1066 1066 .yui-skin-sam .yui-dt-paginator a.yui-dt-first,
1067 1067 .yui-skin-sam .yui-dt-paginator a.yui-dt-last { text-decoration: none }
1068 1068 .yui-skin-sam .yui-dt-paginator .yui-dt-previous,
1069 1069 .yui-skin-sam .yui-dt-paginator .yui-dt-next { display: none }
1070 1070 .yui-skin-sam a.yui-dt-page {
1071 1071 border: 1px solid #cbcbcb;
1072 1072 padding: 2px 6px;
1073 1073 text-decoration: none;
1074 1074 background-color: #fff;
1075 1075 }
1076 1076 .yui-skin-sam .yui-dt-selected {
1077 1077 border: 1px solid #fff;
1078 1078 background-color: #fff;
1079 1079 }
1080 1080
1081 1081 #content #left {
1082 1082 left: 0;
1083 1083 width: 280px;
1084 1084 position: absolute;
1085 1085 }
1086 1086
1087 1087 #content #right {
1088 1088 margin: 0 60px 10px 290px;
1089 1089 }
1090 1090
1091 1091 #content div.box {
1092 1092 clear: both;
1093 1093 overflow: hidden;
1094 1094 background: #fff;
1095 1095 margin: 0 0 10px;
1096 1096 padding: 0 0 10px;
1097 1097 -webkit-border-radius: 4px 4px 4px 4px;
1098 1098 -khtml-border-radius: 4px 4px 4px 4px;
1099 1099 -moz-border-radius: 4px 4px 4px 4px;
1100 1100 border-radius: 4px 4px 4px 4px;
1101 1101 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1102 1102 }
1103 1103
1104 1104 #content div.box-left {
1105 1105 width: 49%;
1106 1106 clear: none;
1107 1107 float: left;
1108 1108 margin: 0 0 10px;
1109 1109 }
1110 1110
1111 1111 #content div.box-right {
1112 1112 width: 49%;
1113 1113 clear: none;
1114 1114 float: right;
1115 1115 margin: 0 0 10px;
1116 1116 }
1117 1117
1118 1118 #content div.box div.title {
1119 1119 clear: both;
1120 1120 overflow: hidden;
1121 1121 background-color: #003B76;
1122 1122 background-repeat: repeat-x;
1123 1123 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
1124 1124 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1125 1125 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1126 1126 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
1127 1127 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
1128 1128 background-image: -o-linear-gradient(top, #003b76, #00376e);
1129 1129 background-image: linear-gradient(top, #003b76, #00376e);
1130 1130 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
1131 1131 margin: 0 0 20px;
1132 1132 padding: 0;
1133 1133 }
1134 1134
1135 1135 #content div.box div.title h5 {
1136 1136 float: left;
1137 1137 border: none;
1138 1138 color: #fff;
1139 1139 text-transform: uppercase;
1140 1140 margin: 0;
1141 1141 padding: 11px 0 11px 10px;
1142 1142 }
1143 1143
1144 1144 #content div.box div.title .link-white {
1145 1145 color: #FFFFFF;
1146 1146 }
1147 1147
1148 1148 #content div.box div.title .link-white.current {
1149 1149 color: #BFE3FF;
1150 1150 }
1151 1151
1152 1152 #content div.box div.title ul.links li {
1153 1153 list-style: none;
1154 1154 float: left;
1155 1155 margin: 0;
1156 1156 padding: 0;
1157 1157 }
1158 1158
1159 1159 #content div.box div.title ul.links li a {
1160 1160 border-left: 1px solid #316293;
1161 1161 color: #FFFFFF;
1162 1162 display: block;
1163 1163 float: left;
1164 1164 font-size: 13px;
1165 1165 font-weight: 700;
1166 1166 height: 1%;
1167 1167 margin: 0;
1168 1168 padding: 11px 22px 12px;
1169 1169 text-decoration: none;
1170 1170 }
1171 1171
1172 1172 #content div.box h1, #content div.box h2, #content div.box h3, #content div.box h4, #content div.box h5, #content div.box h6,
1173 1173 #content div.box div.h1, #content div.box div.h2, #content div.box div.h3, #content div.box div.h4, #content div.box div.h5, #content div.box div.h6 {
1174 1174 clear: both;
1175 1175 overflow: hidden;
1176 1176 border-bottom: 1px solid #DDD;
1177 1177 margin: 10px 20px;
1178 1178 padding: 0 0 15px;
1179 1179 }
1180 1180
1181 1181 #content div.box p {
1182 1182 color: #5f5f5f;
1183 1183 font-size: 12px;
1184 1184 line-height: 150%;
1185 1185 margin: 0 24px 10px;
1186 1186 padding: 0;
1187 1187 }
1188 1188
1189 1189 #content div.box blockquote {
1190 1190 border-left: 4px solid #DDD;
1191 1191 color: #5f5f5f;
1192 1192 font-size: 11px;
1193 1193 line-height: 150%;
1194 1194 margin: 0 34px;
1195 1195 padding: 0 0 0 14px;
1196 1196 }
1197 1197
1198 1198 #content div.box blockquote p {
1199 1199 margin: 10px 0;
1200 1200 padding: 0;
1201 1201 }
1202 1202
1203 1203 #content div.box dl {
1204 1204 margin: 10px 0px;
1205 1205 }
1206 1206
1207 1207 #content div.box dt {
1208 1208 font-size: 12px;
1209 1209 margin: 0;
1210 1210 }
1211 1211
1212 1212 #content div.box dd {
1213 1213 font-size: 12px;
1214 1214 margin: 0;
1215 1215 padding: 8px 0 8px 15px;
1216 1216 }
1217 1217
1218 1218 #content div.box li {
1219 1219 font-size: 12px;
1220 1220 padding: 4px 0;
1221 1221 }
1222 1222
1223 1223 #content div.box ul.disc, #content div.box ul.circle {
1224 1224 margin: 10px 24px 10px 38px;
1225 1225 }
1226 1226
1227 1227 #content div.box ul.square {
1228 1228 margin: 10px 24px 10px 40px;
1229 1229 }
1230 1230
1231 1231 #content div.box img.left {
1232 1232 border: none;
1233 1233 float: left;
1234 1234 margin: 10px 10px 10px 0;
1235 1235 }
1236 1236
1237 1237 #content div.box img.right {
1238 1238 border: none;
1239 1239 float: right;
1240 1240 margin: 10px 0 10px 10px;
1241 1241 }
1242 1242
1243 1243 #content div.box div.messages {
1244 1244 clear: both;
1245 1245 overflow: hidden;
1246 1246 margin: 0 20px;
1247 1247 padding: 0;
1248 1248 }
1249 1249
1250 1250 #content div.box div.message {
1251 1251 clear: both;
1252 1252 overflow: hidden;
1253 1253 margin: 0;
1254 1254 padding: 5px 0;
1255 1255 white-space: pre-wrap;
1256 1256 }
1257 1257 #content div.box div.expand {
1258 1258 width: 110%;
1259 1259 height:14px;
1260 1260 font-size:10px;
1261 1261 text-align:center;
1262 1262 cursor: pointer;
1263 1263 color:#666;
1264 1264
1265 1265 background:-webkit-gradient(linear,0% 50%,100% 50%,color-stop(0%,rgba(255,255,255,0)),color-stop(100%,rgba(64,96,128,0.1)));
1266 1266 background:-webkit-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1267 1267 background:-moz-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1268 1268 background:-o-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1269 1269 background:-ms-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1270 1270 background:linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1271 1271
1272 1272 display: none;
1273 1273 }
1274 1274 #content div.box div.expand .expandtext {
1275 1275 background-color: #ffffff;
1276 1276 padding: 2px;
1277 1277 border-radius: 2px;
1278 1278 }
1279 1279
1280 1280 #content div.box div.message a {
1281 1281 font-weight: 400 !important;
1282 1282 }
1283 1283
1284 1284 #content div.box div.message div.image {
1285 1285 float: left;
1286 1286 margin: 9px 0 0 5px;
1287 1287 padding: 6px;
1288 1288 }
1289 1289
1290 1290 #content div.box div.message div.image img {
1291 1291 vertical-align: middle;
1292 1292 margin: 0;
1293 1293 }
1294 1294
1295 1295 #content div.box div.message div.text {
1296 1296 float: left;
1297 1297 margin: 0;
1298 1298 padding: 9px 6px;
1299 1299 }
1300 1300
1301 1301 #content div.box div.message div.dismiss a {
1302 1302 height: 16px;
1303 1303 width: 16px;
1304 1304 display: block;
1305 1305 background: url("../images/icons/cross.png") no-repeat;
1306 1306 margin: 15px 14px 0 0;
1307 1307 padding: 0;
1308 1308 }
1309 1309
1310 1310 #content div.box div.message div.text h1, #content div.box div.message div.text h2, #content div.box div.message div.text h3, #content div.box div.message div.text h4, #content div.box div.message div.text h5, #content div.box div.message div.text h6 {
1311 1311 border: none;
1312 1312 margin: 0;
1313 1313 padding: 0;
1314 1314 }
1315 1315
1316 1316 #content div.box div.message div.text span {
1317 1317 height: 1%;
1318 1318 display: block;
1319 1319 margin: 0;
1320 1320 padding: 5px 0 0;
1321 1321 }
1322 1322
1323 1323 #content div.box div.message-error {
1324 1324 height: 1%;
1325 1325 clear: both;
1326 1326 overflow: hidden;
1327 1327 background: #FBE3E4;
1328 1328 border: 1px solid #FBC2C4;
1329 1329 color: #860006;
1330 1330 }
1331 1331
1332 1332 #content div.box div.message-error h6 {
1333 1333 color: #860006;
1334 1334 }
1335 1335
1336 1336 #content div.box div.message-warning {
1337 1337 height: 1%;
1338 1338 clear: both;
1339 1339 overflow: hidden;
1340 1340 background: #FFF6BF;
1341 1341 border: 1px solid #FFD324;
1342 1342 color: #5f5200;
1343 1343 }
1344 1344
1345 1345 #content div.box div.message-warning h6 {
1346 1346 color: #5f5200;
1347 1347 }
1348 1348
1349 1349 #content div.box div.message-notice {
1350 1350 height: 1%;
1351 1351 clear: both;
1352 1352 overflow: hidden;
1353 1353 background: #8FBDE0;
1354 1354 border: 1px solid #6BACDE;
1355 1355 color: #003863;
1356 1356 }
1357 1357
1358 1358 #content div.box div.message-notice h6 {
1359 1359 color: #003863;
1360 1360 }
1361 1361
1362 1362 #content div.box div.message-success {
1363 1363 height: 1%;
1364 1364 clear: both;
1365 1365 overflow: hidden;
1366 1366 background: #E6EFC2;
1367 1367 border: 1px solid #C6D880;
1368 1368 color: #4e6100;
1369 1369 }
1370 1370
1371 1371 #content div.box div.message-success h6 {
1372 1372 color: #4e6100;
1373 1373 }
1374 1374
1375 1375 #content div.box div.form div.fields div.field {
1376 1376 height: 1%;
1377 1377 min-height: 12px;
1378 1378 border-bottom: 1px solid #DDD;
1379 1379 clear: both;
1380 1380 margin: 0;
1381 1381 padding: 10px 0;
1382 1382 }
1383 1383
1384 1384 #content div.box div.form div.fields div.field-first {
1385 1385 padding: 0 0 10px;
1386 1386 }
1387 1387
1388 1388 #content div.box div.form div.fields div.field-noborder {
1389 1389 border-bottom: 0 !important;
1390 1390 }
1391 1391
1392 1392 #content div.box div.form div.fields div.field span.error-message {
1393 1393 height: 1%;
1394 1394 display: inline-block;
1395 1395 color: red;
1396 1396 margin: 8px 0 0 4px;
1397 1397 padding: 0;
1398 1398 }
1399 1399
1400 1400 #content div.box div.form div.fields div.field span.success {
1401 1401 height: 1%;
1402 1402 display: block;
1403 1403 color: #316309;
1404 1404 margin: 8px 0 0;
1405 1405 padding: 0;
1406 1406 }
1407 1407
1408 1408 #content div.box div.form div.fields div.field div.label {
1409 1409 left: 70px;
1410 1410 width: 155px;
1411 1411 position: absolute;
1412 1412 margin: 0;
1413 1413 padding: 5px 0 0 0px;
1414 1414 }
1415 1415
1416 1416 #content div.box div.form div.fields div.field div.label-summary {
1417 1417 left: 30px;
1418 1418 width: 155px;
1419 1419 position: absolute;
1420 1420 margin: 0;
1421 1421 padding: 0px 0 0 0px;
1422 1422 }
1423 1423
1424 1424 #content div.box-left div.form div.fields div.field div.label,
1425 1425 #content div.box-right div.form div.fields div.field div.label,
1426 1426 #content div.box-left div.form div.fields div.field div.label,
1427 1427 #content div.box-left div.form div.fields div.field div.label-summary,
1428 1428 #content div.box-right div.form div.fields div.field div.label-summary,
1429 1429 #content div.box-left div.form div.fields div.field div.label-summary {
1430 1430 clear: both;
1431 1431 overflow: hidden;
1432 1432 left: 0;
1433 1433 width: auto;
1434 1434 position: relative;
1435 1435 margin: 0;
1436 1436 padding: 0 0 8px;
1437 1437 }
1438 1438
1439 1439 #content div.box div.form div.fields div.field div.label-select {
1440 1440 padding: 5px 0 0 5px;
1441 1441 }
1442 1442
1443 1443 #content div.box-left div.form div.fields div.field div.label-select,
1444 1444 #content div.box-right div.form div.fields div.field div.label-select {
1445 1445 padding: 0 0 8px;
1446 1446 }
1447 1447
1448 1448 #content div.box-left div.form div.fields div.field div.label-textarea,
1449 1449 #content div.box-right div.form div.fields div.field div.label-textarea {
1450 1450 padding: 0 0 8px !important;
1451 1451 }
1452 1452
1453 1453 #content div.box div.form div.fields div.field div.label label, div.label label {
1454 1454 color: #393939;
1455 1455 font-weight: 700;
1456 1456 }
1457 1457 #content div.box div.form div.fields div.field div.label label, div.label-summary label {
1458 1458 color: #393939;
1459 1459 font-weight: 700;
1460 1460 }
1461 1461 #content div.box div.form div.fields div.field div.input {
1462 1462 margin: 0 0 0 200px;
1463 1463 }
1464 1464
1465 1465 #content div.box div.form div.fields div.field div.input.summary {
1466 1466 margin: 0 0 0 110px;
1467 1467 }
1468 1468 #content div.box div.form div.fields div.field div.input.summary-short {
1469 1469 margin: 0 0 0 110px;
1470 1470 }
1471 1471 #content div.box div.form div.fields div.field div.file {
1472 1472 margin: 0 0 0 200px;
1473 1473 }
1474 1474
1475 1475 #content div.box-left div.form div.fields div.field div.input, #content div.box-right div.form div.fields div.field div.input {
1476 1476 margin: 0 0 0 0px;
1477 1477 }
1478 1478
1479 1479 #content div.box div.form div.fields div.field div.input input,
1480 1480 .reviewer_ac input {
1481 1481 background: #FFF;
1482 1482 border-top: 1px solid #b3b3b3;
1483 1483 border-left: 1px solid #b3b3b3;
1484 1484 border-right: 1px solid #eaeaea;
1485 1485 border-bottom: 1px solid #eaeaea;
1486 1486 color: #000;
1487 1487 font-size: 11px;
1488 1488 margin: 0;
1489 1489 padding: 7px 7px 6px;
1490 1490 }
1491 1491
1492 1492 #content div.box div.form div.fields div.field div.input input#clone_url,
1493 1493 #content div.box div.form div.fields div.field div.input input#clone_url_id
1494 1494 {
1495 1495 font-size: 16px;
1496 1496 padding: 2px;
1497 1497 }
1498 1498
1499 1499 #content div.box div.form div.fields div.field div.file input {
1500 1500 background: none repeat scroll 0 0 #FFFFFF;
1501 1501 border-color: #B3B3B3 #EAEAEA #EAEAEA #B3B3B3;
1502 1502 border-style: solid;
1503 1503 border-width: 1px;
1504 1504 color: #000000;
1505 1505 font-size: 11px;
1506 1506 margin: 0;
1507 1507 padding: 7px 7px 6px;
1508 1508 }
1509 1509
1510 1510 input.disabled {
1511 1511 background-color: #F5F5F5 !important;
1512 1512 }
1513 1513 #content div.box div.form div.fields div.field div.input input.small {
1514 1514 width: 30%;
1515 1515 }
1516 1516
1517 1517 #content div.box div.form div.fields div.field div.input input.medium {
1518 1518 width: 55%;
1519 1519 }
1520 1520
1521 1521 #content div.box div.form div.fields div.field div.input input.large {
1522 1522 width: 85%;
1523 1523 }
1524 1524
1525 1525 #content div.box div.form div.fields div.field div.input input.date {
1526 1526 width: 177px;
1527 1527 }
1528 1528
1529 1529 #content div.box div.form div.fields div.field div.input input.button {
1530 1530 background: #D4D0C8;
1531 1531 border-top: 1px solid #FFF;
1532 1532 border-left: 1px solid #FFF;
1533 1533 border-right: 1px solid #404040;
1534 1534 border-bottom: 1px solid #404040;
1535 1535 color: #000;
1536 1536 margin: 0;
1537 1537 padding: 4px 8px;
1538 1538 }
1539 1539
1540 1540 #content div.box div.form div.fields div.field div.textarea {
1541 1541 border-top: 1px solid #b3b3b3;
1542 1542 border-left: 1px solid #b3b3b3;
1543 1543 border-right: 1px solid #eaeaea;
1544 1544 border-bottom: 1px solid #eaeaea;
1545 1545 margin: 0 0 0 200px;
1546 1546 padding: 10px;
1547 1547 }
1548 1548
1549 1549 #content div.box div.form div.fields div.field div.textarea-editor {
1550 1550 border: 1px solid #ddd;
1551 1551 padding: 0;
1552 1552 }
1553 1553
1554 1554 #content div.box div.form div.fields div.field div.textarea textarea {
1555 1555 width: 100%;
1556 1556 height: 220px;
1557 1557 overflow: hidden;
1558 1558 background: #FFF;
1559 1559 color: #000;
1560 1560 font-size: 11px;
1561 1561 outline: none;
1562 1562 border-width: 0;
1563 1563 margin: 0;
1564 1564 padding: 0;
1565 1565 }
1566 1566
1567 1567 #content div.box-left div.form div.fields div.field div.textarea textarea, #content div.box-right div.form div.fields div.field div.textarea textarea {
1568 1568 width: 100%;
1569 1569 height: 100px;
1570 1570 }
1571 1571
1572 1572 #content div.box div.form div.fields div.field div.textarea table {
1573 1573 width: 100%;
1574 1574 border: none;
1575 1575 margin: 0;
1576 1576 padding: 0;
1577 1577 }
1578 1578
1579 1579 #content div.box div.form div.fields div.field div.textarea table td {
1580 1580 background: #DDD;
1581 1581 border: none;
1582 1582 padding: 0;
1583 1583 }
1584 1584
1585 1585 #content div.box div.form div.fields div.field div.textarea table td table {
1586 1586 width: auto;
1587 1587 border: none;
1588 1588 margin: 0;
1589 1589 padding: 0;
1590 1590 }
1591 1591
1592 1592 #content div.box div.form div.fields div.field div.textarea table td table td {
1593 1593 font-size: 11px;
1594 1594 padding: 5px 5px 5px 0;
1595 1595 }
1596 1596
1597 1597 #content div.box div.form div.fields div.field input[type=text]:focus,
1598 1598 #content div.box div.form div.fields div.field input[type=password]:focus,
1599 1599 #content div.box div.form div.fields div.field input[type=file]:focus,
1600 1600 #content div.box div.form div.fields div.field textarea:focus,
1601 1601 #content div.box div.form div.fields div.field select:focus,
1602 1602 .reviewer_ac input:focus {
1603 1603 background: #f6f6f6;
1604 1604 border-color: #666;
1605 1605 }
1606 1606
1607 1607 .reviewer_ac {
1608 1608 padding:10px
1609 1609 }
1610 1610
1611 1611 div.form div.fields div.field div.button {
1612 1612 margin: 0;
1613 1613 padding: 0 0 0 8px;
1614 1614 }
1615 1615 #content div.box table.noborder {
1616 1616 border: 1px solid transparent;
1617 1617 }
1618 1618
1619 1619 #content div.box table {
1620 1620 width: 100%;
1621 1621 border-collapse: separate;
1622 1622 margin: 0;
1623 1623 padding: 0;
1624 1624 border: 1px solid #eee;
1625 1625 -webkit-border-radius: 4px;
1626 1626 -moz-border-radius: 4px;
1627 1627 border-radius: 4px;
1628 1628 }
1629 1629
1630 1630 #content div.box table th {
1631 1631 background: #eee;
1632 1632 border-bottom: 1px solid #ddd;
1633 1633 padding: 5px 0px 5px 5px;
1634 1634 text-align: left;
1635 1635 }
1636 1636
1637 1637 #content div.box table th.left {
1638 1638 text-align: left;
1639 1639 }
1640 1640
1641 1641 #content div.box table th.right {
1642 1642 text-align: right;
1643 1643 }
1644 1644
1645 1645 #content div.box table th.center {
1646 1646 text-align: center;
1647 1647 }
1648 1648
1649 1649 #content div.box table th.selected {
1650 1650 vertical-align: middle;
1651 1651 padding: 0;
1652 1652 }
1653 1653
1654 1654 #content div.box table td {
1655 1655 background: #fff;
1656 1656 border-bottom: 1px solid #cdcdcd;
1657 1657 vertical-align: middle;
1658 1658 padding: 5px;
1659 1659 }
1660 1660
1661 1661 #content div.box table tr.selected td {
1662 1662 background: #FFC;
1663 1663 }
1664 1664
1665 1665 #content div.box table td.selected {
1666 1666 width: 3%;
1667 1667 text-align: center;
1668 1668 vertical-align: middle;
1669 1669 padding: 0;
1670 1670 }
1671 1671
1672 1672 #content div.box table td.action {
1673 1673 width: 45%;
1674 1674 text-align: left;
1675 1675 }
1676 1676
1677 1677 #content div.box table td.date {
1678 1678 width: 33%;
1679 1679 text-align: center;
1680 1680 }
1681 1681
1682 1682 #content div.box div.action {
1683 1683 float: right;
1684 1684 background: #FFF;
1685 1685 text-align: right;
1686 1686 margin: 10px 0 0;
1687 1687 padding: 0;
1688 1688 }
1689 1689
1690 1690 #content div.box div.action select {
1691 1691 font-size: 11px;
1692 1692 margin: 0;
1693 1693 }
1694 1694
1695 1695 #content div.box div.action .ui-selectmenu {
1696 1696 margin: 0;
1697 1697 padding: 0;
1698 1698 }
1699 1699
1700 1700 #content div.box div.pagination {
1701 1701 height: 1%;
1702 1702 clear: both;
1703 1703 overflow: hidden;
1704 1704 margin: 10px 0 0;
1705 1705 padding: 0;
1706 1706 }
1707 1707
1708 1708 #content div.box div.pagination ul.pager {
1709 1709 float: right;
1710 1710 text-align: right;
1711 1711 margin: 0;
1712 1712 padding: 0;
1713 1713 }
1714 1714
1715 1715 #content div.box div.pagination ul.pager li {
1716 1716 height: 1%;
1717 1717 float: left;
1718 1718 list-style: none;
1719 1719 background: #ebebeb url("../images/pager.png") repeat-x;
1720 1720 border-top: 1px solid #dedede;
1721 1721 border-left: 1px solid #cfcfcf;
1722 1722 border-right: 1px solid #c4c4c4;
1723 1723 border-bottom: 1px solid #c4c4c4;
1724 1724 color: #4A4A4A;
1725 1725 font-weight: 700;
1726 1726 margin: 0 0 0 4px;
1727 1727 padding: 0;
1728 1728 }
1729 1729
1730 1730 #content div.box div.pagination ul.pager li.separator {
1731 1731 padding: 6px;
1732 1732 }
1733 1733
1734 1734 #content div.box div.pagination ul.pager li.current {
1735 1735 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1736 1736 border-top: 1px solid #ccc;
1737 1737 border-left: 1px solid #bebebe;
1738 1738 border-right: 1px solid #b1b1b1;
1739 1739 border-bottom: 1px solid #afafaf;
1740 1740 color: #515151;
1741 1741 padding: 6px;
1742 1742 }
1743 1743
1744 1744 #content div.box div.pagination ul.pager li a {
1745 1745 height: 1%;
1746 1746 display: block;
1747 1747 float: left;
1748 1748 color: #515151;
1749 1749 text-decoration: none;
1750 1750 margin: 0;
1751 1751 padding: 6px;
1752 1752 }
1753 1753
1754 1754 #content div.box div.pagination ul.pager li a:hover, #content div.box div.pagination ul.pager li a:active {
1755 1755 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1756 1756 border-top: 1px solid #ccc;
1757 1757 border-left: 1px solid #bebebe;
1758 1758 border-right: 1px solid #b1b1b1;
1759 1759 border-bottom: 1px solid #afafaf;
1760 1760 margin: -1px;
1761 1761 }
1762 1762
1763 1763 #content div.box div.pagination-wh {
1764 1764 height: 1%;
1765 1765 clear: both;
1766 1766 overflow: hidden;
1767 1767 text-align: right;
1768 1768 margin: 10px 0 0;
1769 1769 padding: 0;
1770 1770 }
1771 1771
1772 1772 #content div.box div.pagination-right {
1773 1773 float: right;
1774 1774 }
1775 1775
1776 1776 #content div.box div.pagination-wh a,
1777 1777 #content div.box div.pagination-wh span.pager_dotdot,
1778 1778 #content div.box div.pagination-wh span.yui-pg-previous,
1779 1779 #content div.box div.pagination-wh span.yui-pg-last,
1780 1780 #content div.box div.pagination-wh span.yui-pg-next,
1781 1781 #content div.box div.pagination-wh span.yui-pg-first {
1782 1782 height: 1%;
1783 1783 float: left;
1784 1784 background: #ebebeb url("../images/pager.png") repeat-x;
1785 1785 border-top: 1px solid #dedede;
1786 1786 border-left: 1px solid #cfcfcf;
1787 1787 border-right: 1px solid #c4c4c4;
1788 1788 border-bottom: 1px solid #c4c4c4;
1789 1789 color: #4A4A4A;
1790 1790 font-weight: 700;
1791 1791 margin: 0 0 0 4px;
1792 1792 padding: 6px;
1793 1793 }
1794 1794
1795 1795 #content div.box div.pagination-wh span.pager_curpage {
1796 1796 height: 1%;
1797 1797 float: left;
1798 1798 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1799 1799 border-top: 1px solid #ccc;
1800 1800 border-left: 1px solid #bebebe;
1801 1801 border-right: 1px solid #b1b1b1;
1802 1802 border-bottom: 1px solid #afafaf;
1803 1803 color: #515151;
1804 1804 font-weight: 700;
1805 1805 margin: 0 0 0 4px;
1806 1806 padding: 6px;
1807 1807 }
1808 1808
1809 1809 #content div.box div.pagination-wh a:hover, #content div.box div.pagination-wh a:active {
1810 1810 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1811 1811 border-top: 1px solid #ccc;
1812 1812 border-left: 1px solid #bebebe;
1813 1813 border-right: 1px solid #b1b1b1;
1814 1814 border-bottom: 1px solid #afafaf;
1815 1815 text-decoration: none;
1816 1816 }
1817 1817
1818 1818 #content div.box div.traffic div.legend {
1819 1819 clear: both;
1820 1820 overflow: hidden;
1821 1821 border-bottom: 1px solid #ddd;
1822 1822 margin: 0 0 10px;
1823 1823 padding: 0 0 10px;
1824 1824 }
1825 1825
1826 1826 #content div.box div.traffic div.legend h6 {
1827 1827 float: left;
1828 1828 border: none;
1829 1829 margin: 0;
1830 1830 padding: 0;
1831 1831 }
1832 1832
1833 1833 #content div.box div.traffic div.legend li {
1834 1834 list-style: none;
1835 1835 float: left;
1836 1836 font-size: 11px;
1837 1837 margin: 0;
1838 1838 padding: 0 8px 0 4px;
1839 1839 }
1840 1840
1841 1841 #content div.box div.traffic div.legend li.visits {
1842 1842 border-left: 12px solid #edc240;
1843 1843 }
1844 1844
1845 1845 #content div.box div.traffic div.legend li.pageviews {
1846 1846 border-left: 12px solid #afd8f8;
1847 1847 }
1848 1848
1849 1849 #content div.box div.traffic table {
1850 1850 width: auto;
1851 1851 }
1852 1852
1853 1853 #content div.box div.traffic table td {
1854 1854 background: transparent;
1855 1855 border: none;
1856 1856 padding: 2px 3px 3px;
1857 1857 }
1858 1858
1859 1859 #content div.box div.traffic table td.legendLabel {
1860 1860 padding: 0 3px 2px;
1861 1861 }
1862 1862
1863 1863 #summary {
1864 1864 }
1865 1865
1866 1866 #summary .metatag {
1867 1867 display: inline-block;
1868 1868 padding: 3px 5px;
1869 1869 margin-bottom: 3px;
1870 1870 margin-right: 1px;
1871 1871 border-radius: 5px;
1872 1872 }
1873 1873
1874 1874 #content div.box #summary p {
1875 1875 margin-bottom: -5px;
1876 1876 width: 600px;
1877 1877 white-space: pre-wrap;
1878 1878 }
1879 1879
1880 1880 #content div.box #summary p:last-child {
1881 1881 margin-bottom: 9px;
1882 1882 }
1883 1883
1884 1884 #content div.box #summary p:first-of-type {
1885 1885 margin-top: 9px;
1886 1886 }
1887 1887
1888 1888 .metatag {
1889 1889 display: inline-block;
1890 1890 margin-right: 1px;
1891 1891 -webkit-border-radius: 4px 4px 4px 4px;
1892 1892 -khtml-border-radius: 4px 4px 4px 4px;
1893 1893 -moz-border-radius: 4px 4px 4px 4px;
1894 1894 border-radius: 4px 4px 4px 4px;
1895 1895
1896 1896 border: solid 1px #9CF;
1897 1897 padding: 2px 3px 2px 3px !important;
1898 1898 background-color: #DEF;
1899 1899 }
1900 1900
1901 1901 .metatag[tag="dead"] {
1902 1902 background-color: #E44;
1903 1903 }
1904 1904
1905 1905 .metatag[tag="stale"] {
1906 1906 background-color: #EA4;
1907 1907 }
1908 1908
1909 1909 .metatag[tag="featured"] {
1910 1910 background-color: #AEA;
1911 1911 }
1912 1912
1913 1913 .metatag[tag="requires"] {
1914 1914 background-color: #9CF;
1915 1915 }
1916 1916
1917 1917 .metatag[tag="recommends"] {
1918 1918 background-color: #BDF;
1919 1919 }
1920 1920
1921 1921 .metatag[tag="lang"] {
1922 1922 background-color: #FAF474;
1923 1923 }
1924 1924
1925 1925 .metatag[tag="license"] {
1926 1926 border: solid 1px #9CF;
1927 1927 background-color: #DEF;
1928 1928 target-new: tab !important;
1929 1929 }
1930 1930 .metatag[tag="see"] {
1931 1931 border: solid 1px #CBD;
1932 1932 background-color: #EDF;
1933 1933 }
1934 1934
1935 1935 a.metatag[tag="license"]:hover {
1936 1936 background-color: #003367;
1937 1937 color: #FFF;
1938 1938 text-decoration: none;
1939 1939 }
1940 1940
1941 1941 #summary .desc {
1942 1942 white-space: pre;
1943 1943 width: 100%;
1944 1944 }
1945 1945
1946 1946 #summary .repo_name {
1947 1947 font-size: 1.6em;
1948 1948 font-weight: bold;
1949 1949 vertical-align: baseline;
1950 1950 clear: right
1951 1951 }
1952 1952
1953 1953 #footer {
1954 1954 clear: both;
1955 1955 overflow: hidden;
1956 1956 text-align: right;
1957 1957 margin: 0;
1958 1958 padding: 0 10px 4px;
1959 1959 margin: -10px 0 0;
1960 1960 }
1961 1961
1962 1962 #footer div#footer-inner {
1963 1963 background-color: #003B76;
1964 1964 background-repeat : repeat-x;
1965 1965 background-image : -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
1966 1966 background-image : -moz-linear-gradient(top, #003b76, #00376e);
1967 1967 background-image : -ms-linear-gradient( top, #003b76, #00376e);
1968 1968 background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1969 1969 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
1970 1970 background-image : -o-linear-gradient( top, #003b76, #00376e));
1971 1971 background-image : linear-gradient( top, #003b76, #00376e);
1972 1972 filter :progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
1973 1973 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1974 1974 -webkit-border-radius: 4px 4px 4px 4px;
1975 1975 -khtml-border-radius: 4px 4px 4px 4px;
1976 1976 -moz-border-radius: 4px 4px 4px 4px;
1977 1977 border-radius: 4px 4px 4px 4px;
1978 1978 }
1979 1979
1980 1980 #footer div#footer-inner p {
1981 1981 padding: 15px 25px 15px 0;
1982 1982 color: #FFF;
1983 1983 font-weight: 700;
1984 1984 }
1985 1985
1986 1986 #footer div#footer-inner .footer-link {
1987 1987 float: left;
1988 1988 padding-left: 10px;
1989 1989 }
1990 1990
1991 1991 #footer div#footer-inner .footer-link a, #footer div#footer-inner .footer-link-right a {
1992 1992 color: #FFF;
1993 1993 }
1994 1994
1995 1995 #login div.title {
1996 1996 clear: both;
1997 1997 overflow: hidden;
1998 1998 position: relative;
1999 1999 background-color: #003B76;
2000 2000 background-repeat : repeat-x;
2001 2001 background-image : -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
2002 2002 background-image : -moz-linear-gradient( top, #003b76, #00376e);
2003 2003 background-image : -ms-linear-gradient( top, #003b76, #00376e);
2004 2004 background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
2005 2005 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
2006 2006 background-image : -o-linear-gradient( top, #003b76, #00376e));
2007 2007 background-image : linear-gradient( top, #003b76, #00376e);
2008 2008 filter : progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
2009 2009 margin: 0 auto;
2010 2010 padding: 0;
2011 2011 }
2012 2012
2013 2013 #login div.inner {
2014 2014 background: #FFF url("../images/login.png") no-repeat top left;
2015 2015 border-top: none;
2016 2016 border-bottom: none;
2017 2017 margin: 0 auto;
2018 2018 padding: 20px;
2019 2019 }
2020 2020
2021 2021 #login div.form div.fields div.field div.label {
2022 2022 width: 173px;
2023 2023 float: left;
2024 2024 text-align: right;
2025 2025 margin: 2px 10px 0 0;
2026 2026 padding: 5px 0 0 5px;
2027 2027 }
2028 2028
2029 2029 #login div.form div.fields div.field div.input input {
2030 2030 background: #FFF;
2031 2031 border-top: 1px solid #b3b3b3;
2032 2032 border-left: 1px solid #b3b3b3;
2033 2033 border-right: 1px solid #eaeaea;
2034 2034 border-bottom: 1px solid #eaeaea;
2035 2035 color: #000;
2036 2036 font-size: 11px;
2037 2037 margin: 0;
2038 2038 padding: 7px 7px 6px;
2039 2039 }
2040 2040
2041 2041 #login div.form div.fields div.buttons {
2042 2042 clear: both;
2043 2043 overflow: hidden;
2044 2044 border-top: 1px solid #DDD;
2045 2045 text-align: right;
2046 2046 margin: 0;
2047 2047 padding: 10px 0 0;
2048 2048 }
2049 2049
2050 2050 #login div.form div.links {
2051 2051 clear: both;
2052 2052 overflow: hidden;
2053 2053 margin: 10px 0 0;
2054 2054 padding: 0 0 2px;
2055 2055 }
2056 2056
2057 2057 .user-menu {
2058 2058 margin: 0px !important;
2059 2059 float: left;
2060 2060 }
2061 2061
2062 2062 .user-menu .container {
2063 2063 padding:0px 4px 0px 4px;
2064 2064 margin: 0px 0px 0px 0px;
2065 2065 }
2066 2066
2067 2067 .user-menu .gravatar {
2068 2068 margin: 0px 0px 0px 0px;
2069 2069 cursor: pointer;
2070 2070 }
2071 2071 .user-menu .gravatar.enabled {
2072 2072 background-color: #FDF784 !important;
2073 2073 }
2074 2074 .user-menu .gravatar:hover {
2075 2075 background-color: #FDF784 !important;
2076 2076 }
2077 2077 #quick_login {
2078 2078 min-height: 80px;
2079 2079 padding: 4px;
2080 2080 position: absolute;
2081 2081 right: 0;
2082 2082 width: 278px;
2083 2083 background-color: #003B76;
2084 2084 background-repeat: repeat-x;
2085 2085 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2086 2086 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2087 2087 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2088 2088 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2089 2089 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2090 2090 background-image: -o-linear-gradient(top, #003b76, #00376e);
2091 2091 background-image: linear-gradient(top, #003b76, #00376e);
2092 2092 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
2093 2093
2094 2094 z-index: 999;
2095 2095 -webkit-border-radius: 0px 0px 4px 4px;
2096 2096 -khtml-border-radius: 0px 0px 4px 4px;
2097 2097 -moz-border-radius: 0px 0px 4px 4px;
2098 2098 border-radius: 0px 0px 4px 4px;
2099 2099 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
2100 2100 }
2101 2101 #quick_login h4 {
2102 2102 color: #fff;
2103 2103 padding: 5px 0px 5px 14px;
2104 2104 }
2105 2105
2106 2106 #quick_login .password_forgoten {
2107 2107 padding-right: 10px;
2108 2108 padding-top: 0px;
2109 2109 text-align: left;
2110 2110 }
2111 2111
2112 2112 #quick_login .password_forgoten a {
2113 2113 font-size: 10px;
2114 2114 color: #fff;
2115 2115 }
2116 2116
2117 2117 #quick_login .register {
2118 2118 padding-right: 10px;
2119 2119 padding-top: 5px;
2120 2120 text-align: left;
2121 2121 }
2122 2122
2123 2123 #quick_login .register a {
2124 2124 font-size: 10px;
2125 2125 color: #fff;
2126 2126 }
2127 2127
2128 2128 #quick_login .submit {
2129 2129 margin: -20px 0 0 0px;
2130 2130 position: absolute;
2131 2131 right: 15px;
2132 2132 }
2133 2133
2134 2134 #quick_login .links_left {
2135 2135 float: left;
2136 2136 }
2137 2137 #quick_login .links_right {
2138 2138 float: right;
2139 2139 }
2140 2140 #quick_login .full_name {
2141 2141 color: #FFFFFF;
2142 2142 font-weight: bold;
2143 2143 padding: 3px 3px 3px 6px;
2144 2144 }
2145 2145 #quick_login .big_gravatar {
2146 2146 padding:4px 0px 0px 6px;
2147 2147 }
2148 2148 #quick_login .notifications {
2149 2149 padding:4px 0px 0px 6px;
2150 2150 color: #FFFFFF;
2151 2151 font-weight: bold;
2152 2152 }
2153 2153 #quick_login .notifications a,
2154 2154 #quick_login .unread a {
2155 2155 color: #FFFFFF;
2156 2156 display: block;
2157 2157 padding: 2px;
2158 2158 }
2159 2159 #quick_login .notifications a:hover,
2160 2160 #quick_login .unread a:hover {
2161 2161 background-color: inherit !important;
2162 2162 }
2163 2163 #quick_login .email, #quick_login .unread {
2164 2164 color: #FFFFFF;
2165 2165 padding: 3px 3px 3px 6px;
2166 2166 }
2167 2167 #quick_login .links .logout {
2168 2168 }
2169 2169
2170 2170 #quick_login div.form div.fields {
2171 2171 padding-top: 2px;
2172 2172 padding-left: 10px;
2173 2173 }
2174 2174
2175 2175 #quick_login div.form div.fields div.field {
2176 2176 padding: 5px;
2177 2177 }
2178 2178
2179 2179 #quick_login div.form div.fields div.field div.label label {
2180 2180 color: #fff;
2181 2181 padding-bottom: 3px;
2182 2182 }
2183 2183
2184 2184 #quick_login div.form div.fields div.field div.input input {
2185 2185 width: 236px;
2186 2186 background: #FFF;
2187 2187 border-top: 1px solid #b3b3b3;
2188 2188 border-left: 1px solid #b3b3b3;
2189 2189 border-right: 1px solid #eaeaea;
2190 2190 border-bottom: 1px solid #eaeaea;
2191 2191 color: #000;
2192 2192 font-size: 11px;
2193 2193 margin: 0;
2194 2194 padding: 5px 7px 4px;
2195 2195 }
2196 2196
2197 2197 #quick_login div.form div.fields div.buttons {
2198 2198 clear: both;
2199 2199 overflow: hidden;
2200 2200 text-align: right;
2201 2201 margin: 0;
2202 2202 padding: 5px 14px 0px 5px;
2203 2203 }
2204 2204
2205 2205 #quick_login div.form div.links {
2206 2206 clear: both;
2207 2207 overflow: hidden;
2208 2208 margin: 10px 0 0;
2209 2209 padding: 0 0 2px;
2210 2210 }
2211 2211
2212 2212 #quick_login ol.links {
2213 2213 display: block;
2214 2214 font-weight: bold;
2215 2215 list-style: none outside none;
2216 2216 text-align: right;
2217 2217 }
2218 2218 #quick_login ol.links li {
2219 2219 line-height: 27px;
2220 2220 margin: 0;
2221 2221 padding: 0;
2222 2222 color: #fff;
2223 2223 display: block;
2224 2224 float:none !important;
2225 2225 }
2226 2226
2227 2227 #quick_login ol.links li a {
2228 2228 color: #fff;
2229 2229 display: block;
2230 2230 padding: 2px;
2231 2231 }
2232 2232 #quick_login ol.links li a:HOVER {
2233 2233 background-color: inherit !important;
2234 2234 }
2235 2235
2236 2236 #register div.title {
2237 2237 clear: both;
2238 2238 overflow: hidden;
2239 2239 position: relative;
2240 2240 background-color: #003B76;
2241 2241 background-repeat: repeat-x;
2242 2242 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2243 2243 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2244 2244 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2245 2245 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2246 2246 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2247 2247 background-image: -o-linear-gradient(top, #003b76, #00376e);
2248 2248 background-image: linear-gradient(top, #003b76, #00376e);
2249 2249 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
2250 2250 endColorstr='#00376e', GradientType=0 );
2251 2251 margin: 0 auto;
2252 2252 padding: 0;
2253 2253 }
2254 2254
2255 2255 #register div.inner {
2256 2256 background: #FFF;
2257 2257 border-top: none;
2258 2258 border-bottom: none;
2259 2259 margin: 0 auto;
2260 2260 padding: 20px;
2261 2261 }
2262 2262
2263 2263 #register div.form div.fields div.field div.label {
2264 2264 width: 135px;
2265 2265 float: left;
2266 2266 text-align: right;
2267 2267 margin: 2px 10px 0 0;
2268 2268 padding: 5px 0 0 5px;
2269 2269 }
2270 2270
2271 2271 #register div.form div.fields div.field div.input input {
2272 2272 width: 300px;
2273 2273 background: #FFF;
2274 2274 border-top: 1px solid #b3b3b3;
2275 2275 border-left: 1px solid #b3b3b3;
2276 2276 border-right: 1px solid #eaeaea;
2277 2277 border-bottom: 1px solid #eaeaea;
2278 2278 color: #000;
2279 2279 font-size: 11px;
2280 2280 margin: 0;
2281 2281 padding: 7px 7px 6px;
2282 2282 }
2283 2283
2284 2284 #register div.form div.fields div.buttons {
2285 2285 clear: both;
2286 2286 overflow: hidden;
2287 2287 border-top: 1px solid #DDD;
2288 2288 text-align: left;
2289 2289 margin: 0;
2290 2290 padding: 10px 0 0 150px;
2291 2291 }
2292 2292
2293 2293 #register div.form div.activation_msg {
2294 2294 padding-top: 4px;
2295 2295 padding-bottom: 4px;
2296 2296 }
2297 2297
2298 2298 #journal .journal_day {
2299 2299 font-size: 20px;
2300 2300 padding: 10px 0px;
2301 2301 border-bottom: 2px solid #DDD;
2302 2302 margin-left: 10px;
2303 2303 margin-right: 10px;
2304 2304 }
2305 2305
2306 2306 #journal .journal_container {
2307 2307 padding: 5px;
2308 2308 clear: both;
2309 2309 margin: 0px 5px 0px 10px;
2310 2310 }
2311 2311
2312 2312 #journal .journal_action_container {
2313 2313 padding-left: 38px;
2314 2314 }
2315 2315
2316 2316 #journal .journal_user {
2317 2317 color: #747474;
2318 2318 font-size: 14px;
2319 2319 font-weight: bold;
2320 2320 height: 30px;
2321 2321 }
2322 2322
2323 2323 #journal .journal_user.deleted {
2324 2324 color: #747474;
2325 2325 font-size: 14px;
2326 2326 font-weight: normal;
2327 2327 height: 30px;
2328 2328 font-style: italic;
2329 2329 }
2330 2330
2331 2331
2332 2332 #journal .journal_icon {
2333 2333 clear: both;
2334 2334 float: left;
2335 2335 padding-right: 4px;
2336 2336 padding-top: 3px;
2337 2337 }
2338 2338
2339 2339 #journal .journal_action {
2340 2340 padding-top: 4px;
2341 2341 min-height: 2px;
2342 2342 float: left
2343 2343 }
2344 2344
2345 2345 #journal .journal_action_params {
2346 2346 clear: left;
2347 2347 padding-left: 22px;
2348 2348 }
2349 2349
2350 2350 #journal .journal_repo {
2351 2351 float: left;
2352 2352 margin-left: 6px;
2353 2353 padding-top: 3px;
2354 2354 }
2355 2355
2356 2356 #journal .date {
2357 2357 clear: both;
2358 2358 color: #777777;
2359 2359 font-size: 11px;
2360 2360 padding-left: 22px;
2361 2361 }
2362 2362
2363 2363 #journal .journal_repo .journal_repo_name {
2364 2364 font-weight: bold;
2365 2365 font-size: 1.1em;
2366 2366 }
2367 2367
2368 2368 #journal .compare_view {
2369 2369 padding: 5px 0px 5px 0px;
2370 2370 width: 95px;
2371 2371 }
2372 2372
2373 2373 .journal_highlight {
2374 2374 font-weight: bold;
2375 2375 padding: 0 2px;
2376 2376 vertical-align: bottom;
2377 2377 }
2378 2378
2379 2379 .trending_language_tbl, .trending_language_tbl td {
2380 2380 border: 0 !important;
2381 2381 margin: 0 !important;
2382 2382 padding: 0 !important;
2383 2383 }
2384 2384
2385 2385 .trending_language_tbl, .trending_language_tbl tr {
2386 2386 border-spacing: 1px;
2387 2387 }
2388 2388
2389 2389 .trending_language {
2390 2390 background-color: #003367;
2391 2391 color: #FFF;
2392 2392 display: block;
2393 2393 min-width: 20px;
2394 2394 text-decoration: none;
2395 2395 height: 12px;
2396 2396 margin-bottom: 0px;
2397 2397 margin-left: 5px;
2398 2398 white-space: pre;
2399 2399 padding: 3px;
2400 2400 }
2401 2401
2402 2402 h3.files_location {
2403 2403 font-size: 1.8em;
2404 2404 font-weight: 700;
2405 2405 border-bottom: none !important;
2406 2406 margin: 10px 0 !important;
2407 2407 }
2408 2408
2409 2409 #files_data dl dt {
2410 2410 float: left;
2411 2411 width: 60px;
2412 2412 margin: 0 !important;
2413 2413 padding: 5px;
2414 2414 }
2415 2415
2416 2416 #files_data dl dd {
2417 2417 margin: 0 !important;
2418 2418 padding: 5px !important;
2419 2419 }
2420 2420
2421 2421 .file_history {
2422 2422 padding-top:10px;
2423 2423 font-size:16px;
2424 2424 }
2425 2425 .file_author {
2426 2426 float: left;
2427 2427 }
2428 2428
2429 2429 .file_author .item {
2430 2430 float:left;
2431 2431 padding:5px;
2432 2432 color: #888;
2433 2433 }
2434 2434
2435 2435 .tablerow0 {
2436 2436 background-color: #F8F8F8;
2437 2437 }
2438 2438
2439 2439 .tablerow1 {
2440 2440 background-color: #FFFFFF;
2441 2441 }
2442 2442
2443 2443 .changeset_id {
2444 2444 font-family: monospace;
2445 2445 color: #666666;
2446 2446 }
2447 2447
2448 2448 .changeset_hash {
2449 2449 color: #000000;
2450 2450 }
2451 2451
2452 2452 #changeset_content {
2453 2453 border-left: 1px solid #CCC;
2454 2454 border-right: 1px solid #CCC;
2455 2455 border-bottom: 1px solid #CCC;
2456 2456 padding: 5px;
2457 2457 }
2458 2458
2459 2459 #changeset_compare_view_content {
2460 2460 border: 1px solid #CCC;
2461 2461 padding: 5px;
2462 2462 }
2463 2463
2464 2464 #changeset_content .container {
2465 2465 min-height: 100px;
2466 2466 font-size: 1.2em;
2467 2467 overflow: hidden;
2468 2468 }
2469 2469
2470 2470 #changeset_compare_view_content .compare_view_commits {
2471 2471 width: auto !important;
2472 2472 }
2473 2473
2474 2474 #changeset_compare_view_content .compare_view_commits td {
2475 2475 padding: 0px 0px 0px 12px !important;
2476 2476 }
2477 2477
2478 2478 #changeset_content .container .right {
2479 2479 float: right;
2480 2480 width: 20%;
2481 2481 text-align: right;
2482 2482 }
2483 2483
2484 2484 #changeset_content .container .left .message {
2485 2485 white-space: pre-wrap;
2486 2486 }
2487 2487 #changeset_content .container .left .message a:hover {
2488 2488 text-decoration: none;
2489 2489 }
2490 2490 .cs_files .cur_cs {
2491 2491 margin: 10px 2px;
2492 2492 font-weight: bold;
2493 2493 }
2494 2494
2495 2495 .cs_files .node {
2496 2496 float: left;
2497 2497 }
2498 2498
2499 2499 .cs_files .changes {
2500 2500 float: right;
2501 2501 color:#003367;
2502 2502 }
2503 2503
2504 2504 .cs_files .changes .added {
2505 2505 background-color: #BBFFBB;
2506 2506 float: left;
2507 2507 text-align: center;
2508 2508 font-size: 9px;
2509 2509 padding: 2px 0px 2px 0px;
2510 2510 }
2511 2511
2512 2512 .cs_files .changes .deleted {
2513 2513 background-color: #FF8888;
2514 2514 float: left;
2515 2515 text-align: center;
2516 2516 font-size: 9px;
2517 2517 padding: 2px 0px 2px 0px;
2518 2518 }
2519 2519 /*new binary*/
2520 2520 .cs_files .changes .bin1 {
2521 2521 background-color: #BBFFBB;
2522 2522 float: left;
2523 2523 text-align: center;
2524 2524 font-size: 9px;
2525 2525 padding: 2px 0px 2px 0px;
2526 2526 }
2527 2527
2528 2528 /*deleted binary*/
2529 2529 .cs_files .changes .bin2 {
2530 2530 background-color: #FF8888;
2531 2531 float: left;
2532 2532 text-align: center;
2533 2533 font-size: 9px;
2534 2534 padding: 2px 0px 2px 0px;
2535 2535 }
2536 2536
2537 2537 /*mod binary*/
2538 2538 .cs_files .changes .bin3 {
2539 2539 background-color: #DDDDDD;
2540 2540 float: left;
2541 2541 text-align: center;
2542 2542 font-size: 9px;
2543 2543 padding: 2px 0px 2px 0px;
2544 2544 }
2545 2545
2546 2546 /*rename file*/
2547 2547 .cs_files .changes .bin4 {
2548 2548 background-color: #6D99FF;
2549 2549 float: left;
2550 2550 text-align: center;
2551 2551 font-size: 9px;
2552 2552 padding: 2px 0px 2px 0px;
2553 2553 }
2554 2554
2555 2555
2556 2556 .cs_files .cs_added, .cs_files .cs_A {
2557 2557 background: url("../images/icons/page_white_add.png") no-repeat scroll
2558 2558 3px;
2559 2559 height: 16px;
2560 2560 padding-left: 20px;
2561 2561 margin-top: 7px;
2562 2562 text-align: left;
2563 2563 }
2564 2564
2565 2565 .cs_files .cs_changed, .cs_files .cs_M {
2566 2566 background: url("../images/icons/page_white_edit.png") no-repeat scroll
2567 2567 3px;
2568 2568 height: 16px;
2569 2569 padding-left: 20px;
2570 2570 margin-top: 7px;
2571 2571 text-align: left;
2572 2572 }
2573 2573
2574 2574 .cs_files .cs_removed, .cs_files .cs_D {
2575 2575 background: url("../images/icons/page_white_delete.png") no-repeat
2576 2576 scroll 3px;
2577 2577 height: 16px;
2578 2578 padding-left: 20px;
2579 2579 margin-top: 7px;
2580 2580 text-align: left;
2581 2581 }
2582 2582
2583 2583 #graph {
2584 2584 overflow: hidden;
2585 2585 }
2586 2586
2587 2587 #graph_nodes {
2588 2588 float: left;
2589 2589 margin-right: 0px;
2590 2590 margin-top: 0px;
2591 2591 }
2592 2592
2593 2593 #graph_content {
2594 2594 width: 80%;
2595 2595 float: left;
2596 2596 }
2597 2597
2598 2598 #graph_content .container_header {
2599 2599 border-bottom: 1px solid #DDD;
2600 2600 padding: 10px;
2601 2601 height: 25px;
2602 2602 }
2603 2603
2604 2604 #graph_content #rev_range_container {
2605 2605 float: left;
2606 2606 margin: 0px 0px 0px 3px;
2607 2607 }
2608 2608
2609 2609 #graph_content #rev_range_clear {
2610 2610 float: left;
2611 2611 margin: 0px 0px 0px 3px;
2612 2612 }
2613 2613
2614 2614 #graph_content .container {
2615 2615 border-bottom: 1px solid #DDD;
2616 2616 height: 56px;
2617 2617 overflow: hidden;
2618 2618 }
2619 2619
2620 2620 #graph_content .container .right {
2621 2621 float: right;
2622 2622 width: 23%;
2623 2623 text-align: right;
2624 2624 }
2625 2625
2626 2626 #graph_content .container .left {
2627 2627 float: left;
2628 2628 width: 25%;
2629 2629 padding-left: 5px;
2630 2630 }
2631 2631
2632 2632 #graph_content .container .mid {
2633 2633 float: left;
2634 2634 width: 49%;
2635 2635 }
2636 2636
2637 2637
2638 2638 #graph_content .container .left .date {
2639 2639 color: #666;
2640 2640 padding-left: 22px;
2641 2641 font-size: 10px;
2642 2642 }
2643 2643
2644 2644 #graph_content .container .left .author {
2645 2645 height: 22px;
2646 2646 }
2647 2647
2648 2648 #graph_content .container .left .author .user {
2649 2649 color: #444444;
2650 2650 float: left;
2651 2651 margin-left: -4px;
2652 2652 margin-top: 4px;
2653 2653 }
2654 2654
2655 2655 #graph_content .container .mid .message {
2656 2656 white-space: pre-wrap;
2657 2657 }
2658 2658
2659 2659 #graph_content .container .mid .message a:hover {
2660 2660 text-decoration: none;
2661 2661 }
2662 2662
2663 2663 .revision-link {
2664 2664 color:#3F6F9F;
2665 2665 font-weight: bold !important;
2666 2666 }
2667 2667
2668 2668 .issue-tracker-link {
2669 2669 color:#3F6F9F;
2670 2670 font-weight: bold !important;
2671 2671 }
2672 2672
2673 2673 .changeset-status-container {
2674 2674 padding-right: 5px;
2675 2675 margin-top:1px;
2676 2676 float:right;
2677 2677 height:14px;
2678 2678 }
2679 2679 .code-header .changeset-status-container {
2680 2680 float:left;
2681 2681 padding:2px 0px 0px 2px;
2682 2682 }
2683 2683 .changeset-status-container .changeset-status-lbl {
2684 2684 color: rgb(136, 136, 136);
2685 2685 float: left;
2686 2686 padding: 3px 4px 0px 0px
2687 2687 }
2688 2688 .code-header .changeset-status-container .changeset-status-lbl {
2689 2689 float: left;
2690 2690 padding: 0px 4px 0px 0px;
2691 2691 }
2692 2692 .changeset-status-container .changeset-status-ico {
2693 2693 float: left;
2694 2694 }
2695 2695 .code-header .changeset-status-container .changeset-status-ico, .container .changeset-status-ico {
2696 2696 float: left;
2697 2697 }
2698 2698 .right .comments-container {
2699 2699 padding-right: 5px;
2700 2700 margin-top:1px;
2701 2701 float:right;
2702 2702 height:14px;
2703 2703 }
2704 2704
2705 2705 .right .comments-cnt {
2706 2706 float: left;
2707 2707 color: rgb(136, 136, 136);
2708 2708 padding-right: 2px;
2709 2709 }
2710 2710
2711 2711 .right .changes {
2712 2712 clear: both;
2713 2713 }
2714 2714
2715 2715 .right .changes .changed_total {
2716 2716 display: block;
2717 2717 float: right;
2718 2718 text-align: center;
2719 2719 min-width: 45px;
2720 2720 cursor: pointer;
2721 2721 color: #444444;
2722 2722 background: #FEA;
2723 2723 -webkit-border-radius: 0px 0px 0px 6px;
2724 2724 -moz-border-radius: 0px 0px 0px 6px;
2725 2725 border-radius: 0px 0px 0px 6px;
2726 2726 padding: 1px;
2727 2727 }
2728 2728
2729 2729 .right .changes .added, .changed, .removed {
2730 2730 display: block;
2731 2731 padding: 1px;
2732 2732 color: #444444;
2733 2733 float: right;
2734 2734 text-align: center;
2735 2735 min-width: 15px;
2736 2736 }
2737 2737
2738 2738 .right .changes .added {
2739 2739 background: #CFC;
2740 2740 }
2741 2741
2742 2742 .right .changes .changed {
2743 2743 background: #FEA;
2744 2744 }
2745 2745
2746 2746 .right .changes .removed {
2747 2747 background: #FAA;
2748 2748 }
2749 2749
2750 2750 .right .merge {
2751 2751 padding: 1px 3px 1px 3px;
2752 2752 background-color: #fca062;
2753 2753 font-size: 10px;
2754 2754 font-weight: bold;
2755 2755 color: #ffffff;
2756 2756 text-transform: uppercase;
2757 2757 white-space: nowrap;
2758 2758 -webkit-border-radius: 3px;
2759 2759 -moz-border-radius: 3px;
2760 2760 border-radius: 3px;
2761 2761 margin-right: 2px;
2762 2762 }
2763 2763
2764 2764 .right .parent {
2765 2765 color: #666666;
2766 2766 clear:both;
2767 2767 }
2768 2768 .right .logtags {
2769 2769 padding: 2px 2px 2px 2px;
2770 2770 }
2771 2771 .right .logtags .branchtag, .right .logtags .tagtag, .right .logtags .booktag {
2772 2772 margin: 0px 2px;
2773 2773 }
2774 2774
2775 2775 .right .logtags .branchtag,
2776 2776 .logtags .branchtag,
2777 2777 .spantag {
2778 2778 padding: 1px 3px 1px 3px;
2779 2779 background-color: #bfbfbf;
2780 2780 font-size: 10px;
2781 2781 font-weight: bold;
2782 2782 color: #ffffff;
2783 2783 white-space: nowrap;
2784 2784 -webkit-border-radius: 3px;
2785 2785 -moz-border-radius: 3px;
2786 2786 border-radius: 3px;
2787 2787 }
2788 2788 .right .logtags .branchtag a:hover, .logtags .branchtag a {
2789 2789 color: #ffffff;
2790 2790 }
2791 2791 .right .logtags .branchtag a:hover, .logtags .branchtag a:hover {
2792 2792 text-decoration: none;
2793 2793 color: #ffffff;
2794 2794 }
2795 2795 .right .logtags .tagtag, .logtags .tagtag {
2796 2796 padding: 1px 3px 1px 3px;
2797 2797 background-color: #62cffc;
2798 2798 font-size: 10px;
2799 2799 font-weight: bold;
2800 2800 color: #ffffff;
2801 2801 white-space: nowrap;
2802 2802 -webkit-border-radius: 3px;
2803 2803 -moz-border-radius: 3px;
2804 2804 border-radius: 3px;
2805 2805 }
2806 2806 .right .logtags .tagtag a:hover, .logtags .tagtag a {
2807 2807 color: #ffffff;
2808 2808 }
2809 2809 .right .logtags .tagtag a:hover, .logtags .tagtag a:hover {
2810 2810 text-decoration: none;
2811 2811 color: #ffffff;
2812 2812 }
2813 2813 .right .logbooks .bookbook, .logbooks .bookbook, .right .logtags .bookbook, .logtags .bookbook {
2814 2814 padding: 1px 3px 1px 3px;
2815 2815 background-color: #46A546;
2816 2816 font-size: 10px;
2817 2817 font-weight: bold;
2818 2818 color: #ffffff;
2819 2819 text-transform: uppercase;
2820 2820 white-space: nowrap;
2821 2821 -webkit-border-radius: 3px;
2822 2822 -moz-border-radius: 3px;
2823 2823 border-radius: 3px;
2824 2824 }
2825 2825 .right .logbooks .bookbook, .logbooks .bookbook a, .right .logtags .bookbook, .logtags .bookbook a {
2826 2826 color: #ffffff;
2827 2827 }
2828 2828 .right .logbooks .bookbook, .logbooks .bookbook a:hover, .right .logtags .bookbook, .logtags .bookbook a:hover {
2829 2829 text-decoration: none;
2830 2830 color: #ffffff;
2831 2831 }
2832 2832 div.browserblock {
2833 2833 overflow: hidden;
2834 2834 border: 1px solid #ccc;
2835 2835 background: #f8f8f8;
2836 2836 font-size: 100%;
2837 2837 line-height: 125%;
2838 2838 padding: 0;
2839 2839 -webkit-border-radius: 6px 6px 0px 0px;
2840 2840 -moz-border-radius: 6px 6px 0px 0px;
2841 2841 border-radius: 6px 6px 0px 0px;
2842 2842 }
2843 2843
2844 2844 div.browserblock .browser-header {
2845 2845 background: #FFF;
2846 2846 padding: 10px 0px 15px 0px;
2847 2847 width: 100%;
2848 2848 }
2849 2849
2850 2850 div.browserblock .browser-nav {
2851 2851 float: left
2852 2852 }
2853 2853
2854 2854 div.browserblock .browser-branch {
2855 2855 float: left;
2856 2856 }
2857 2857
2858 2858 div.browserblock .browser-branch label {
2859 2859 color: #4A4A4A;
2860 2860 vertical-align: text-top;
2861 2861 }
2862 2862
2863 2863 div.browserblock .browser-header span {
2864 2864 margin-left: 5px;
2865 2865 font-weight: 700;
2866 2866 }
2867 2867
2868 2868 div.browserblock .browser-search {
2869 2869 clear: both;
2870 2870 padding: 8px 8px 0px 5px;
2871 2871 height: 20px;
2872 2872 }
2873 2873
2874 2874 div.browserblock #node_filter_box {
2875 2875 }
2876 2876
2877 2877 div.browserblock .search_activate {
2878 2878 float: left
2879 2879 }
2880 2880
2881 2881 div.browserblock .add_node {
2882 2882 float: left;
2883 2883 padding-left: 5px;
2884 2884 }
2885 2885
2886 2886 div.browserblock .search_activate a:hover, div.browserblock .add_node a:hover {
2887 2887 text-decoration: none !important;
2888 2888 }
2889 2889
2890 2890 div.browserblock .browser-body {
2891 2891 background: #EEE;
2892 2892 border-top: 1px solid #CCC;
2893 2893 }
2894 2894
2895 2895 table.code-browser {
2896 2896 border-collapse: collapse;
2897 2897 width: 100%;
2898 2898 }
2899 2899
2900 2900 table.code-browser tr {
2901 2901 margin: 3px;
2902 2902 }
2903 2903
2904 2904 table.code-browser thead th {
2905 2905 background-color: #EEE;
2906 2906 height: 20px;
2907 2907 font-size: 1.1em;
2908 2908 font-weight: 700;
2909 2909 text-align: left;
2910 2910 padding-left: 10px;
2911 2911 }
2912 2912
2913 2913 table.code-browser tbody td {
2914 2914 padding-left: 10px;
2915 2915 height: 20px;
2916 2916 }
2917 2917
2918 2918 table.code-browser .browser-file {
2919 2919 background: url("../images/icons/document_16.png") no-repeat scroll 3px;
2920 2920 height: 16px;
2921 2921 padding-left: 20px;
2922 2922 text-align: left;
2923 2923 }
2924 2924 .diffblock .changeset_header {
2925 2925 height: 16px;
2926 2926 }
2927 2927 .diffblock .changeset_file {
2928 2928 background: url("../images/icons/file.png") no-repeat scroll 3px;
2929 2929 text-align: left;
2930 2930 float: left;
2931 2931 padding: 2px 0px 2px 22px;
2932 2932 }
2933 2933 .diffblock .diff-menu-wrapper {
2934 2934 float: left;
2935 2935 }
2936 2936
2937 2937 .diffblock .diff-menu {
2938 2938 position: absolute;
2939 2939 background: none repeat scroll 0 0 #FFFFFF;
2940 2940 border-color: #003367 #666666 #666666;
2941 2941 border-right: 1px solid #666666;
2942 2942 border-style: solid solid solid;
2943 2943 border-width: 1px;
2944 2944 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
2945 2945 margin-top:5px;
2946 2946 margin-left:1px;
2947 2947
2948 2948 }
2949 2949 .diffblock .diff-actions {
2950 2950 padding: 2px 0px 0px 2px;
2951 2951 float: left;
2952 2952 }
2953 2953 .diffblock .diff-menu ul li {
2954 2954 padding: 0px 0px 0px 0px !important;
2955 2955 }
2956 2956 .diffblock .diff-menu ul li a {
2957 2957 display: block;
2958 2958 padding: 3px 8px 3px 8px !important;
2959 2959 }
2960 2960 .diffblock .diff-menu ul li a:hover {
2961 2961 text-decoration: none;
2962 2962 background-color: #EEEEEE;
2963 2963 }
2964 2964 table.code-browser .browser-dir {
2965 2965 background: url("../images/icons/folder_16.png") no-repeat scroll 3px;
2966 2966 height: 16px;
2967 2967 padding-left: 20px;
2968 2968 text-align: left;
2969 2969 }
2970 2970
2971 2971 table.code-browser .submodule-dir {
2972 2972 background: url("../images/icons/disconnect.png") no-repeat scroll 3px;
2973 2973 height: 16px;
2974 2974 padding-left: 20px;
2975 2975 text-align: left;
2976 2976 }
2977 2977
2978 2978
2979 2979 .box .search {
2980 2980 clear: both;
2981 2981 overflow: hidden;
2982 2982 margin: 0;
2983 2983 padding: 0 20px 10px;
2984 2984 }
2985 2985
2986 2986 .box .search div.search_path {
2987 2987 background: none repeat scroll 0 0 #EEE;
2988 2988 border: 1px solid #CCC;
2989 2989 color: blue;
2990 2990 margin-bottom: 10px;
2991 2991 padding: 10px 0;
2992 2992 }
2993 2993
2994 2994 .box .search div.search_path div.link {
2995 2995 font-weight: 700;
2996 2996 margin-left: 25px;
2997 2997 }
2998 2998
2999 2999 .box .search div.search_path div.link a {
3000 3000 color: #003367;
3001 3001 cursor: pointer;
3002 3002 text-decoration: none;
3003 3003 }
3004 3004
3005 3005 #path_unlock {
3006 3006 color: red;
3007 3007 font-size: 1.2em;
3008 3008 padding-left: 4px;
3009 3009 }
3010 3010
3011 3011 .info_box span {
3012 3012 margin-left: 3px;
3013 3013 margin-right: 3px;
3014 3014 }
3015 3015
3016 3016 .info_box .rev {
3017 3017 color: #003367;
3018 3018 font-size: 1.6em;
3019 3019 font-weight: bold;
3020 3020 vertical-align: sub;
3021 3021 }
3022 3022
3023 3023 .info_box input#at_rev, .info_box input#size {
3024 3024 background: #FFF;
3025 3025 border-top: 1px solid #b3b3b3;
3026 3026 border-left: 1px solid #b3b3b3;
3027 3027 border-right: 1px solid #eaeaea;
3028 3028 border-bottom: 1px solid #eaeaea;
3029 3029 color: #000;
3030 3030 font-size: 12px;
3031 3031 margin: 0;
3032 3032 padding: 1px 5px 1px;
3033 3033 }
3034 3034
3035 3035 .info_box input#view {
3036 3036 text-align: center;
3037 3037 padding: 4px 3px 2px 2px;
3038 3038 }
3039 3039
3040 3040 .yui-overlay, .yui-panel-container {
3041 3041 visibility: hidden;
3042 3042 position: absolute;
3043 3043 z-index: 2;
3044 3044 }
3045 3045
3046 3046 #tip-box {
3047 3047 position: absolute;
3048 3048
3049 3049 background-color: #FFF;
3050 3050 border: 2px solid #003367;
3051 3051 font: 100% sans-serif;
3052 3052 width: auto;
3053 3053 opacity: 1px;
3054 3054 padding: 8px;
3055 3055
3056 3056 white-space: pre-wrap;
3057 3057 -webkit-border-radius: 8px 8px 8px 8px;
3058 3058 -khtml-border-radius: 8px 8px 8px 8px;
3059 3059 -moz-border-radius: 8px 8px 8px 8px;
3060 3060 border-radius: 8px 8px 8px 8px;
3061 3061 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3062 3062 -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3063 3063 -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3064 3064 }
3065 3065
3066 3066 .hl-tip-box {
3067 3067 visibility: hidden;
3068 3068 position: absolute;
3069 3069 color: #666;
3070 3070 background-color: #FFF;
3071 3071 border: 2px solid #003367;
3072 3072 font: 100% sans-serif;
3073 3073 width: auto;
3074 3074 opacity: 1px;
3075 3075 padding: 8px;
3076 3076 white-space: pre-wrap;
3077 3077 -webkit-border-radius: 8px 8px 8px 8px;
3078 3078 -khtml-border-radius: 8px 8px 8px 8px;
3079 3079 -moz-border-radius: 8px 8px 8px 8px;
3080 3080 border-radius: 8px 8px 8px 8px;
3081 3081 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3082 3082 }
3083 3083
3084 3084
3085 3085 .mentions-container {
3086 3086 width: 90% !important;
3087 3087 }
3088 3088 .mentions-container .yui-ac-content {
3089 3089 width: 100% !important;
3090 3090 }
3091 3091
3092 3092 .ac {
3093 3093 vertical-align: top;
3094 3094 }
3095 3095
3096 3096 .ac .yui-ac {
3097 3097 position: inherit;
3098 3098 font-size: 100%;
3099 3099 }
3100 3100
3101 3101 .ac .perm_ac {
3102 3102 width: 20em;
3103 3103 }
3104 3104
3105 3105 .ac .yui-ac-input {
3106 3106 width: 100%;
3107 3107 }
3108 3108
3109 3109 .ac .yui-ac-container {
3110 3110 position: absolute;
3111 3111 top: 1.6em;
3112 3112 width: auto;
3113 3113 }
3114 3114
3115 3115 .ac .yui-ac-content {
3116 3116 position: absolute;
3117 3117 border: 1px solid gray;
3118 3118 background: #fff;
3119 3119 z-index: 9050;
3120 3120 }
3121 3121
3122 3122 .ac .yui-ac-shadow {
3123 3123 position: absolute;
3124 3124 width: 100%;
3125 3125 background: #000;
3126 3126 -moz-opacity: 0.1px;
3127 3127 opacity: .10;
3128 3128 filter: alpha(opacity = 10);
3129 3129 z-index: 9049;
3130 3130 margin: .3em;
3131 3131 }
3132 3132
3133 3133 .ac .yui-ac-content ul {
3134 3134 width: 100%;
3135 3135 margin: 0;
3136 3136 padding: 0;
3137 3137 z-index: 9050;
3138 3138 }
3139 3139
3140 3140 .ac .yui-ac-content li {
3141 3141 cursor: default;
3142 3142 white-space: nowrap;
3143 3143 margin: 0;
3144 3144 padding: 2px 5px;
3145 3145 height: 18px;
3146 3146 z-index: 9050;
3147 3147 display: block;
3148 3148 width: auto !important;
3149 3149 }
3150 3150
3151 3151 .ac .yui-ac-content li .ac-container-wrap {
3152 3152 width: auto;
3153 3153 }
3154 3154
3155 3155 .ac .yui-ac-content li.yui-ac-prehighlight {
3156 3156 background: #B3D4FF;
3157 3157 z-index: 9050;
3158 3158 }
3159 3159
3160 3160 .ac .yui-ac-content li.yui-ac-highlight {
3161 3161 background: #556CB5;
3162 3162 color: #FFF;
3163 3163 z-index: 9050;
3164 3164 }
3165 3165 .ac .yui-ac-bd {
3166 3166 z-index: 9050;
3167 3167 }
3168 3168
3169 3169 .follow {
3170 3170 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3171 3171 height: 16px;
3172 3172 width: 20px;
3173 3173 cursor: pointer;
3174 3174 display: block;
3175 3175 float: right;
3176 3176 margin-top: 2px;
3177 3177 }
3178 3178
3179 3179 .following {
3180 3180 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3181 3181 height: 16px;
3182 3182 width: 20px;
3183 3183 cursor: pointer;
3184 3184 display: block;
3185 3185 float: right;
3186 3186 margin-top: 2px;
3187 3187 }
3188 3188
3189 3189 .reposize {
3190 3190 background: url("../images/icons/server.png") no-repeat scroll 3px;
3191 3191 height: 16px;
3192 3192 width: 20px;
3193 3193 cursor: pointer;
3194 3194 display: block;
3195 3195 float: right;
3196 3196 margin-top: 2px;
3197 3197 }
3198 3198
3199 3199 #repo_size {
3200 3200 display: block;
3201 3201 margin-top: 4px;
3202 3202 color: #666;
3203 3203 float:right;
3204 3204 }
3205 3205
3206 3206 .locking_locked {
3207 3207 background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px;
3208 3208 height: 16px;
3209 3209 width: 20px;
3210 3210 cursor: pointer;
3211 3211 display: block;
3212 3212 float: right;
3213 3213 margin-top: 2px;
3214 3214 }
3215 3215
3216 3216 .locking_unlocked {
3217 3217 background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px;
3218 3218 height: 16px;
3219 3219 width: 20px;
3220 3220 cursor: pointer;
3221 3221 display: block;
3222 3222 float: right;
3223 3223 margin-top: 2px;
3224 3224 }
3225 3225
3226 3226 .currently_following {
3227 3227 padding-left: 10px;
3228 3228 padding-bottom: 5px;
3229 3229 }
3230 3230
3231 3231 .add_icon {
3232 3232 background: url("../images/icons/add.png") no-repeat scroll 3px;
3233 3233 padding-left: 20px;
3234 3234 padding-top: 0px;
3235 3235 text-align: left;
3236 3236 }
3237 3237
3238 3238 .accept_icon {
3239 3239 background: url("../images/icons/accept.png") no-repeat scroll 3px;
3240 3240 padding-left: 20px;
3241 3241 padding-top: 0px;
3242 3242 text-align: left;
3243 3243 }
3244 3244
3245 3245 .edit_icon {
3246 3246 background: url("../images/icons/application_form_edit.png") no-repeat scroll 3px;
3247 3247 padding-left: 20px;
3248 3248 padding-top: 0px;
3249 3249 text-align: left;
3250 3250 }
3251 3251
3252 3252 .delete_icon {
3253 3253 background: url("../images/icons/delete.png") no-repeat scroll 3px;
3254 3254 padding-left: 20px;
3255 3255 padding-top: 0px;
3256 3256 text-align: left;
3257 3257 }
3258 3258
3259 3259 .refresh_icon {
3260 3260 background: url("../images/icons/arrow_refresh.png") no-repeat scroll
3261 3261 3px;
3262 3262 padding-left: 20px;
3263 3263 padding-top: 0px;
3264 3264 text-align: left;
3265 3265 }
3266 3266
3267 3267 .pull_icon {
3268 3268 background: url("../images/icons/connect.png") no-repeat scroll 3px;
3269 3269 padding-left: 20px;
3270 3270 padding-top: 0px;
3271 3271 text-align: left;
3272 3272 }
3273 3273
3274 3274 .rss_icon {
3275 3275 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3276 3276 padding-left: 20px;
3277 3277 padding-top: 4px;
3278 3278 text-align: left;
3279 3279 font-size: 8px
3280 3280 }
3281 3281
3282 3282 .atom_icon {
3283 3283 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3284 3284 padding-left: 20px;
3285 3285 padding-top: 4px;
3286 3286 text-align: left;
3287 3287 font-size: 8px
3288 3288 }
3289 3289
3290 3290 .archive_icon {
3291 3291 background: url("../images/icons/compress.png") no-repeat scroll 3px;
3292 3292 padding-left: 20px;
3293 3293 text-align: left;
3294 3294 padding-top: 1px;
3295 3295 }
3296 3296
3297 3297 .start_following_icon {
3298 3298 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3299 3299 padding-left: 20px;
3300 3300 text-align: left;
3301 3301 padding-top: 0px;
3302 3302 }
3303 3303
3304 3304 .stop_following_icon {
3305 3305 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3306 3306 padding-left: 20px;
3307 3307 text-align: left;
3308 3308 padding-top: 0px;
3309 3309 }
3310 3310
3311 3311 .action_button {
3312 3312 border: 0;
3313 3313 display: inline;
3314 3314 }
3315 3315
3316 3316 .action_button:hover {
3317 3317 border: 0;
3318 3318 text-decoration: underline;
3319 3319 cursor: pointer;
3320 3320 }
3321 3321
3322 3322 #switch_repos {
3323 3323 position: absolute;
3324 3324 height: 25px;
3325 3325 z-index: 1;
3326 3326 }
3327 3327
3328 3328 #switch_repos select {
3329 3329 min-width: 150px;
3330 3330 max-height: 250px;
3331 3331 z-index: 1;
3332 3332 }
3333 3333
3334 3334 .breadcrumbs {
3335 3335 border: medium none;
3336 3336 color: #FFF;
3337 3337 float: left;
3338 3338 font-weight: 700;
3339 3339 font-size: 14px;
3340 3340 margin: 0;
3341 3341 padding: 11px 0 11px 10px;
3342 3342 }
3343 3343
3344 3344 .breadcrumbs .hash {
3345 3345 text-transform: none;
3346 3346 color: #fff;
3347 3347 }
3348 3348
3349 3349 .breadcrumbs a {
3350 3350 color: #FFF;
3351 3351 }
3352 3352
3353 3353 .flash_msg {
3354 3354 }
3355 3355
3356 3356 .flash_msg ul {
3357 3357 }
3358 3358
3359 3359 .error_red {
3360 3360 color:red;
3361 3361 }
3362 3362
3363 3363 .error_msg {
3364 3364 background-color: #c43c35;
3365 3365 background-repeat: repeat-x;
3366 3366 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35) );
3367 3367 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3368 3368 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3369 3369 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) );
3370 3370 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3371 3371 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3372 3372 background-image: linear-gradient(top, #ee5f5b, #c43c35);
3373 3373 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 );
3374 3374 border-color: #c43c35 #c43c35 #882a25;
3375 3375 }
3376 3376
3377 3377 .warning_msg {
3378 3378 color: #404040 !important;
3379 3379 background-color: #eedc94;
3380 3380 background-repeat: repeat-x;
3381 3381 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94) );
3382 3382 background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
3383 3383 background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
3384 3384 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) );
3385 3385 background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
3386 3386 background-image: -o-linear-gradient(top, #fceec1, #eedc94);
3387 3387 background-image: linear-gradient(top, #fceec1, #eedc94);
3388 3388 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 );
3389 3389 border-color: #eedc94 #eedc94 #e4c652;
3390 3390 }
3391 3391
3392 3392 .success_msg {
3393 3393 background-color: #57a957;
3394 3394 background-repeat: repeat-x !important;
3395 3395 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957) );
3396 3396 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3397 3397 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3398 3398 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) );
3399 3399 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3400 3400 background-image: -o-linear-gradient(top, #62c462, #57a957);
3401 3401 background-image: linear-gradient(top, #62c462, #57a957);
3402 3402 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 );
3403 3403 border-color: #57a957 #57a957 #3d773d;
3404 3404 }
3405 3405
3406 3406 .notice_msg {
3407 3407 background-color: #339bb9;
3408 3408 background-repeat: repeat-x;
3409 3409 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9) );
3410 3410 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3411 3411 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3412 3412 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) );
3413 3413 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3414 3414 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3415 3415 background-image: linear-gradient(top, #5bc0de, #339bb9);
3416 3416 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 );
3417 3417 border-color: #339bb9 #339bb9 #22697d;
3418 3418 }
3419 3419
3420 3420 .success_msg, .error_msg, .notice_msg, .warning_msg {
3421 3421 font-size: 12px;
3422 3422 font-weight: 700;
3423 3423 min-height: 14px;
3424 3424 line-height: 14px;
3425 3425 margin-bottom: 10px;
3426 3426 margin-top: 0;
3427 3427 display: block;
3428 3428 overflow: auto;
3429 3429 padding: 6px 10px 6px 10px;
3430 3430 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3431 3431 position: relative;
3432 3432 color: #FFF;
3433 3433 border-width: 1px;
3434 3434 border-style: solid;
3435 3435 -webkit-border-radius: 4px;
3436 3436 -moz-border-radius: 4px;
3437 3437 border-radius: 4px;
3438 3438 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3439 3439 -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3440 3440 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3441 3441 }
3442 3442
3443 3443 #msg_close {
3444 3444 background: transparent url("../icons/cross_grey_small.png") no-repeat scroll 0 0;
3445 3445 cursor: pointer;
3446 3446 height: 16px;
3447 3447 position: absolute;
3448 3448 right: 5px;
3449 3449 top: 5px;
3450 3450 width: 16px;
3451 3451 }
3452 3452 div#legend_data {
3453 3453 padding-left:10px;
3454 3454 }
3455 3455 div#legend_container table {
3456 3456 border: none !important;
3457 3457 }
3458 3458 div#legend_container table, div#legend_choices table {
3459 3459 width: auto !important;
3460 3460 }
3461 3461
3462 3462 table#permissions_manage {
3463 3463 width: 0 !important;
3464 3464 }
3465 3465
3466 3466 table#permissions_manage span.private_repo_msg {
3467 3467 font-size: 0.8em;
3468 3468 opacity: 0.6px;
3469 3469 }
3470 3470
3471 3471 table#permissions_manage td.private_repo_msg {
3472 3472 font-size: 0.8em;
3473 3473 }
3474 3474
3475 3475 table#permissions_manage tr#add_perm_input td {
3476 3476 vertical-align: middle;
3477 3477 }
3478 3478
3479 3479 div.gravatar {
3480 3480 background-color: #FFF;
3481 3481 float: left;
3482 3482 margin-right: 0.7em;
3483 3483 padding: 1px 1px 1px 1px;
3484 3484 line-height:0;
3485 3485 -webkit-border-radius: 3px;
3486 3486 -khtml-border-radius: 3px;
3487 3487 -moz-border-radius: 3px;
3488 3488 border-radius: 3px;
3489 3489 }
3490 3490
3491 3491 div.gravatar img {
3492 3492 -webkit-border-radius: 2px;
3493 3493 -khtml-border-radius: 2px;
3494 3494 -moz-border-radius: 2px;
3495 3495 border-radius: 2px;
3496 3496 }
3497 3497
3498 3498 #header, #content, #footer {
3499 3499 min-width: 978px;
3500 3500 }
3501 3501
3502 3502 #content {
3503 3503 clear: both;
3504 overflow: hidden;
3504 /*overflow: hidden;*/
3505 3505 padding: 10px 10px 14px 10px;
3506 3506 }
3507 3507
3508 3508 #content.hover {
3509 3509 padding: 55px 10px 14px 10px !important;
3510 3510 }
3511 3511
3512 3512 #content div.box div.title div.search {
3513 3513 border-left: 1px solid #316293;
3514 3514 }
3515 3515
3516 3516 #content div.box div.title div.search div.input input {
3517 3517 border: 1px solid #316293;
3518 3518 }
3519 3519
3520 3520 .ui-btn {
3521 3521 color: #515151;
3522 3522 background-color: #DADADA;
3523 3523 background-repeat: repeat-x;
3524 3524 background-image: -khtml-gradient(linear, left top, left bottom, from(#F4F4F4),to(#DADADA) );
3525 3525 background-image: -moz-linear-gradient(top, #F4F4F4, #DADADA);
3526 3526 background-image: -ms-linear-gradient(top, #F4F4F4, #DADADA);
3527 3527 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) );
3528 3528 background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) );
3529 3529 background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) );
3530 3530 background-image: linear-gradient(top, #F4F4F4, #DADADA);
3531 3531 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0);
3532 3532
3533 3533 border-top: 1px solid #DDD;
3534 3534 border-left: 1px solid #c6c6c6;
3535 3535 border-right: 1px solid #DDD;
3536 3536 border-bottom: 1px solid #c6c6c6;
3537 3537 color: #515151;
3538 3538 outline: none;
3539 3539 margin: 0px 3px 3px 0px;
3540 3540 -webkit-border-radius: 4px 4px 4px 4px !important;
3541 3541 -khtml-border-radius: 4px 4px 4px 4px !important;
3542 3542 -moz-border-radius: 4px 4px 4px 4px !important;
3543 3543 border-radius: 4px 4px 4px 4px !important;
3544 3544 cursor: pointer !important;
3545 3545 padding: 3px 3px 3px 3px;
3546 3546 background-position: 0 -15px;
3547 3547
3548 3548 }
3549 3549
3550 3550 .ui-btn.disabled {
3551 3551 color: #999;
3552 3552 }
3553 3553
3554 3554 .ui-btn.xsmall {
3555 3555 padding: 1px 2px 1px 1px;
3556 3556 }
3557 3557
3558 3558 .ui-btn.large {
3559 3559 padding: 6px 12px;
3560 3560 }
3561 3561
3562 3562 .ui-btn.clone {
3563 3563 padding: 5px 2px 6px 1px;
3564 3564 margin: 0px 0px 3px -4px;
3565 3565 -webkit-border-radius: 0px 4px 4px 0px !important;
3566 3566 -khtml-border-radius: 0px 4px 4px 0px !important;
3567 3567 -moz-border-radius: 0px 4px 4px 0px !important;
3568 3568 border-radius: 0px 4px 4px 0px !important;
3569 3569 width: 100px;
3570 3570 text-align: center;
3571 3571 display: inline-block;
3572 3572 position: relative;
3573 3573 top: -2px;
3574 3574 }
3575 3575 .ui-btn:focus {
3576 3576 outline: none;
3577 3577 }
3578 3578 .ui-btn:hover {
3579 3579 background-position: 0 -15px;
3580 3580 text-decoration: none;
3581 3581 color: #515151;
3582 3582 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 3px #FFFFFF !important;
3583 3583 }
3584 3584
3585 3585 .ui-btn.disabled:hover {
3586 3586 background-position:none;
3587 3587 color: #999;
3588 3588 text-decoration: none;
3589 3589 box-shadow: none !important;
3590 3590 }
3591 3591
3592 3592 .ui-btn.red {
3593 3593 color:#fff;
3594 3594 background-color: #c43c35;
3595 3595 background-repeat: repeat-x;
3596 3596 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
3597 3597 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3598 3598 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3599 3599 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));
3600 3600 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3601 3601 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3602 3602 background-image: linear-gradient(top, #ee5f5b, #c43c35);
3603 3603 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
3604 3604 border-color: #c43c35 #c43c35 #882a25;
3605 3605 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3606 3606 }
3607 3607
3608 3608
3609 3609 .ui-btn.blue {
3610 3610 color:#fff;
3611 3611 background-color: #339bb9;
3612 3612 background-repeat: repeat-x;
3613 3613 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));
3614 3614 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3615 3615 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3616 3616 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));
3617 3617 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3618 3618 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3619 3619 background-image: linear-gradient(top, #5bc0de, #339bb9);
3620 3620 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
3621 3621 border-color: #339bb9 #339bb9 #22697d;
3622 3622 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3623 3623 }
3624 3624
3625 3625 .ui-btn.green {
3626 3626 background-color: #57a957;
3627 3627 background-repeat: repeat-x;
3628 3628 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));
3629 3629 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3630 3630 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3631 3631 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));
3632 3632 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3633 3633 background-image: -o-linear-gradient(top, #62c462, #57a957);
3634 3634 background-image: linear-gradient(top, #62c462, #57a957);
3635 3635 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
3636 3636 border-color: #57a957 #57a957 #3d773d;
3637 3637 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3638 3638 }
3639 3639
3640 3640 .ui-btn.blue.hidden {
3641 3641 display: none;
3642 3642 }
3643 3643
3644 3644 .ui-btn.active {
3645 3645 font-weight: bold;
3646 3646 }
3647 3647
3648 3648 ins, div.options a:hover {
3649 3649 text-decoration: none;
3650 3650 }
3651 3651
3652 3652 img,
3653 3653 #header #header-inner #quick li a:hover span.normal,
3654 3654 #header #header-inner #quick li ul li.last,
3655 3655 #content div.box div.form div.fields div.field div.textarea table td table td a,
3656 3656 #clone_url,
3657 3657 #clone_url_id
3658 3658 {
3659 3659 border: none;
3660 3660 }
3661 3661
3662 3662 img.icon, .right .merge img {
3663 3663 vertical-align: bottom;
3664 3664 }
3665 3665
3666 3666 #header ul#logged-user, #content div.box div.title ul.links,
3667 3667 #content div.box div.message div.dismiss,
3668 3668 #content div.box div.traffic div.legend ul {
3669 3669 float: right;
3670 3670 margin: 0;
3671 3671 padding: 0;
3672 3672 }
3673 3673
3674 3674 #header #header-inner #home, #header #header-inner #logo,
3675 3675 #content div.box ul.left, #content div.box ol.left,
3676 3676 #content div.box div.pagination-left, div#commit_history,
3677 3677 div#legend_data, div#legend_container, div#legend_choices {
3678 3678 float: left;
3679 3679 }
3680 3680
3681 3681 #header #header-inner #quick li #quick_login,
3682 3682 #header #header-inner #quick li:hover ul ul,
3683 3683 #header #header-inner #quick li:hover ul ul ul,
3684 3684 #header #header-inner #quick li:hover ul ul ul ul,
3685 3685 #content #left #menu ul.closed, #content #left #menu li ul.collapsed, .yui-tt-shadow {
3686 3686 display: none;
3687 3687 }
3688 3688
3689 3689 #header #header-inner #quick li:hover #quick_login,
3690 3690 #header #header-inner #quick li:hover ul, #header #header-inner #quick li li:hover ul, #header #header-inner #quick li li li:hover ul, #header #header-inner #quick li li li li:hover ul, #content #left #menu ul.opened, #content #left #menu li ul.expanded {
3691 3691 display: block;
3692 3692 }
3693 3693
3694 3694 #content div.graph {
3695 3695 padding: 0 10px 10px;
3696 3696 }
3697 3697
3698 3698 #content div.box div.title ul.links li a:hover, #content div.box div.title ul.links li.ui-tabs-selected a {
3699 3699 color: #bfe3ff;
3700 3700 }
3701 3701
3702 3702 #content div.box ol.lower-roman, #content div.box ol.upper-roman, #content div.box ol.lower-alpha, #content div.box ol.upper-alpha, #content div.box ol.decimal {
3703 3703 margin: 10px 24px 10px 44px;
3704 3704 }
3705 3705
3706 3706 #content div.box div.form, #content div.box div.table, #content div.box div.traffic {
3707 3707 clear: both;
3708 3708 overflow: hidden;
3709 3709 margin: 0;
3710 3710 padding: 0 20px 10px;
3711 3711 }
3712 3712
3713 3713 #content div.box div.form div.fields, #login div.form, #login div.form div.fields, #register div.form, #register div.form div.fields {
3714 3714 clear: both;
3715 3715 overflow: hidden;
3716 3716 margin: 0;
3717 3717 padding: 0;
3718 3718 }
3719 3719
3720 3720 #content div.box div.form div.fields div.field div.label span, #login div.form div.fields div.field div.label span, #register div.form div.fields div.field div.label span {
3721 3721 height: 1%;
3722 3722 display: block;
3723 3723 color: #363636;
3724 3724 margin: 0;
3725 3725 padding: 2px 0 0;
3726 3726 }
3727 3727
3728 3728 #content div.box div.form div.fields div.field div.input input.error, #login div.form div.fields div.field div.input input.error, #register div.form div.fields div.field div.input input.error {
3729 3729 background: #FBE3E4;
3730 3730 border-top: 1px solid #e1b2b3;
3731 3731 border-left: 1px solid #e1b2b3;
3732 3732 border-right: 1px solid #FBC2C4;
3733 3733 border-bottom: 1px solid #FBC2C4;
3734 3734 }
3735 3735
3736 3736 #content div.box div.form div.fields div.field div.input input.success, #login div.form div.fields div.field div.input input.success, #register div.form div.fields div.field div.input input.success {
3737 3737 background: #E6EFC2;
3738 3738 border-top: 1px solid #cebb98;
3739 3739 border-left: 1px solid #cebb98;
3740 3740 border-right: 1px solid #c6d880;
3741 3741 border-bottom: 1px solid #c6d880;
3742 3742 }
3743 3743
3744 3744 #content div.box-left div.form div.fields div.field div.textarea, #content div.box-right div.form div.fields div.field div.textarea, #content div.box div.form div.fields div.field div.select select, #content div.box table th.selected input, #content div.box table td.selected input {
3745 3745 margin: 0;
3746 3746 }
3747 3747
3748 3748 #content div.box-left div.form div.fields div.field div.select, #content div.box-left div.form div.fields div.field div.checkboxes, #content div.box-left div.form div.fields div.field div.radios, #content div.box-right div.form div.fields div.field div.select, #content div.box-right div.form div.fields div.field div.checkboxes, #content div.box-right div.form div.fields div.field div.radios {
3749 3749 margin: 0 0 0 0px !important;
3750 3750 padding: 0;
3751 3751 }
3752 3752
3753 3753 #content div.box div.form div.fields div.field div.select, #content div.box div.form div.fields div.field div.checkboxes, #content div.box div.form div.fields div.field div.radios {
3754 3754 margin: 0 0 0 200px;
3755 3755 padding: 0;
3756 3756 }
3757 3757
3758 3758 #content div.box div.form div.fields div.field div.select a:hover, #content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover, #content div.box div.action a:hover {
3759 3759 color: #000;
3760 3760 text-decoration: none;
3761 3761 }
3762 3762
3763 3763 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus, #content div.box div.action a.ui-selectmenu-focus {
3764 3764 border: 1px solid #666;
3765 3765 }
3766 3766
3767 3767 #content div.box div.form div.fields div.field div.checkboxes div.checkbox, #content div.box div.form div.fields div.field div.radios div.radio {
3768 3768 clear: both;
3769 3769 overflow: hidden;
3770 3770 margin: 0;
3771 3771 padding: 8px 0 2px;
3772 3772 }
3773 3773
3774 3774 #content div.box div.form div.fields div.field div.checkboxes div.checkbox input, #content div.box div.form div.fields div.field div.radios div.radio input {
3775 3775 float: left;
3776 3776 margin: 0;
3777 3777 }
3778 3778
3779 3779 #content div.box div.form div.fields div.field div.checkboxes div.checkbox label, #content div.box div.form div.fields div.field div.radios div.radio label {
3780 3780 height: 1%;
3781 3781 display: block;
3782 3782 float: left;
3783 3783 margin: 2px 0 0 4px;
3784 3784 }
3785 3785
3786 3786 div.form div.fields div.field div.button input,
3787 3787 #content div.box div.form div.fields div.buttons input
3788 3788 div.form div.fields div.buttons input,
3789 3789 #content div.box div.action div.button input {
3790 3790 /*color: #000;*/
3791 3791 font-size: 11px;
3792 3792 font-weight: 700;
3793 3793 margin: 0;
3794 3794 }
3795 3795
3796 3796 input.ui-button {
3797 3797 background: #e5e3e3 url("../images/button.png") repeat-x;
3798 3798 border-top: 1px solid #DDD;
3799 3799 border-left: 1px solid #c6c6c6;
3800 3800 border-right: 1px solid #DDD;
3801 3801 border-bottom: 1px solid #c6c6c6;
3802 3802 color: #515151 !important;
3803 3803 outline: none;
3804 3804 margin: 0;
3805 3805 padding: 6px 12px;
3806 3806 -webkit-border-radius: 4px 4px 4px 4px;
3807 3807 -khtml-border-radius: 4px 4px 4px 4px;
3808 3808 -moz-border-radius: 4px 4px 4px 4px;
3809 3809 border-radius: 4px 4px 4px 4px;
3810 3810 box-shadow: 0 1px 0 #ececec;
3811 3811 cursor: pointer;
3812 3812 }
3813 3813
3814 3814 input.ui-button:hover {
3815 3815 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3816 3816 border-top: 1px solid #ccc;
3817 3817 border-left: 1px solid #bebebe;
3818 3818 border-right: 1px solid #b1b1b1;
3819 3819 border-bottom: 1px solid #afafaf;
3820 3820 }
3821 3821
3822 3822 div.form div.fields div.field div.highlight, #content div.box div.form div.fields div.buttons div.highlight {
3823 3823 display: inline;
3824 3824 }
3825 3825
3826 3826 #content div.box div.form div.fields div.buttons, div.form div.fields div.buttons {
3827 3827 margin: 10px 0 0 200px;
3828 3828 padding: 0;
3829 3829 }
3830 3830
3831 3831 #content div.box-left div.form div.fields div.buttons, #content div.box-right div.form div.fields div.buttons, div.box-left div.form div.fields div.buttons, div.box-right div.form div.fields div.buttons {
3832 3832 margin: 10px 0 0;
3833 3833 }
3834 3834
3835 3835 #content div.box table td.user, #content div.box table td.address {
3836 3836 width: 10%;
3837 3837 text-align: center;
3838 3838 }
3839 3839
3840 3840 #content div.box div.action div.button, #login div.form div.fields div.field div.input div.link, #register div.form div.fields div.field div.input div.link {
3841 3841 text-align: right;
3842 3842 margin: 6px 0 0;
3843 3843 padding: 0;
3844 3844 }
3845 3845
3846 3846 #content div.box div.action div.button input.ui-state-hover, #login div.form div.fields div.buttons input.ui-state-hover, #register div.form div.fields div.buttons input.ui-state-hover {
3847 3847 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3848 3848 border-top: 1px solid #ccc;
3849 3849 border-left: 1px solid #bebebe;
3850 3850 border-right: 1px solid #b1b1b1;
3851 3851 border-bottom: 1px solid #afafaf;
3852 3852 color: #515151;
3853 3853 margin: 0;
3854 3854 padding: 6px 12px;
3855 3855 }
3856 3856
3857 3857 #content div.box div.pagination div.results, #content div.box div.pagination-wh div.results {
3858 3858 text-align: left;
3859 3859 float: left;
3860 3860 margin: 0;
3861 3861 padding: 0;
3862 3862 }
3863 3863
3864 3864 #content div.box div.pagination div.results span, #content div.box div.pagination-wh div.results span {
3865 3865 height: 1%;
3866 3866 display: block;
3867 3867 float: left;
3868 3868 background: #ebebeb url("../images/pager.png") repeat-x;
3869 3869 border-top: 1px solid #dedede;
3870 3870 border-left: 1px solid #cfcfcf;
3871 3871 border-right: 1px solid #c4c4c4;
3872 3872 border-bottom: 1px solid #c4c4c4;
3873 3873 color: #4A4A4A;
3874 3874 font-weight: 700;
3875 3875 margin: 0;
3876 3876 padding: 6px 8px;
3877 3877 }
3878 3878
3879 3879 #content div.box div.pagination ul.pager li.disabled, #content div.box div.pagination-wh a.disabled {
3880 3880 color: #B4B4B4;
3881 3881 padding: 6px;
3882 3882 }
3883 3883
3884 3884 #login, #register {
3885 3885 width: 520px;
3886 3886 margin: 10% auto 0;
3887 3887 padding: 0;
3888 3888 }
3889 3889
3890 3890 #login div.color, #register div.color {
3891 3891 clear: both;
3892 3892 overflow: hidden;
3893 3893 background: #FFF;
3894 3894 margin: 10px auto 0;
3895 3895 padding: 3px 3px 3px 0;
3896 3896 }
3897 3897
3898 3898 #login div.color a, #register div.color a {
3899 3899 width: 20px;
3900 3900 height: 20px;
3901 3901 display: block;
3902 3902 float: left;
3903 3903 margin: 0 0 0 3px;
3904 3904 padding: 0;
3905 3905 }
3906 3906
3907 3907 #login div.title h5, #register div.title h5 {
3908 3908 color: #fff;
3909 3909 margin: 10px;
3910 3910 padding: 0;
3911 3911 }
3912 3912
3913 3913 #login div.form div.fields div.field, #register div.form div.fields div.field {
3914 3914 clear: both;
3915 3915 overflow: hidden;
3916 3916 margin: 0;
3917 3917 padding: 0 0 10px;
3918 3918 }
3919 3919
3920 3920 #login div.form div.fields div.field span.error-message, #register div.form div.fields div.field span.error-message {
3921 3921 height: 1%;
3922 3922 display: block;
3923 3923 color: red;
3924 3924 margin: 8px 0 0;
3925 3925 padding: 0;
3926 3926 max-width: 320px;
3927 3927 }
3928 3928
3929 3929 #login div.form div.fields div.field div.label label, #register div.form div.fields div.field div.label label {
3930 3930 color: #000;
3931 3931 font-weight: 700;
3932 3932 }
3933 3933
3934 3934 #login div.form div.fields div.field div.input, #register div.form div.fields div.field div.input {
3935 3935 float: left;
3936 3936 margin: 0;
3937 3937 padding: 0;
3938 3938 }
3939 3939
3940 3940 #login div.form div.fields div.field div.checkbox, #register div.form div.fields div.field div.checkbox {
3941 3941 margin: 0 0 0 184px;
3942 3942 padding: 0;
3943 3943 }
3944 3944
3945 3945 #login div.form div.fields div.field div.checkbox label, #register div.form div.fields div.field div.checkbox label {
3946 3946 color: #565656;
3947 3947 font-weight: 700;
3948 3948 }
3949 3949
3950 3950 #login div.form div.fields div.buttons input, #register div.form div.fields div.buttons input {
3951 3951 color: #000;
3952 3952 font-size: 1em;
3953 3953 font-weight: 700;
3954 3954 margin: 0;
3955 3955 }
3956 3956
3957 3957 #changeset_content .container .wrapper, #graph_content .container .wrapper {
3958 3958 width: 600px;
3959 3959 }
3960 3960
3961 3961 #changeset_content .container .left {
3962 3962 float: left;
3963 3963 width: 75%;
3964 3964 padding-left: 5px;
3965 3965 }
3966 3966
3967 3967 #changeset_content .container .left .date, .ac .match {
3968 3968 font-weight: 700;
3969 3969 padding-top: 5px;
3970 3970 padding-bottom: 5px;
3971 3971 }
3972 3972
3973 3973 div#legend_container table td, div#legend_choices table td {
3974 3974 border: none !important;
3975 3975 height: 20px !important;
3976 3976 padding: 0 !important;
3977 3977 }
3978 3978
3979 3979 .q_filter_box {
3980 3980 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3981 3981 -webkit-border-radius: 4px;
3982 3982 -moz-border-radius: 4px;
3983 3983 border-radius: 4px;
3984 3984 border: 0 none;
3985 3985 color: #AAAAAA;
3986 3986 margin-bottom: -4px;
3987 3987 margin-top: -4px;
3988 3988 padding-left: 3px;
3989 3989 }
3990 3990
3991 3991 #node_filter {
3992 3992 border: 0px solid #545454;
3993 3993 color: #AAAAAA;
3994 3994 padding-left: 3px;
3995 3995 }
3996 3996
3997 3997
3998 3998 .group_members_wrap {
3999 3999 min-height: 85px;
4000 4000 padding-left: 20px;
4001 4001 }
4002 4002
4003 4003 .group_members .group_member {
4004 4004 height: 30px;
4005 4005 padding:0px 0px 0px 0px;
4006 4006 }
4007 4007
4008 4008 .reviewers_member {
4009 4009 height: 15px;
4010 4010 padding:0px 0px 0px 10px;
4011 4011 }
4012 4012
4013 4013 .emails_wrap {
4014 4014 padding: 0px 20px;
4015 4015 }
4016 4016
4017 4017 .emails_wrap .email_entry {
4018 4018 height: 30px;
4019 4019 padding:0px 0px 0px 10px;
4020 4020 }
4021 4021 .emails_wrap .email_entry .email {
4022 4022 float: left
4023 4023 }
4024 4024 .emails_wrap .email_entry .email_action {
4025 4025 float: left
4026 4026 }
4027 4027
4028 4028 .ips_wrap {
4029 4029 padding: 0px 20px;
4030 4030 }
4031 4031
4032 4032 .ips_wrap .ip_entry {
4033 4033 height: 30px;
4034 4034 padding:0px 0px 0px 10px;
4035 4035 }
4036 4036 .ips_wrap .ip_entry .ip {
4037 4037 float: left
4038 4038 }
4039 4039 .ips_wrap .ip_entry .ip_action {
4040 4040 float: left
4041 4041 }
4042 4042
4043 4043
4044 4044 /*README STYLE*/
4045 4045
4046 4046 div.readme {
4047 4047 padding:0px;
4048 4048 }
4049 4049
4050 4050 div.readme h2 {
4051 4051 font-weight: normal;
4052 4052 }
4053 4053
4054 4054 div.readme .readme_box {
4055 4055 background-color: #fafafa;
4056 4056 }
4057 4057
4058 4058 div.readme .readme_box {
4059 4059 clear:both;
4060 4060 overflow:hidden;
4061 4061 margin:0;
4062 4062 padding:0 20px 10px;
4063 4063 }
4064 4064
4065 4065 div.readme .readme_box h1, div.readme .readme_box h2, div.readme .readme_box h3, div.readme .readme_box h4, div.readme .readme_box h5, div.readme .readme_box h6 {
4066 4066 border-bottom: 0 !important;
4067 4067 margin: 0 !important;
4068 4068 padding: 0 !important;
4069 4069 line-height: 1.5em !important;
4070 4070 }
4071 4071
4072 4072
4073 4073 div.readme .readme_box h1:first-child {
4074 4074 padding-top: .25em !important;
4075 4075 }
4076 4076
4077 4077 div.readme .readme_box h2, div.readme .readme_box h3 {
4078 4078 margin: 1em 0 !important;
4079 4079 }
4080 4080
4081 4081 div.readme .readme_box h2 {
4082 4082 margin-top: 1.5em !important;
4083 4083 border-top: 4px solid #e0e0e0 !important;
4084 4084 padding-top: .5em !important;
4085 4085 }
4086 4086
4087 4087 div.readme .readme_box p {
4088 4088 color: black !important;
4089 4089 margin: 1em 0 !important;
4090 4090 line-height: 1.5em !important;
4091 4091 }
4092 4092
4093 4093 div.readme .readme_box ul {
4094 4094 list-style: disc !important;
4095 4095 margin: 1em 0 1em 2em !important;
4096 4096 }
4097 4097
4098 4098 div.readme .readme_box ol {
4099 4099 list-style: decimal;
4100 4100 margin: 1em 0 1em 2em !important;
4101 4101 }
4102 4102
4103 4103 div.readme .readme_box pre, code {
4104 4104 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4105 4105 }
4106 4106
4107 4107 div.readme .readme_box code {
4108 4108 font-size: 12px !important;
4109 4109 background-color: ghostWhite !important;
4110 4110 color: #444 !important;
4111 4111 padding: 0 .2em !important;
4112 4112 border: 1px solid #dedede !important;
4113 4113 }
4114 4114
4115 4115 div.readme .readme_box pre code {
4116 4116 padding: 0 !important;
4117 4117 font-size: 12px !important;
4118 4118 background-color: #eee !important;
4119 4119 border: none !important;
4120 4120 }
4121 4121
4122 4122 div.readme .readme_box pre {
4123 4123 margin: 1em 0;
4124 4124 font-size: 12px;
4125 4125 background-color: #eee;
4126 4126 border: 1px solid #ddd;
4127 4127 padding: 5px;
4128 4128 color: #444;
4129 4129 overflow: auto;
4130 4130 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4131 4131 -webkit-border-radius: 3px;
4132 4132 -moz-border-radius: 3px;
4133 4133 border-radius: 3px;
4134 4134 }
4135 4135
4136 4136 div.readme .readme_box table {
4137 4137 display: table;
4138 4138 border-collapse: separate;
4139 4139 border-spacing: 2px;
4140 4140 border-color: gray;
4141 4141 width: auto !important;
4142 4142 }
4143 4143
4144 4144
4145 4145 /** RST STYLE **/
4146 4146
4147 4147
4148 4148 div.rst-block {
4149 4149 padding:0px;
4150 4150 }
4151 4151
4152 4152 div.rst-block h2 {
4153 4153 font-weight: normal;
4154 4154 }
4155 4155
4156 4156 div.rst-block {
4157 4157 background-color: #fafafa;
4158 4158 }
4159 4159
4160 4160 div.rst-block {
4161 4161 clear:both;
4162 4162 overflow:hidden;
4163 4163 margin:0;
4164 4164 padding:0 20px 10px;
4165 4165 }
4166 4166
4167 4167 div.rst-block h1, div.rst-block h2, div.rst-block h3, div.rst-block h4, div.rst-block h5, div.rst-block h6 {
4168 4168 border-bottom: 0 !important;
4169 4169 margin: 0 !important;
4170 4170 padding: 0 !important;
4171 4171 line-height: 1.5em !important;
4172 4172 }
4173 4173
4174 4174
4175 4175 div.rst-block h1:first-child {
4176 4176 padding-top: .25em !important;
4177 4177 }
4178 4178
4179 4179 div.rst-block h2, div.rst-block h3 {
4180 4180 margin: 1em 0 !important;
4181 4181 }
4182 4182
4183 4183 div.rst-block h2 {
4184 4184 margin-top: 1.5em !important;
4185 4185 border-top: 4px solid #e0e0e0 !important;
4186 4186 padding-top: .5em !important;
4187 4187 }
4188 4188
4189 4189 div.rst-block p {
4190 4190 color: black !important;
4191 4191 margin: 1em 0 !important;
4192 4192 line-height: 1.5em !important;
4193 4193 }
4194 4194
4195 4195 div.rst-block ul {
4196 4196 list-style: disc !important;
4197 4197 margin: 1em 0 1em 2em !important;
4198 4198 }
4199 4199
4200 4200 div.rst-block ol {
4201 4201 list-style: decimal;
4202 4202 margin: 1em 0 1em 2em !important;
4203 4203 }
4204 4204
4205 4205 div.rst-block pre, code {
4206 4206 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4207 4207 }
4208 4208
4209 4209 div.rst-block code {
4210 4210 font-size: 12px !important;
4211 4211 background-color: ghostWhite !important;
4212 4212 color: #444 !important;
4213 4213 padding: 0 .2em !important;
4214 4214 border: 1px solid #dedede !important;
4215 4215 }
4216 4216
4217 4217 div.rst-block pre code {
4218 4218 padding: 0 !important;
4219 4219 font-size: 12px !important;
4220 4220 background-color: #eee !important;
4221 4221 border: none !important;
4222 4222 }
4223 4223
4224 4224 div.rst-block pre {
4225 4225 margin: 1em 0;
4226 4226 font-size: 12px;
4227 4227 background-color: #eee;
4228 4228 border: 1px solid #ddd;
4229 4229 padding: 5px;
4230 4230 color: #444;
4231 4231 overflow: auto;
4232 4232 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4233 4233 -webkit-border-radius: 3px;
4234 4234 -moz-border-radius: 3px;
4235 4235 border-radius: 3px;
4236 4236 }
4237 4237
4238 4238
4239 4239 /** comment main **/
4240 4240 .comments {
4241 4241 padding:10px 20px;
4242 4242 }
4243 4243
4244 4244 .comments .comment {
4245 4245 border: 1px solid #ddd;
4246 4246 margin-top: 10px;
4247 4247 -webkit-border-radius: 4px;
4248 4248 -moz-border-radius: 4px;
4249 4249 border-radius: 4px;
4250 4250 }
4251 4251
4252 4252 .comments .comment .meta {
4253 4253 background: #f8f8f8;
4254 4254 padding: 4px;
4255 4255 border-bottom: 1px solid #ddd;
4256 4256 height: 18px;
4257 4257 }
4258 4258
4259 4259 .comments .comment .meta img {
4260 4260 vertical-align: middle;
4261 4261 }
4262 4262
4263 4263 .comments .comment .meta .user {
4264 4264 font-weight: bold;
4265 4265 float: left;
4266 4266 padding: 4px 2px 2px 2px;
4267 4267 }
4268 4268
4269 4269 .comments .comment .meta .date {
4270 4270 float: left;
4271 4271 padding:4px 4px 0px 4px;
4272 4272 }
4273 4273
4274 4274 .comments .comment .text {
4275 4275 background-color: #FAFAFA;
4276 4276 }
4277 4277 .comment .text div.rst-block p {
4278 4278 margin: 0.5em 0px !important;
4279 4279 }
4280 4280
4281 4281 .comments .comments-number {
4282 4282 padding:0px 0px 10px 0px;
4283 4283 font-weight: bold;
4284 4284 color: #666;
4285 4285 font-size: 16px;
4286 4286 }
4287 4287
4288 4288 /** comment form **/
4289 4289
4290 4290 .status-block {
4291 4291 min-height:80px;
4292 4292 clear:both
4293 4293 }
4294 4294
4295 4295 .comment-form .clearfix {
4296 4296 background: #EEE;
4297 4297 -webkit-border-radius: 4px;
4298 4298 -moz-border-radius: 4px;
4299 4299 border-radius: 4px;
4300 4300 padding: 10px;
4301 4301 }
4302 4302
4303 4303 div.comment-form {
4304 4304 margin-top: 20px;
4305 4305 }
4306 4306
4307 4307 .comment-form strong {
4308 4308 display: block;
4309 4309 margin-bottom: 15px;
4310 4310 }
4311 4311
4312 4312 .comment-form textarea {
4313 4313 width: 100%;
4314 4314 height: 100px;
4315 4315 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4316 4316 }
4317 4317
4318 4318 form.comment-form {
4319 4319 margin-top: 10px;
4320 4320 margin-left: 10px;
4321 4321 }
4322 4322
4323 4323 .comment-form-submit {
4324 4324 margin-top: 5px;
4325 4325 margin-left: 525px;
4326 4326 }
4327 4327
4328 4328 .file-comments {
4329 4329 display: none;
4330 4330 }
4331 4331
4332 4332 .comment-form .comment {
4333 4333 margin-left: 10px;
4334 4334 }
4335 4335
4336 4336 .comment-form .comment-help {
4337 4337 padding: 0px 0px 5px 0px;
4338 4338 color: #666;
4339 4339 }
4340 4340
4341 4341 .comment-form .comment-button {
4342 4342 padding-top:5px;
4343 4343 }
4344 4344
4345 4345 .add-another-button {
4346 4346 margin-left: 10px;
4347 4347 margin-top: 10px;
4348 4348 margin-bottom: 10px;
4349 4349 }
4350 4350
4351 4351 .comment .buttons {
4352 4352 float: right;
4353 4353 padding:2px 2px 0px 0px;
4354 4354 }
4355 4355
4356 4356
4357 4357 .show-inline-comments {
4358 4358 position: relative;
4359 4359 top:1px
4360 4360 }
4361 4361
4362 4362 /** comment inline form **/
4363 4363 .comment-inline-form .overlay {
4364 4364 display: none;
4365 4365 }
4366 4366 .comment-inline-form .overlay.submitting {
4367 4367 display:block;
4368 4368 background: none repeat scroll 0 0 white;
4369 4369 font-size: 16px;
4370 4370 opacity: 0.5;
4371 4371 position: absolute;
4372 4372 text-align: center;
4373 4373 vertical-align: top;
4374 4374
4375 4375 }
4376 4376 .comment-inline-form .overlay.submitting .overlay-text {
4377 4377 width:100%;
4378 4378 margin-top:5%;
4379 4379 }
4380 4380
4381 4381 .comment-inline-form .clearfix {
4382 4382 background: #EEE;
4383 4383 -webkit-border-radius: 4px;
4384 4384 -moz-border-radius: 4px;
4385 4385 border-radius: 4px;
4386 4386 padding: 5px;
4387 4387 }
4388 4388
4389 4389 div.comment-inline-form {
4390 4390 padding:4px 0px 6px 0px;
4391 4391 }
4392 4392
4393 4393
4394 4394 tr.hl-comment {
4395 4395 /*
4396 4396 background-color: #FFFFCC !important;
4397 4397 */
4398 4398 }
4399 4399
4400 4400 /*
4401 4401 tr.hl-comment pre {
4402 4402 border-top: 2px solid #FFEE33;
4403 4403 border-left: 2px solid #FFEE33;
4404 4404 border-right: 2px solid #FFEE33;
4405 4405 }
4406 4406 */
4407 4407
4408 4408 .comment-inline-form strong {
4409 4409 display: block;
4410 4410 margin-bottom: 15px;
4411 4411 }
4412 4412
4413 4413 .comment-inline-form textarea {
4414 4414 width: 100%;
4415 4415 height: 100px;
4416 4416 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4417 4417 }
4418 4418
4419 4419 form.comment-inline-form {
4420 4420 margin-top: 10px;
4421 4421 margin-left: 10px;
4422 4422 }
4423 4423
4424 4424 .comment-inline-form-submit {
4425 4425 margin-top: 5px;
4426 4426 margin-left: 525px;
4427 4427 }
4428 4428
4429 4429 .file-comments {
4430 4430 display: none;
4431 4431 }
4432 4432
4433 4433 .comment-inline-form .comment {
4434 4434 margin-left: 10px;
4435 4435 }
4436 4436
4437 4437 .comment-inline-form .comment-help {
4438 4438 padding: 0px 0px 2px 0px;
4439 4439 color: #666666;
4440 4440 font-size: 10px;
4441 4441 }
4442 4442
4443 4443 .comment-inline-form .comment-button {
4444 4444 padding-top:5px;
4445 4445 }
4446 4446
4447 4447 /** comment inline **/
4448 4448 .inline-comments {
4449 4449 padding:10px 20px;
4450 4450 }
4451 4451
4452 4452 .inline-comments div.rst-block {
4453 4453 clear:both;
4454 4454 overflow:hidden;
4455 4455 margin:0;
4456 4456 padding:0 20px 0px;
4457 4457 }
4458 4458 .inline-comments .comment {
4459 4459 border: 1px solid #ddd;
4460 4460 -webkit-border-radius: 4px;
4461 4461 -moz-border-radius: 4px;
4462 4462 border-radius: 4px;
4463 4463 margin: 3px 3px 5px 5px;
4464 4464 background-color: #FAFAFA;
4465 4465 }
4466 4466 .inline-comments .add-comment {
4467 4467 padding: 2px 4px 8px 5px;
4468 4468 }
4469 4469
4470 4470 .inline-comments .comment-wrapp {
4471 4471 padding:1px;
4472 4472 }
4473 4473 .inline-comments .comment .meta {
4474 4474 background: #f8f8f8;
4475 4475 padding: 4px;
4476 4476 border-bottom: 1px solid #ddd;
4477 4477 height: 20px;
4478 4478 }
4479 4479
4480 4480 .inline-comments .comment .meta img {
4481 4481 vertical-align: middle;
4482 4482 }
4483 4483
4484 4484 .inline-comments .comment .meta .user {
4485 4485 font-weight: bold;
4486 4486 float:left;
4487 4487 padding: 3px;
4488 4488 }
4489 4489
4490 4490 .inline-comments .comment .meta .date {
4491 4491 float:left;
4492 4492 padding: 3px;
4493 4493 }
4494 4494
4495 4495 .inline-comments .comment .text {
4496 4496 background-color: #FAFAFA;
4497 4497 }
4498 4498
4499 4499 .inline-comments .comments-number {
4500 4500 padding:0px 0px 10px 0px;
4501 4501 font-weight: bold;
4502 4502 color: #666;
4503 4503 font-size: 16px;
4504 4504 }
4505 4505 .inline-comments-button .add-comment {
4506 4506 margin:2px 0px 8px 5px !important
4507 4507 }
4508 4508
4509 4509
4510 4510 .notification-paginator {
4511 4511 padding: 0px 0px 4px 16px;
4512 4512 float: left;
4513 4513 }
4514 4514
4515 4515 .menu_link_user {
4516 4516 padding: 10px 8px 8px 8px !important;
4517 4517 }
4518 4518
4519 4519 .menu_link_notifications {
4520 4520 padding: 4px 4px !important;
4521 4521 margin: 7px 4px 0px 0px !important;
4522 4522 text-align: center;
4523 4523 color:#888 !important;
4524 4524 font-size: 10px;
4525 4525 background-color: #DEDEDE !important;
4526 4526 border-radius: 4px !important;
4527 4527 -webkit-border-radius: 4px !important;
4528 4528 -moz-border-radius: 4px !important;
4529 4529 }
4530 4530
4531 4531 .notification-header {
4532 4532 padding-top:6px;
4533 4533 }
4534 4534 .notification-header .desc {
4535 4535 font-size: 16px;
4536 4536 height: 24px;
4537 4537 float: left
4538 4538 }
4539 4539 .notification-list .container.unread {
4540 4540 background: none repeat scroll 0 0 rgba(255, 255, 180, 0.6);
4541 4541 }
4542 4542 .notification-header .gravatar {
4543 4543 background: none repeat scroll 0 0 transparent;
4544 4544 padding: 0px 0px 0px 8px;
4545 4545 }
4546 4546 .notification-list .container .notification-header .desc {
4547 4547 font-weight: bold;
4548 4548 font-size: 17px;
4549 4549 }
4550 4550 .notification-table {
4551 4551 border: 1px solid #ccc;
4552 4552 -webkit-border-radius: 6px 6px 6px 6px;
4553 4553 -moz-border-radius: 6px 6px 6px 6px;
4554 4554 border-radius: 6px 6px 6px 6px;
4555 4555 clear: both;
4556 4556 margin: 0px 20px 0px 20px;
4557 4557 }
4558 4558 .notification-header .delete-notifications {
4559 4559 float: right;
4560 4560 padding-top: 8px;
4561 4561 cursor: pointer;
4562 4562 }
4563 4563 .notification-header .read-notifications {
4564 4564 float: right;
4565 4565 padding-top: 8px;
4566 4566 cursor: pointer;
4567 4567 }
4568 4568 .notification-subject {
4569 4569 clear:both;
4570 4570 border-bottom: 1px solid #eee;
4571 4571 padding:5px 0px 5px 38px;
4572 4572 }
4573 4573
4574 4574 .notification-body {
4575 4575 clear:both;
4576 4576 margin: 34px 2px 2px 8px
4577 4577 }
4578 4578
4579 4579 /****
4580 4580 PULL REQUESTS
4581 4581 *****/
4582 4582 .pullrequests_section_head {
4583 4583 padding:10px 10px 10px 0px;
4584 4584 font-size:16px;
4585 4585 font-weight: bold;
4586 4586 }
4587 4587
4588 4588 /****
4589 4589 PERMS
4590 4590 *****/
4591 4591 #perms .perms_section_head {
4592 4592 padding:10px 10px 10px 0px;
4593 4593 font-size:16px;
4594 4594 font-weight: bold;
4595 4595 }
4596 4596
4597 4597 #perms .perm_tag {
4598 4598 padding: 1px 3px 1px 3px;
4599 4599 font-size: 10px;
4600 4600 font-weight: bold;
4601 4601 text-transform: uppercase;
4602 4602 white-space: nowrap;
4603 4603 -webkit-border-radius: 3px;
4604 4604 -moz-border-radius: 3px;
4605 4605 border-radius: 3px;
4606 4606 }
4607 4607
4608 4608 #perms .perm_tag.admin {
4609 4609 background-color: #B94A48;
4610 4610 color: #ffffff;
4611 4611 }
4612 4612
4613 4613 #perms .perm_tag.write {
4614 4614 background-color: #DB7525;
4615 4615 color: #ffffff;
4616 4616 }
4617 4617
4618 4618 #perms .perm_tag.read {
4619 4619 background-color: #468847;
4620 4620 color: #ffffff;
4621 4621 }
4622 4622
4623 4623 #perms .perm_tag.none {
4624 4624 background-color: #bfbfbf;
4625 4625 color: #ffffff;
4626 4626 }
4627 4627
4628 4628 .perm-gravatar {
4629 4629 vertical-align:middle;
4630 4630 padding:2px;
4631 4631 }
4632 4632 .perm-gravatar-ac {
4633 4633 vertical-align:middle;
4634 4634 padding:2px;
4635 4635 width: 14px;
4636 4636 height: 14px;
4637 4637 }
4638 4638
4639 4639 /*****************************************************************************
4640 4640 DIFFS CSS
4641 4641 ******************************************************************************/
4642 4642
4643 4643 div.diffblock {
4644 4644 overflow: auto;
4645 4645 padding: 0px;
4646 4646 border: 1px solid #ccc;
4647 4647 background: #f8f8f8;
4648 4648 font-size: 100%;
4649 4649 line-height: 100%;
4650 4650 /* new */
4651 4651 line-height: 125%;
4652 4652 -webkit-border-radius: 6px 6px 0px 0px;
4653 4653 -moz-border-radius: 6px 6px 0px 0px;
4654 4654 border-radius: 6px 6px 0px 0px;
4655 4655 }
4656 4656 div.diffblock.margined {
4657 4657 margin: 0px 20px 0px 20px;
4658 4658 }
4659 4659 div.diffblock .code-header {
4660 4660 border-bottom: 1px solid #CCCCCC;
4661 4661 background: #EEEEEE;
4662 4662 padding:10px 0 10px 0;
4663 4663 height: 14px;
4664 4664 }
4665 4665
4666 4666 div.diffblock .code-header.banner {
4667 4667 border-bottom: 1px solid #CCCCCC;
4668 4668 background: #EEEEEE;
4669 4669 height: 14px;
4670 4670 margin: 0px 95px 0px 95px;
4671 4671 padding: 3px 3px 11px 3px;
4672 4672 }
4673 4673
4674 4674 div.diffblock .code-header.cv {
4675 4675 height: 34px;
4676 4676 }
4677 4677 div.diffblock .code-header-title {
4678 4678 padding: 0px 0px 10px 5px !important;
4679 4679 margin: 0 !important;
4680 4680 }
4681 4681 div.diffblock .code-header .hash {
4682 4682 float: left;
4683 4683 padding: 2px 0 0 2px;
4684 4684 }
4685 4685 div.diffblock .code-header .date {
4686 4686 float:left;
4687 4687 text-transform: uppercase;
4688 4688 padding: 2px 0px 0px 2px;
4689 4689 }
4690 4690 div.diffblock .code-header div {
4691 4691 margin-left:4px;
4692 4692 font-weight: bold;
4693 4693 font-size: 14px;
4694 4694 }
4695 4695
4696 4696 div.diffblock .parents {
4697 4697 float: left;
4698 4698 height: 26px;
4699 4699 width:100px;
4700 4700 font-size: 10px;
4701 4701 font-weight: 400;
4702 4702 vertical-align: middle;
4703 4703 padding: 0px 2px 2px 2px;
4704 4704 background-color:#eeeeee;
4705 4705 border-bottom: 1px solid #CCCCCC;
4706 4706 }
4707 4707
4708 4708 div.diffblock .children {
4709 4709 float: right;
4710 4710 height: 26px;
4711 4711 width:100px;
4712 4712 font-size: 10px;
4713 4713 font-weight: 400;
4714 4714 vertical-align: middle;
4715 4715 text-align: right;
4716 4716 padding: 0px 2px 2px 2px;
4717 4717 background-color:#eeeeee;
4718 4718 border-bottom: 1px solid #CCCCCC;
4719 4719 }
4720 4720
4721 4721 div.diffblock .code-body {
4722 4722 background: #FFFFFF;
4723 4723 }
4724 4724 div.diffblock pre.raw {
4725 4725 background: #FFFFFF;
4726 4726 color:#000000;
4727 4727 }
4728 4728 table.code-difftable {
4729 4729 border-collapse: collapse;
4730 4730 width: 99%;
4731 4731 }
4732 4732 table.code-difftable td {
4733 4733 padding: 0 !important;
4734 4734 background: none !important;
4735 4735 border:0 !important;
4736 4736 vertical-align: none !important;
4737 4737 }
4738 4738 table.code-difftable .context {
4739 4739 background:none repeat scroll 0 0 #DDE7EF;
4740 4740 }
4741 4741 table.code-difftable .add {
4742 4742 background:none repeat scroll 0 0 #DDFFDD;
4743 4743 }
4744 4744 table.code-difftable .add ins {
4745 4745 background:none repeat scroll 0 0 #AAFFAA;
4746 4746 text-decoration:none;
4747 4747 }
4748 4748 table.code-difftable .del {
4749 4749 background:none repeat scroll 0 0 #FFDDDD;
4750 4750 }
4751 4751 table.code-difftable .del del {
4752 4752 background:none repeat scroll 0 0 #FFAAAA;
4753 4753 text-decoration:none;
4754 4754 }
4755 4755
4756 4756 /** LINE NUMBERS **/
4757 4757 table.code-difftable .lineno {
4758 4758
4759 4759 padding-left:2px;
4760 4760 padding-right:2px;
4761 4761 text-align:right;
4762 4762 width:32px;
4763 4763 -moz-user-select:none;
4764 4764 -webkit-user-select: none;
4765 4765 border-right: 1px solid #CCC !important;
4766 4766 border-left: 0px solid #CCC !important;
4767 4767 border-top: 0px solid #CCC !important;
4768 4768 border-bottom: none !important;
4769 4769 vertical-align: middle !important;
4770 4770
4771 4771 }
4772 4772 table.code-difftable .lineno.new {
4773 4773 }
4774 4774 table.code-difftable .lineno.old {
4775 4775 }
4776 4776 table.code-difftable .lineno a {
4777 4777 color:#747474 !important;
4778 4778 font:11px "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace !important;
4779 4779 letter-spacing:-1px;
4780 4780 text-align:right;
4781 4781 padding-right: 2px;
4782 4782 cursor: pointer;
4783 4783 display: block;
4784 4784 width: 32px;
4785 4785 }
4786 4786
4787 4787 table.code-difftable .lineno-inline {
4788 4788 background:none repeat scroll 0 0 #FFF !important;
4789 4789 padding-left:2px;
4790 4790 padding-right:2px;
4791 4791 text-align:right;
4792 4792 width:30px;
4793 4793 -moz-user-select:none;
4794 4794 -webkit-user-select: none;
4795 4795 }
4796 4796
4797 4797 /** CODE **/
4798 4798 table.code-difftable .code {
4799 4799 display: block;
4800 4800 width: 100%;
4801 4801 }
4802 4802 table.code-difftable .code td {
4803 4803 margin:0;
4804 4804 padding:0;
4805 4805 }
4806 4806 table.code-difftable .code pre {
4807 4807 margin:0;
4808 4808 padding:0;
4809 4809 height: 17px;
4810 4810 line-height: 17px;
4811 4811 }
4812 4812
4813 4813
4814 4814 .diffblock.margined.comm .line .code:hover {
4815 4815 background-color:#FFFFCC !important;
4816 4816 cursor: pointer !important;
4817 4817 background-image:url("../images/icons/comment_add.png") !important;
4818 4818 background-repeat:no-repeat !important;
4819 4819 background-position: right !important;
4820 4820 background-position: 0% 50% !important;
4821 4821 }
4822 4822 .diffblock.margined.comm .line .code.no-comment:hover {
4823 4823 background-image: none !important;
4824 4824 cursor: auto !important;
4825 4825 background-color: inherit !important;
4826 4826 }
4827 4827
4828 4828 div.comment:target>.comment-wrapp {
4829 4829 border: solid 2px #ee0 !important;
4830 4830 }
@@ -1,2150 +1,2151 b''
1 1 /**
2 2 RhodeCode JS Files
3 3 **/
4 4
5 5 if (typeof console == "undefined" || typeof console.log == "undefined"){
6 6 console = { log: function() {} }
7 7 }
8 8
9 9
10 10 var str_repeat = function(i, m) {
11 11 for (var o = []; m > 0; o[--m] = i);
12 12 return o.join('');
13 13 };
14 14
15 15 /**
16 16 * INJECT .format function into String
17 17 * Usage: "My name is {0} {1}".format("Johny","Bravo")
18 18 * Return "My name is Johny Bravo"
19 19 * Inspired by https://gist.github.com/1049426
20 20 */
21 21 String.prototype.format = function() {
22 22
23 23 function format() {
24 24 var str = this;
25 25 var len = arguments.length+1;
26 26 var safe = undefined;
27 27 var arg = undefined;
28 28
29 29 // For each {0} {1} {n...} replace with the argument in that position. If
30 30 // the argument is an object or an array it will be stringified to JSON.
31 31 for (var i=0; i < len; arg = arguments[i++]) {
32 32 safe = typeof arg === 'object' ? JSON.stringify(arg) : arg;
33 33 str = str.replace(RegExp('\\{'+(i-1)+'\\}', 'g'), safe);
34 34 }
35 35 return str;
36 36 }
37 37
38 38 // Save a reference of what may already exist under the property native.
39 39 // Allows for doing something like: if("".format.native) { /* use native */ }
40 40 format.native = String.prototype.format;
41 41
42 42 // Replace the prototype property
43 43 return format;
44 44
45 45 }();
46 46
47 47 String.prototype.strip = function(char) {
48 48 if(char === undefined){
49 49 char = '\\s';
50 50 }
51 51 return this.replace(new RegExp('^'+char+'+|'+char+'+$','g'), '');
52 52 }
53 53 String.prototype.lstrip = function(char) {
54 54 if(char === undefined){
55 55 char = '\\s';
56 56 }
57 57 return this.replace(new RegExp('^'+char+'+'),'');
58 58 }
59 59 String.prototype.rstrip = function(char) {
60 60 if(char === undefined){
61 61 char = '\\s';
62 62 }
63 63 return this.replace(new RegExp(''+char+'+$'),'');
64 64 }
65 65
66 66
67 67 if(!Array.prototype.indexOf) {
68 68 Array.prototype.indexOf = function(needle) {
69 69 for(var i = 0; i < this.length; i++) {
70 70 if(this[i] === needle) {
71 71 return i;
72 72 }
73 73 }
74 74 return -1;
75 75 };
76 76 }
77 77
78 78 // IE(CRAP) doesn't support previousElementSibling
79 79 var prevElementSibling = function( el ) {
80 80 if( el.previousElementSibling ) {
81 81 return el.previousElementSibling;
82 82 } else {
83 83 while( el = el.previousSibling ) {
84 84 if( el.nodeType === 1 ) return el;
85 85 }
86 86 }
87 87 }
88 88
89 89 var setSelectValue = function(select, val){
90 90 var selection = YUD.get(select);
91 91
92 92 // select element
93 93 for(var i=0;i<selection.options.length;i++){
94 94 if (selection.options[i].innerHTML == val) {
95 95 selection.selectedIndex = i;
96 96 break;
97 97 }
98 98 }
99 99 }
100 100
101 101
102 102 /**
103 103 * SmartColorGenerator
104 104 *
105 105 *usage::
106 106 * var CG = new ColorGenerator();
107 107 * var col = CG.getColor(key); //returns array of RGB
108 108 * 'rgb({0})'.format(col.join(',')
109 109 *
110 110 * @returns {ColorGenerator}
111 111 */
112 112 var ColorGenerator = function(){
113 113 this.GOLDEN_RATIO = 0.618033988749895;
114 114 this.CURRENT_RATIO = 0.22717784590367374 // this can be random
115 115 this.HSV_1 = 0.75;//saturation
116 116 this.HSV_2 = 0.95;
117 117 this.color;
118 118 this.cacheColorMap = {};
119 119 };
120 120
121 121 ColorGenerator.prototype = {
122 122 getColor:function(key){
123 123 if(this.cacheColorMap[key] !== undefined){
124 124 return this.cacheColorMap[key];
125 125 }
126 126 else{
127 127 this.cacheColorMap[key] = this.generateColor();
128 128 return this.cacheColorMap[key];
129 129 }
130 130 },
131 131 _hsvToRgb:function(h,s,v){
132 132 if (s == 0.0)
133 133 return [v, v, v];
134 134 i = parseInt(h * 6.0)
135 135 f = (h * 6.0) - i
136 136 p = v * (1.0 - s)
137 137 q = v * (1.0 - s * f)
138 138 t = v * (1.0 - s * (1.0 - f))
139 139 i = i % 6
140 140 if (i == 0)
141 141 return [v, t, p]
142 142 if (i == 1)
143 143 return [q, v, p]
144 144 if (i == 2)
145 145 return [p, v, t]
146 146 if (i == 3)
147 147 return [p, q, v]
148 148 if (i == 4)
149 149 return [t, p, v]
150 150 if (i == 5)
151 151 return [v, p, q]
152 152 },
153 153 generateColor:function(){
154 154 this.CURRENT_RATIO = this.CURRENT_RATIO+this.GOLDEN_RATIO;
155 155 this.CURRENT_RATIO = this.CURRENT_RATIO %= 1;
156 156 HSV_tuple = [this.CURRENT_RATIO, this.HSV_1, this.HSV_2]
157 157 RGB_tuple = this._hsvToRgb(HSV_tuple[0],HSV_tuple[1],HSV_tuple[2]);
158 158 function toRgb(v){
159 159 return ""+parseInt(v*256)
160 160 }
161 161 return [toRgb(RGB_tuple[0]),toRgb(RGB_tuple[1]),toRgb(RGB_tuple[2])];
162 162
163 163 }
164 164 }
165 165
166 166 /**
167 167 * PyRoutesJS
168 168 *
169 169 * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id>
170 170 */
171 171 var pyroutes = (function() {
172 172 // access global map defined in special file pyroutes
173 173 var matchlist = PROUTES_MAP;
174 174 var sprintf = (function() {
175 175 function get_type(variable) {
176 176 return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
177 177 }
178 178 function str_repeat(input, multiplier) {
179 179 for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
180 180 return output.join('');
181 181 }
182 182
183 183 var str_format = function() {
184 184 if (!str_format.cache.hasOwnProperty(arguments[0])) {
185 185 str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
186 186 }
187 187 return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
188 188 };
189 189
190 190 str_format.format = function(parse_tree, argv) {
191 191 var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
192 192 for (i = 0; i < tree_length; i++) {
193 193 node_type = get_type(parse_tree[i]);
194 194 if (node_type === 'string') {
195 195 output.push(parse_tree[i]);
196 196 }
197 197 else if (node_type === 'array') {
198 198 match = parse_tree[i]; // convenience purposes only
199 199 if (match[2]) { // keyword argument
200 200 arg = argv[cursor];
201 201 for (k = 0; k < match[2].length; k++) {
202 202 if (!arg.hasOwnProperty(match[2][k])) {
203 203 throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
204 204 }
205 205 arg = arg[match[2][k]];
206 206 }
207 207 }
208 208 else if (match[1]) { // positional argument (explicit)
209 209 arg = argv[match[1]];
210 210 }
211 211 else { // positional argument (implicit)
212 212 arg = argv[cursor++];
213 213 }
214 214
215 215 if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
216 216 throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
217 217 }
218 218 switch (match[8]) {
219 219 case 'b': arg = arg.toString(2); break;
220 220 case 'c': arg = String.fromCharCode(arg); break;
221 221 case 'd': arg = parseInt(arg, 10); break;
222 222 case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
223 223 case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
224 224 case 'o': arg = arg.toString(8); break;
225 225 case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
226 226 case 'u': arg = Math.abs(arg); break;
227 227 case 'x': arg = arg.toString(16); break;
228 228 case 'X': arg = arg.toString(16).toUpperCase(); break;
229 229 }
230 230 arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
231 231 pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
232 232 pad_length = match[6] - String(arg).length;
233 233 pad = match[6] ? str_repeat(pad_character, pad_length) : '';
234 234 output.push(match[5] ? arg + pad : pad + arg);
235 235 }
236 236 }
237 237 return output.join('');
238 238 };
239 239
240 240 str_format.cache = {};
241 241
242 242 str_format.parse = function(fmt) {
243 243 var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
244 244 while (_fmt) {
245 245 if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
246 246 parse_tree.push(match[0]);
247 247 }
248 248 else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
249 249 parse_tree.push('%');
250 250 }
251 251 else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
252 252 if (match[2]) {
253 253 arg_names |= 1;
254 254 var field_list = [], replacement_field = match[2], field_match = [];
255 255 if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
256 256 field_list.push(field_match[1]);
257 257 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
258 258 if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
259 259 field_list.push(field_match[1]);
260 260 }
261 261 else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
262 262 field_list.push(field_match[1]);
263 263 }
264 264 else {
265 265 throw('[sprintf] huh?');
266 266 }
267 267 }
268 268 }
269 269 else {
270 270 throw('[sprintf] huh?');
271 271 }
272 272 match[2] = field_list;
273 273 }
274 274 else {
275 275 arg_names |= 2;
276 276 }
277 277 if (arg_names === 3) {
278 278 throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
279 279 }
280 280 parse_tree.push(match);
281 281 }
282 282 else {
283 283 throw('[sprintf] huh?');
284 284 }
285 285 _fmt = _fmt.substring(match[0].length);
286 286 }
287 287 return parse_tree;
288 288 };
289 289
290 290 return str_format;
291 291 })();
292 292
293 293 var vsprintf = function(fmt, argv) {
294 294 argv.unshift(fmt);
295 295 return sprintf.apply(null, argv);
296 296 };
297 297 return {
298 298 'url': function(route_name, params) {
299 299 var result = route_name;
300 300 if (typeof(params) != 'object'){
301 301 params = {};
302 302 }
303 303 if (matchlist.hasOwnProperty(route_name)) {
304 304 var route = matchlist[route_name];
305 305 for(var i=0; i < route[1].length; i++) {
306 306
307 307 if (!params.hasOwnProperty(route[1][i]))
308 308 throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation');
309 309 }
310 310 result = sprintf(route[0], params);
311 311 }
312 312
313 313 return result;
314 314 },
315 315 'register': function(route_name, route_tmpl, req_params) {
316 316 if (typeof(req_params) != 'object') {
317 317 req_params = [];
318 318 }
319 319 //fix escape
320 320 route_tmpl = unescape(route_tmpl);
321 321 keys = [];
322 322 for (o in req_params){
323 323 keys.push(req_params[o])
324 324 }
325 325 matchlist[route_name] = [
326 326 route_tmpl,
327 327 keys
328 328 ]
329 329 },
330 330 '_routes': function(){
331 331 return matchlist;
332 332 }
333 333 }
334 334 })();
335 335
336 336
337 337
338 338 /**
339 339 * GLOBAL YUI Shortcuts
340 340 */
341 341 var YUC = YAHOO.util.Connect;
342 342 var YUD = YAHOO.util.Dom;
343 343 var YUE = YAHOO.util.Event;
344 344 var YUQ = YAHOO.util.Selector.query;
345 345
346 346 // defines if push state is enabled for this browser ?
347 347 var push_state_enabled = Boolean(
348 348 window.history && window.history.pushState && window.history.replaceState
349 349 && !( /* disable for versions of iOS before version 4.3 (8F190) */
350 350 (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent)
351 351 /* disable for the mercury iOS browser, or at least older versions of the webkit engine */
352 352 || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent)
353 353 )
354 354 );
355 355
356 356 var _run_callbacks = function(callbacks){
357 357 if (callbacks !== undefined){
358 358 var _l = callbacks.length;
359 359 for (var i=0;i<_l;i++){
360 360 var func = callbacks[i];
361 361 if(typeof(func)=='function'){
362 362 try{
363 363 func();
364 364 }catch (err){};
365 365 }
366 366 }
367 367 }
368 368 }
369 369
370 370 /**
371 371 * Partial Ajax Implementation
372 372 *
373 373 * @param url: defines url to make partial request
374 374 * @param container: defines id of container to input partial result
375 375 * @param s_call: success callback function that takes o as arg
376 376 * o.tId
377 377 * o.status
378 378 * o.statusText
379 379 * o.getResponseHeader[ ]
380 380 * o.getAllResponseHeaders
381 381 * o.responseText
382 382 * o.responseXML
383 383 * o.argument
384 384 * @param f_call: failure callback
385 385 * @param args arguments
386 386 */
387 387 function ypjax(url,container,s_call,f_call,args){
388 388 var method='GET';
389 389 if(args===undefined){
390 390 args=null;
391 391 }
392 392
393 393 // Set special header for partial ajax == HTTP_X_PARTIAL_XHR
394 394 YUC.initHeader('X-PARTIAL-XHR',true);
395 395
396 396 // wrapper of passed callback
397 397 var s_wrapper = (function(o){
398 398 return function(o){
399 399 YUD.get(container).innerHTML=o.responseText;
400 400 YUD.setStyle(container,'opacity','1.0');
401 401 //execute the given original callback
402 402 if (s_call !== undefined){
403 403 s_call(o);
404 404 }
405 405 }
406 406 })()
407 407 YUD.setStyle(container,'opacity','0.3');
408 408 YUC.asyncRequest(method,url,{
409 409 success:s_wrapper,
410 410 failure:function(o){
411 411 console.log(o);
412 412 YUD.get(container).innerHTML='<span class="error_red">ERROR: {0}</span>'.format(o.status);
413 413 YUD.setStyle(container,'opacity','1.0');
414 414 },
415 415 cache:false
416 416 },args);
417 417
418 418 };
419 419
420 420 var ajaxGET = function(url,success) {
421 421 // Set special header for ajax == HTTP_X_PARTIAL_XHR
422 422 YUC.initHeader('X-PARTIAL-XHR',true);
423 423
424 424 var sUrl = url;
425 425 var callback = {
426 426 success: success,
427 427 failure: function (o) {
428 428 alert("error");
429 429 },
430 430 };
431 431
432 432 var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
433 433 return request;
434 434 };
435 435
436 436
437 437
438 438 var ajaxPOST = function(url,postData,success) {
439 439 // Set special header for ajax == HTTP_X_PARTIAL_XHR
440 440 YUC.initHeader('X-PARTIAL-XHR',true);
441 441
442 442 var toQueryString = function(o) {
443 443 if(typeof o !== 'object') {
444 444 return false;
445 445 }
446 446 var _p, _qs = [];
447 447 for(_p in o) {
448 448 _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
449 449 }
450 450 return _qs.join('&');
451 451 };
452 452
453 453 var sUrl = url;
454 454 var callback = {
455 455 success: success,
456 456 failure: function (o) {
457 457 alert("error");
458 458 },
459 459 };
460 460 var postData = toQueryString(postData);
461 461 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
462 462 return request;
463 463 };
464 464
465 465
466 466 /**
467 467 * tooltip activate
468 468 */
469 469 var tooltip_activate = function(){
470 470 yt = YAHOO.yuitip.main;
471 471 YUE.onDOMReady(yt.init);
472 472 };
473 473
474 474 /**
475 475 * show more
476 476 */
477 477 var show_more_event = function(){
478 478 YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
479 479 var el = e.target;
480 480 YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
481 481 YUD.setStyle(el.parentNode,'display','none');
482 482 });
483 483 };
484 484
485 485 /**
486 486 * show changeset tooltip
487 487 */
488 488 var show_changeset_tooltip = function(){
489 489 YUE.on(YUD.getElementsByClassName('lazy-cs'), 'mouseover', function(e){
490 490 var target = e.currentTarget;
491 491 var rid = YUD.getAttribute(target,'raw_id');
492 492 var repo_name = YUD.getAttribute(target,'repo_name');
493 493 var ttid = 'tt-'+rid;
494 494 var success = function(o){
495 495 var json = JSON.parse(o.responseText);
496 496 YUD.addClass(target,'tooltip')
497 497 YUD.setAttribute(target, 'title',json['message']);
498 498 YAHOO.yuitip.main.show_yuitip(e, target);
499 499 }
500 500 if(rid && !YUD.hasClass(target, 'tooltip')){
501 501 YUD.setAttribute(target,'id',ttid);
502 502 YUD.setAttribute(target, 'title',_TM['loading...']);
503 503 YAHOO.yuitip.main.set_listeners(target);
504 504 YAHOO.yuitip.main.show_yuitip(e, target);
505 505 var url = pyroutes.url('changeset_info', {"repo_name":repo_name, "revision": rid});
506 506 ajaxGET(url, success)
507 507 }
508 508 });
509 509 };
510 510
511 511 var onSuccessFollow = function(target){
512 var f = YUD.get(target.id);
512 var f = YUD.get(target);
513 513 var f_cnt = YUD.get('current_followers_count');
514 514
515 515 if(YUD.hasClass(f, 'follow')){
516 516 f.setAttribute('class','following');
517 517 f.setAttribute('title',_TM['Stop following this repository']);
518 518
519 519 if(f_cnt){
520 520 var cnt = Number(f_cnt.innerHTML)+1;
521 521 f_cnt.innerHTML = cnt;
522 522 }
523 523 }
524 524 else{
525 525 f.setAttribute('class','follow');
526 526 f.setAttribute('title',_TM['Start following this repository']);
527 527 if(f_cnt){
528 528 var cnt = Number(f_cnt.innerHTML)-1;
529 529 f_cnt.innerHTML = cnt;
530 530 }
531 531 }
532 532 }
533 533
534 534 var toggleFollowingUser = function(target,fallows_user_id,token,user_id){
535 535 args = 'follows_user_id='+fallows_user_id;
536 536 args+= '&amp;auth_token='+token;
537 537 if(user_id != undefined){
538 538 args+="&amp;user_id="+user_id;
539 539 }
540 540 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
541 541 success:function(o){
542 542 onSuccessFollow(target);
543 543 }
544 544 },args);
545 545 return false;
546 546 }
547 547
548 548 var toggleFollowingRepo = function(target,fallows_repo_id,token,user_id){
549 549
550 550 args = 'follows_repo_id='+fallows_repo_id;
551 551 args+= '&amp;auth_token='+token;
552 552 if(user_id != undefined){
553 553 args+="&amp;user_id="+user_id;
554 554 }
555 555 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
556 556 success:function(o){
557 557 onSuccessFollow(target);
558 558 }
559 559 },args);
560 560 return false;
561 561 }
562 562
563 563 var showRepoSize = function(target, repo_name, token){
564 564 var args= 'auth_token='+token;
565 565
566 566 if(!YUD.hasClass(target, 'loaded')){
567 567 YUD.get(target).innerHTML = _TM['loading...'];
568 568 var url = pyroutes.url('repo_size', {"repo_name":repo_name});
569 569 YUC.asyncRequest('POST',url,{
570 570 success:function(o){
571 571 YUD.get(target).innerHTML = JSON.parse(o.responseText);
572 572 YUD.addClass(target, 'loaded');
573 573 }
574 574 },args);
575 575 }
576 576 return false;
577 577 }
578 578
579
579 580 /**
580 581 * TOOLTIP IMPL.
581 582 */
582 583 YAHOO.namespace('yuitip');
583 584 YAHOO.yuitip.main = {
584 585
585 586 $: YAHOO.util.Dom.get,
586 587
587 588 bgColor: '#000',
588 589 speed: 0.3,
589 590 opacity: 0.9,
590 591 offset: [15,15],
591 592 useAnim: false,
592 593 maxWidth: 600,
593 594 add_links: false,
594 595 yuitips: [],
595 596
596 597 set_listeners: function(tt){
597 598 YUE.on(tt, 'mouseover', yt.show_yuitip, tt);
598 599 YUE.on(tt, 'mousemove', yt.move_yuitip, tt);
599 600 YUE.on(tt, 'mouseout', yt.close_yuitip, tt);
600 601 },
601 602
602 603 init: function(){
603 604 yt.tipBox = yt.$('tip-box');
604 605 if(!yt.tipBox){
605 606 yt.tipBox = document.createElement('div');
606 607 document.body.appendChild(yt.tipBox);
607 608 yt.tipBox.id = 'tip-box';
608 609 }
609 610
610 611 YUD.setStyle(yt.tipBox, 'display', 'none');
611 612 YUD.setStyle(yt.tipBox, 'position', 'absolute');
612 613 if(yt.maxWidth !== null){
613 614 YUD.setStyle(yt.tipBox, 'max-width', yt.maxWidth+'px');
614 615 }
615 616
616 617 var yuitips = YUD.getElementsByClassName('tooltip');
617 618
618 619 if(yt.add_links === true){
619 620 var links = document.getElementsByTagName('a');
620 621 var linkLen = links.length;
621 622 for(i=0;i<linkLen;i++){
622 623 yuitips.push(links[i]);
623 624 }
624 625 }
625 626
626 627 var yuiLen = yuitips.length;
627 628
628 629 for(i=0;i<yuiLen;i++){
629 630 yt.set_listeners(yuitips[i]);
630 631 }
631 632 },
632 633
633 634 show_yuitip: function(e, el){
634 635 YUE.stopEvent(e);
635 636 if(el.tagName.toLowerCase() === 'img'){
636 637 yt.tipText = el.alt ? el.alt : '';
637 638 } else {
638 639 yt.tipText = el.title ? el.title : '';
639 640 }
640 641
641 642 if(yt.tipText !== ''){
642 643 // save org title
643 644 YUD.setAttribute(el, 'tt_title', yt.tipText);
644 645 // reset title to not show org tooltips
645 646 YUD.setAttribute(el, 'title', '');
646 647
647 648 yt.tipBox.innerHTML = yt.tipText;
648 649 YUD.setStyle(yt.tipBox, 'display', 'block');
649 650 if(yt.useAnim === true){
650 651 YUD.setStyle(yt.tipBox, 'opacity', '0');
651 652 var newAnim = new YAHOO.util.Anim(yt.tipBox,
652 653 {
653 654 opacity: { to: yt.opacity }
654 655 }, yt.speed, YAHOO.util.Easing.easeOut
655 656 );
656 657 newAnim.animate();
657 658 }
658 659 }
659 660 },
660 661
661 662 move_yuitip: function(e, el){
662 663 YUE.stopEvent(e);
663 664 var movePos = YUE.getXY(e);
664 665 YUD.setStyle(yt.tipBox, 'top', (movePos[1] + yt.offset[1]) + 'px');
665 666 YUD.setStyle(yt.tipBox, 'left', (movePos[0] + yt.offset[0]) + 'px');
666 667 },
667 668
668 669 close_yuitip: function(e, el){
669 670 YUE.stopEvent(e);
670 671
671 672 if(yt.useAnim === true){
672 673 var newAnim = new YAHOO.util.Anim(yt.tipBox,
673 674 {
674 675 opacity: { to: 0 }
675 676 }, yt.speed, YAHOO.util.Easing.easeOut
676 677 );
677 678 newAnim.animate();
678 679 } else {
679 680 YUD.setStyle(yt.tipBox, 'display', 'none');
680 681 }
681 682 YUD.setAttribute(el,'title', YUD.getAttribute(el, 'tt_title'));
682 683 }
683 684 }
684 685
685 686 /**
686 687 * Quick filter widget
687 688 *
688 689 * @param target: filter input target
689 690 * @param nodes: list of nodes in html we want to filter.
690 691 * @param display_element function that takes current node from nodes and
691 692 * does hide or show based on the node
692 693 *
693 694 */
694 695 var q_filter = function(target,nodes,display_element){
695 696
696 697 var nodes = nodes;
697 698 var q_filter_field = YUD.get(target);
698 699 var F = YAHOO.namespace(target);
699 700
700 701 YUE.on(q_filter_field,'click',function(){
701 702 q_filter_field.value = '';
702 703 });
703 704
704 705 YUE.on(q_filter_field,'keyup',function(e){
705 706 clearTimeout(F.filterTimeout);
706 707 F.filterTimeout = setTimeout(F.updateFilter,600);
707 708 });
708 709
709 710 F.filterTimeout = null;
710 711
711 712 var show_node = function(node){
712 713 YUD.setStyle(node,'display','')
713 714 }
714 715 var hide_node = function(node){
715 716 YUD.setStyle(node,'display','none');
716 717 }
717 718
718 719 F.updateFilter = function() {
719 720 // Reset timeout
720 721 F.filterTimeout = null;
721 722
722 723 var obsolete = [];
723 724
724 725 var req = q_filter_field.value.toLowerCase();
725 726
726 727 var l = nodes.length;
727 728 var i;
728 729 var showing = 0;
729 730
730 731 for (i=0;i<l;i++ ){
731 732 var n = nodes[i];
732 733 var target_element = display_element(n)
733 734 if(req && n.innerHTML.toLowerCase().indexOf(req) == -1){
734 735 hide_node(target_element);
735 736 }
736 737 else{
737 738 show_node(target_element);
738 739 showing+=1;
739 740 }
740 741 }
741 742
742 743 // if repo_count is set update the number
743 744 var cnt = YUD.get('repo_count');
744 745 if(cnt){
745 746 YUD.get('repo_count').innerHTML = showing;
746 747 }
747 748
748 749 }
749 750 };
750 751
751 752 var tableTr = function(cls, body){
752 753 var _el = document.createElement('div');
753 754 var cont = new YAHOO.util.Element(body);
754 755 var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
755 756 var id = 'comment-tr-{0}'.format(comment_id);
756 757 var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
757 758 '<td class="lineno-inline new-inline"></td>'+
758 759 '<td class="lineno-inline old-inline"></td>'+
759 760 '<td>{2}</td>'+
760 761 '</tr></tbody></table>').format(id, cls, body);
761 762 _el.innerHTML = _html;
762 763 return _el.children[0].children[0].children[0];
763 764 };
764 765
765 766 /** comments **/
766 767 var removeInlineForm = function(form) {
767 768 form.parentNode.removeChild(form);
768 769 };
769 770
770 771 var createInlineForm = function(parent_tr, f_path, line) {
771 772 var tmpl = YUD.get('comment-inline-form-template').innerHTML;
772 773 tmpl = tmpl.format(f_path, line);
773 774 var form = tableTr('comment-form-inline',tmpl)
774 775
775 776 // create event for hide button
776 777 form = new YAHOO.util.Element(form);
777 778 var form_hide_button = new YAHOO.util.Element(YUD.getElementsByClassName('hide-inline-form',null,form)[0]);
778 779 form_hide_button.on('click', function(e) {
779 780 var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
780 781 if(YUD.hasClass(newtr.nextElementSibling,'inline-comments-button')){
781 782 YUD.setStyle(newtr.nextElementSibling,'display','');
782 783 }
783 784 removeInlineForm(newtr);
784 785 YUD.removeClass(parent_tr, 'form-open');
785 786 YUD.removeClass(parent_tr, 'hl-comment');
786 787
787 788 });
788 789
789 790 return form
790 791 };
791 792
792 793 /**
793 794 * Inject inline comment for on given TR this tr should be always an .line
794 795 * tr containing the line. Code will detect comment, and always put the comment
795 796 * block at the very bottom
796 797 */
797 798 var injectInlineForm = function(tr){
798 799 if(!YUD.hasClass(tr, 'line')){
799 800 return
800 801 }
801 802 var submit_url = AJAX_COMMENT_URL;
802 803 var _td = YUD.getElementsByClassName('code',null,tr)[0];
803 804 if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(_td,'no-comment')){
804 805 return
805 806 }
806 807 YUD.addClass(tr,'form-open');
807 808 YUD.addClass(tr,'hl-comment');
808 809 var node = YUD.getElementsByClassName('full_f_path',null,tr.parentNode.parentNode.parentNode)[0];
809 810 var f_path = YUD.getAttribute(node,'path');
810 811 var lineno = getLineNo(tr);
811 812 var form = createInlineForm(tr, f_path, lineno, submit_url);
812 813
813 814 var parent = tr;
814 815 while (1){
815 816 var n = parent.nextElementSibling;
816 817 // next element are comments !
817 818 if(YUD.hasClass(n,'inline-comments')){
818 819 parent = n;
819 820 }
820 821 else{
821 822 break;
822 823 }
823 824 }
824 825 YUD.insertAfter(form,parent);
825 826 var f = YUD.get(form);
826 827 var overlay = YUD.getElementsByClassName('overlay',null,f)[0];
827 828 var _form = YUD.getElementsByClassName('inline-form',null,f)[0];
828 829
829 830 YUE.on(YUD.get(_form), 'submit',function(e){
830 831 YUE.preventDefault(e);
831 832
832 833 //ajax submit
833 834 var text = YUD.get('text_'+lineno).value;
834 835 var postData = {
835 836 'text':text,
836 837 'f_path':f_path,
837 838 'line':lineno
838 839 };
839 840
840 841 if(lineno === undefined){
841 842 alert('missing line !');
842 843 return
843 844 }
844 845 if(f_path === undefined){
845 846 alert('missing file path !');
846 847 return
847 848 }
848 849
849 850 if(text == ""){
850 851 return
851 852 }
852 853
853 854 var success = function(o){
854 855 YUD.removeClass(tr, 'form-open');
855 856 removeInlineForm(f);
856 857 var json_data = JSON.parse(o.responseText);
857 858 renderInlineComment(json_data);
858 859 };
859 860
860 861 if (YUD.hasClass(overlay,'overlay')){
861 862 var w = _form.offsetWidth;
862 863 var h = _form.offsetHeight;
863 864 YUD.setStyle(overlay,'width',w+'px');
864 865 YUD.setStyle(overlay,'height',h+'px');
865 866 }
866 867 YUD.addClass(overlay, 'submitting');
867 868
868 869 ajaxPOST(submit_url, postData, success);
869 870 });
870 871
871 872 setTimeout(function(){
872 873 // callbacks
873 874 tooltip_activate();
874 875 MentionsAutoComplete('text_'+lineno, 'mentions_container_'+lineno,
875 876 _USERS_AC_DATA, _GROUPS_AC_DATA);
876 877 var _e = YUD.get('text_'+lineno);
877 878 if(_e){
878 879 _e.focus();
879 880 }
880 881 },10)
881 882 };
882 883
883 884 var deleteComment = function(comment_id){
884 885 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__',comment_id);
885 886 var postData = {'_method':'delete'};
886 887 var success = function(o){
887 888 var n = YUD.get('comment-tr-'+comment_id);
888 889 var root = prevElementSibling(prevElementSibling(n));
889 890 n.parentNode.removeChild(n);
890 891
891 892 // scann nodes, and attach add button to last one
892 893 placeAddButton(root);
893 894 }
894 895 ajaxPOST(url,postData,success);
895 896 }
896 897
897 898 var createInlineAddButton = function(tr){
898 899
899 900 var label = TRANSLATION_MAP['add another comment'];
900 901
901 902 var html_el = document.createElement('div');
902 903 YUD.addClass(html_el, 'add-comment');
903 904 html_el.innerHTML = '<span class="ui-btn">{0}</span>'.format(label);
904 905
905 906 var add = new YAHOO.util.Element(html_el);
906 907 add.on('click', function(e) {
907 908 injectInlineForm(tr);
908 909 });
909 910 return add;
910 911 };
911 912
912 913 var getLineNo = function(tr) {
913 914 var line;
914 915 var o = tr.children[0].id.split('_');
915 916 var n = tr.children[1].id.split('_');
916 917
917 918 if (n.length >= 2) {
918 919 line = n[n.length-1];
919 920 } else if (o.length >= 2) {
920 921 line = o[o.length-1];
921 922 }
922 923
923 924 return line
924 925 };
925 926
926 927 var placeAddButton = function(target_tr){
927 928 if(!target_tr){
928 929 return
929 930 }
930 931 var last_node = target_tr;
931 932 //scann
932 933 while (1){
933 934 var n = last_node.nextElementSibling;
934 935 // next element are comments !
935 936 if(YUD.hasClass(n,'inline-comments')){
936 937 last_node = n;
937 938 //also remove the comment button from previous
938 939 var comment_add_buttons = YUD.getElementsByClassName('add-comment',null,last_node);
939 940 for(var i=0;i<comment_add_buttons.length;i++){
940 941 var b = comment_add_buttons[i];
941 942 b.parentNode.removeChild(b);
942 943 }
943 944 }
944 945 else{
945 946 break;
946 947 }
947 948 }
948 949
949 950 var add = createInlineAddButton(target_tr);
950 951 // get the comment div
951 952 var comment_block = YUD.getElementsByClassName('comment',null,last_node)[0];
952 953 // attach add button
953 954 YUD.insertAfter(add,comment_block);
954 955 }
955 956
956 957 /**
957 958 * Places the inline comment into the changeset block in proper line position
958 959 */
959 960 var placeInline = function(target_container,lineno,html){
960 961 var lineid = "{0}_{1}".format(target_container,lineno);
961 962 var target_line = YUD.get(lineid);
962 963 var comment = new YAHOO.util.Element(tableTr('inline-comments',html))
963 964
964 965 // check if there are comments already !
965 966 var parent = target_line.parentNode;
966 967 var root_parent = parent;
967 968 while (1){
968 969 var n = parent.nextElementSibling;
969 970 // next element are comments !
970 971 if(YUD.hasClass(n,'inline-comments')){
971 972 parent = n;
972 973 }
973 974 else{
974 975 break;
975 976 }
976 977 }
977 978 // put in the comment at the bottom
978 979 YUD.insertAfter(comment,parent);
979 980
980 981 // scann nodes, and attach add button to last one
981 982 placeAddButton(root_parent);
982 983
983 984 return target_line;
984 985 }
985 986
986 987 /**
987 988 * make a single inline comment and place it inside
988 989 */
989 990 var renderInlineComment = function(json_data){
990 991 try{
991 992 var html = json_data['rendered_text'];
992 993 var lineno = json_data['line_no'];
993 994 var target_id = json_data['target_id'];
994 995 placeInline(target_id, lineno, html);
995 996
996 997 }catch(e){
997 998 console.log(e);
998 999 }
999 1000 }
1000 1001
1001 1002 /**
1002 1003 * Iterates over all the inlines, and places them inside proper blocks of data
1003 1004 */
1004 1005 var renderInlineComments = function(file_comments){
1005 1006 for (f in file_comments){
1006 1007 // holding all comments for a FILE
1007 1008 var box = file_comments[f];
1008 1009
1009 1010 var target_id = YUD.getAttribute(box,'target_id');
1010 1011 // actually comments with line numbers
1011 1012 var comments = box.children;
1012 1013 for(var i=0; i<comments.length; i++){
1013 1014 var data = {
1014 1015 'rendered_text': comments[i].outerHTML,
1015 1016 'line_no': YUD.getAttribute(comments[i],'line'),
1016 1017 'target_id': target_id
1017 1018 }
1018 1019 renderInlineComment(data);
1019 1020 }
1020 1021 }
1021 1022 }
1022 1023
1023 1024 var fileBrowserListeners = function(current_url, node_list_url, url_base){
1024 1025 var current_url_branch = +"?branch=__BRANCH__";
1025 1026
1026 1027 YUE.on('stay_at_branch','click',function(e){
1027 1028 if(e.target.checked){
1028 1029 var uri = current_url_branch;
1029 1030 uri = uri.replace('__BRANCH__',e.target.value);
1030 1031 window.location = uri;
1031 1032 }
1032 1033 else{
1033 1034 window.location = current_url;
1034 1035 }
1035 1036 })
1036 1037
1037 1038 var n_filter = YUD.get('node_filter');
1038 1039 var F = YAHOO.namespace('node_filter');
1039 1040
1040 1041 F.filterTimeout = null;
1041 1042 var nodes = null;
1042 1043
1043 1044 F.initFilter = function(){
1044 1045 YUD.setStyle('node_filter_box_loading','display','');
1045 1046 YUD.setStyle('search_activate_id','display','none');
1046 1047 YUD.setStyle('add_node_id','display','none');
1047 1048 YUC.initHeader('X-PARTIAL-XHR',true);
1048 1049 YUC.asyncRequest('GET', node_list_url, {
1049 1050 success:function(o){
1050 1051 nodes = JSON.parse(o.responseText).nodes;
1051 1052 YUD.setStyle('node_filter_box_loading','display','none');
1052 1053 YUD.setStyle('node_filter_box','display','');
1053 1054 n_filter.focus();
1054 1055 if(YUD.hasClass(n_filter,'init')){
1055 1056 n_filter.value = '';
1056 1057 YUD.removeClass(n_filter,'init');
1057 1058 }
1058 1059 },
1059 1060 failure:function(o){
1060 1061 console.log('failed to load');
1061 1062 }
1062 1063 },null);
1063 1064 }
1064 1065
1065 1066 F.updateFilter = function(e) {
1066 1067
1067 1068 return function(){
1068 1069 // Reset timeout
1069 1070 F.filterTimeout = null;
1070 1071 var query = e.target.value.toLowerCase();
1071 1072 var match = [];
1072 1073 var matches = 0;
1073 1074 var matches_max = 20;
1074 1075 if (query != ""){
1075 1076 for(var i=0;i<nodes.length;i++){
1076 1077
1077 1078 var pos = nodes[i].name.toLowerCase().indexOf(query)
1078 1079 if(query && pos != -1){
1079 1080
1080 1081 matches++
1081 1082 //show only certain amount to not kill browser
1082 1083 if (matches > matches_max){
1083 1084 break;
1084 1085 }
1085 1086
1086 1087 var n = nodes[i].name;
1087 1088 var t = nodes[i].type;
1088 1089 var n_hl = n.substring(0,pos)
1089 1090 +"<b>{0}</b>".format(n.substring(pos,pos+query.length))
1090 1091 +n.substring(pos+query.length)
1091 1092 var new_url = url_base.replace('__FPATH__',n);
1092 1093 match.push('<tr><td><a class="browser-{0}" href="{1}">{2}</a></td><td colspan="5"></td></tr>'.format(t,new_url,n_hl));
1093 1094 }
1094 1095 if(match.length >= matches_max){
1095 1096 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['search truncated']));
1096 1097 }
1097 1098 }
1098 1099 }
1099 1100 if(query != ""){
1100 1101 YUD.setStyle('tbody','display','none');
1101 1102 YUD.setStyle('tbody_filtered','display','');
1102 1103
1103 1104 if (match.length==0){
1104 1105 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['no matching files']));
1105 1106 }
1106 1107
1107 1108 YUD.get('tbody_filtered').innerHTML = match.join("");
1108 1109 }
1109 1110 else{
1110 1111 YUD.setStyle('tbody','display','');
1111 1112 YUD.setStyle('tbody_filtered','display','none');
1112 1113 }
1113 1114
1114 1115 }
1115 1116 };
1116 1117
1117 1118 YUE.on(YUD.get('filter_activate'),'click',function(){
1118 1119 F.initFilter();
1119 1120 })
1120 1121 YUE.on(n_filter,'click',function(){
1121 1122 if(YUD.hasClass(n_filter,'init')){
1122 1123 n_filter.value = '';
1123 1124 YUD.removeClass(n_filter,'init');
1124 1125 }
1125 1126 });
1126 1127 YUE.on(n_filter,'keyup',function(e){
1127 1128 clearTimeout(F.filterTimeout);
1128 1129 F.filterTimeout = setTimeout(F.updateFilter(e),600);
1129 1130 });
1130 1131 };
1131 1132
1132 1133
1133 1134 var initCodeMirror = function(textAreadId,resetUrl){
1134 1135 var myCodeMirror = CodeMirror.fromTextArea(YUD.get(textAreadId),{
1135 1136 mode: "null",
1136 1137 lineNumbers:true
1137 1138 });
1138 1139 YUE.on('reset','click',function(e){
1139 1140 window.location=resetUrl
1140 1141 });
1141 1142
1142 1143 YUE.on('file_enable','click',function(){
1143 1144 YUD.setStyle('editor_container','display','');
1144 1145 YUD.setStyle('upload_file_container','display','none');
1145 1146 YUD.setStyle('filename_container','display','');
1146 1147 });
1147 1148
1148 1149 YUE.on('upload_file_enable','click',function(){
1149 1150 YUD.setStyle('editor_container','display','none');
1150 1151 YUD.setStyle('upload_file_container','display','');
1151 1152 YUD.setStyle('filename_container','display','none');
1152 1153 });
1153 1154 };
1154 1155
1155 1156
1156 1157
1157 1158 var getIdentNode = function(n){
1158 1159 //iterate thru nodes untill matched interesting node !
1159 1160
1160 1161 if (typeof n == 'undefined'){
1161 1162 return -1
1162 1163 }
1163 1164
1164 1165 if(typeof n.id != "undefined" && n.id.match('L[0-9]+')){
1165 1166 return n
1166 1167 }
1167 1168 else{
1168 1169 return getIdentNode(n.parentNode);
1169 1170 }
1170 1171 };
1171 1172
1172 1173 var getSelectionLink = function(e) {
1173 1174
1174 1175 //get selection from start/to nodes
1175 1176 if (typeof window.getSelection != "undefined") {
1176 1177 s = window.getSelection();
1177 1178
1178 1179 from = getIdentNode(s.anchorNode);
1179 1180 till = getIdentNode(s.focusNode);
1180 1181
1181 1182 f_int = parseInt(from.id.replace('L',''));
1182 1183 t_int = parseInt(till.id.replace('L',''));
1183 1184
1184 1185 if (f_int > t_int){
1185 1186 //highlight from bottom
1186 1187 offset = -35;
1187 1188 ranges = [t_int,f_int];
1188 1189
1189 1190 }
1190 1191 else{
1191 1192 //highligth from top
1192 1193 offset = 35;
1193 1194 ranges = [f_int,t_int];
1194 1195 }
1195 1196 // if we select more than 2 lines
1196 1197 if (ranges[0] != ranges[1]){
1197 1198 if(YUD.get('linktt') == null){
1198 1199 hl_div = document.createElement('div');
1199 1200 hl_div.id = 'linktt';
1200 1201 }
1201 1202 hl_div.innerHTML = '';
1202 1203
1203 1204 anchor = '#L'+ranges[0]+'-'+ranges[1];
1204 1205 var link = document.createElement('a');
1205 1206 link.href = location.href.substring(0,location.href.indexOf('#'))+anchor;
1206 1207 link.innerHTML = _TM['Selection link'];
1207 1208 hl_div.appendChild(link);
1208 1209 YUD.get('body').appendChild(hl_div);
1209 1210
1210 1211 xy = YUD.getXY(till.id);
1211 1212
1212 1213 YUD.addClass('linktt', 'hl-tip-box');
1213 1214 YUD.setStyle('linktt','top',xy[1]+offset+'px');
1214 1215 YUD.setStyle('linktt','left',xy[0]+'px');
1215 1216 YUD.setStyle('linktt','visibility','visible');
1216 1217
1217 1218 }
1218 1219 else{
1219 1220 YUD.setStyle('linktt','visibility','hidden');
1220 1221 }
1221 1222 }
1222 1223 };
1223 1224
1224 1225 var deleteNotification = function(url, notification_id,callbacks){
1225 1226 var callback = {
1226 1227 success:function(o){
1227 1228 var obj = YUD.get(String("notification_"+notification_id));
1228 1229 if(obj.parentNode !== undefined){
1229 1230 obj.parentNode.removeChild(obj);
1230 1231 }
1231 1232 _run_callbacks(callbacks);
1232 1233 },
1233 1234 failure:function(o){
1234 1235 alert("error");
1235 1236 },
1236 1237 };
1237 1238 var postData = '_method=delete';
1238 1239 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1239 1240 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1240 1241 callback, postData);
1241 1242 };
1242 1243
1243 1244 var readNotification = function(url, notification_id,callbacks){
1244 1245 var callback = {
1245 1246 success:function(o){
1246 1247 var obj = YUD.get(String("notification_"+notification_id));
1247 1248 YUD.removeClass(obj, 'unread');
1248 1249 var r_button = YUD.getElementsByClassName('read-notification',null,obj.children[0])[0];
1249 1250
1250 1251 if(r_button.parentNode !== undefined){
1251 1252 r_button.parentNode.removeChild(r_button);
1252 1253 }
1253 1254 _run_callbacks(callbacks);
1254 1255 },
1255 1256 failure:function(o){
1256 1257 alert("error");
1257 1258 },
1258 1259 };
1259 1260 var postData = '_method=put';
1260 1261 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1261 1262 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1262 1263 callback, postData);
1263 1264 };
1264 1265
1265 1266 /** MEMBERS AUTOCOMPLETE WIDGET **/
1266 1267
1267 1268 var MembersAutoComplete = function (divid, cont, users_list, groups_list) {
1268 1269 var myUsers = users_list;
1269 1270 var myGroups = groups_list;
1270 1271
1271 1272 // Define a custom search function for the DataSource of users
1272 1273 var matchUsers = function (sQuery) {
1273 1274 // Case insensitive matching
1274 1275 var query = sQuery.toLowerCase();
1275 1276 var i = 0;
1276 1277 var l = myUsers.length;
1277 1278 var matches = [];
1278 1279
1279 1280 // Match against each name of each contact
1280 1281 for (; i < l; i++) {
1281 1282 contact = myUsers[i];
1282 1283 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1283 1284 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1284 1285 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1285 1286 matches[matches.length] = contact;
1286 1287 }
1287 1288 }
1288 1289 return matches;
1289 1290 };
1290 1291
1291 1292 // Define a custom search function for the DataSource of usersGroups
1292 1293 var matchGroups = function (sQuery) {
1293 1294 // Case insensitive matching
1294 1295 var query = sQuery.toLowerCase();
1295 1296 var i = 0;
1296 1297 var l = myGroups.length;
1297 1298 var matches = [];
1298 1299
1299 1300 // Match against each name of each contact
1300 1301 for (; i < l; i++) {
1301 1302 matched_group = myGroups[i];
1302 1303 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1303 1304 matches[matches.length] = matched_group;
1304 1305 }
1305 1306 }
1306 1307 return matches;
1307 1308 };
1308 1309
1309 1310 //match all
1310 1311 var matchAll = function (sQuery) {
1311 1312 u = matchUsers(sQuery);
1312 1313 g = matchGroups(sQuery);
1313 1314 return u.concat(g);
1314 1315 };
1315 1316
1316 1317 // DataScheme for members
1317 1318 var memberDS = new YAHOO.util.FunctionDataSource(matchAll);
1318 1319 memberDS.responseSchema = {
1319 1320 fields: ["id", "fname", "lname", "nname", "grname", "grmembers", "gravatar_lnk"]
1320 1321 };
1321 1322
1322 1323 // DataScheme for owner
1323 1324 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1324 1325 ownerDS.responseSchema = {
1325 1326 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1326 1327 };
1327 1328
1328 1329 // Instantiate AutoComplete for perms
1329 1330 var membersAC = new YAHOO.widget.AutoComplete(divid, cont, memberDS);
1330 1331 membersAC.useShadow = false;
1331 1332 membersAC.resultTypeList = false;
1332 1333 membersAC.animVert = false;
1333 1334 membersAC.animHoriz = false;
1334 1335 membersAC.animSpeed = 0.1;
1335 1336
1336 1337 // Instantiate AutoComplete for owner
1337 1338 var ownerAC = new YAHOO.widget.AutoComplete("user", "owner_container", ownerDS);
1338 1339 ownerAC.useShadow = false;
1339 1340 ownerAC.resultTypeList = false;
1340 1341 ownerAC.animVert = false;
1341 1342 ownerAC.animHoriz = false;
1342 1343 ownerAC.animSpeed = 0.1;
1343 1344
1344 1345 // Helper highlight function for the formatter
1345 1346 var highlightMatch = function (full, snippet, matchindex) {
1346 1347 return full.substring(0, matchindex)
1347 1348 + "<span class='match'>"
1348 1349 + full.substr(matchindex, snippet.length)
1349 1350 + "</span>" + full.substring(matchindex + snippet.length);
1350 1351 };
1351 1352
1352 1353 // Custom formatter to highlight the matching letters
1353 1354 var custom_formatter = function (oResultData, sQuery, sResultMatch) {
1354 1355 var query = sQuery.toLowerCase();
1355 1356 var _gravatar = function(res, em, group){
1356 1357 if (group !== undefined){
1357 1358 em = '/images/icons/group.png'
1358 1359 }
1359 1360 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1360 1361 return tmpl.format(em,res)
1361 1362 }
1362 1363 // group
1363 1364 if (oResultData.grname != undefined) {
1364 1365 var grname = oResultData.grname;
1365 1366 var grmembers = oResultData.grmembers;
1366 1367 var grnameMatchIndex = grname.toLowerCase().indexOf(query);
1367 1368 var grprefix = "{0}: ".format(_TM['Group']);
1368 1369 var grsuffix = " (" + grmembers + " )";
1369 1370 var grsuffix = " ({0} {1})".format(grmembers, _TM['members']);
1370 1371
1371 1372 if (grnameMatchIndex > -1) {
1372 1373 return _gravatar(grprefix + highlightMatch(grname, query, grnameMatchIndex) + grsuffix,null,true);
1373 1374 }
1374 1375 return _gravatar(grprefix + oResultData.grname + grsuffix, null,true);
1375 1376 // Users
1376 1377 } else if (oResultData.nname != undefined) {
1377 1378 var fname = oResultData.fname || "";
1378 1379 var lname = oResultData.lname || "";
1379 1380 var nname = oResultData.nname;
1380 1381
1381 1382 // Guard against null value
1382 1383 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1383 1384 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1384 1385 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1385 1386 displayfname, displaylname, displaynname;
1386 1387
1387 1388 if (fnameMatchIndex > -1) {
1388 1389 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1389 1390 } else {
1390 1391 displayfname = fname;
1391 1392 }
1392 1393
1393 1394 if (lnameMatchIndex > -1) {
1394 1395 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1395 1396 } else {
1396 1397 displaylname = lname;
1397 1398 }
1398 1399
1399 1400 if (nnameMatchIndex > -1) {
1400 1401 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1401 1402 } else {
1402 1403 displaynname = nname ? "(" + nname + ")" : "";
1403 1404 }
1404 1405
1405 1406 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1406 1407 } else {
1407 1408 return '';
1408 1409 }
1409 1410 };
1410 1411 membersAC.formatResult = custom_formatter;
1411 1412 ownerAC.formatResult = custom_formatter;
1412 1413
1413 1414 var myHandler = function (sType, aArgs) {
1414 1415 var nextId = divid.split('perm_new_member_name_')[1];
1415 1416 var myAC = aArgs[0]; // reference back to the AC instance
1416 1417 var elLI = aArgs[1]; // reference to the selected LI element
1417 1418 var oData = aArgs[2]; // object literal of selected item's result data
1418 1419 //fill the autocomplete with value
1419 1420 if (oData.nname != undefined) {
1420 1421 //users
1421 1422 myAC.getInputEl().value = oData.nname;
1422 1423 YUD.get('perm_new_member_type_'+nextId).value = 'user';
1423 1424 } else {
1424 1425 //groups
1425 1426 myAC.getInputEl().value = oData.grname;
1426 1427 YUD.get('perm_new_member_type_'+nextId).value = 'users_group';
1427 1428 }
1428 1429 };
1429 1430
1430 1431 membersAC.itemSelectEvent.subscribe(myHandler);
1431 1432 if(ownerAC.itemSelectEvent){
1432 1433 ownerAC.itemSelectEvent.subscribe(myHandler);
1433 1434 }
1434 1435
1435 1436 return {
1436 1437 memberDS: memberDS,
1437 1438 ownerDS: ownerDS,
1438 1439 membersAC: membersAC,
1439 1440 ownerAC: ownerAC,
1440 1441 };
1441 1442 }
1442 1443
1443 1444
1444 1445 var MentionsAutoComplete = function (divid, cont, users_list, groups_list) {
1445 1446 var myUsers = users_list;
1446 1447 var myGroups = groups_list;
1447 1448
1448 1449 // Define a custom search function for the DataSource of users
1449 1450 var matchUsers = function (sQuery) {
1450 1451 var org_sQuery = sQuery;
1451 1452 if(this.mentionQuery == null){
1452 1453 return []
1453 1454 }
1454 1455 sQuery = this.mentionQuery;
1455 1456 // Case insensitive matching
1456 1457 var query = sQuery.toLowerCase();
1457 1458 var i = 0;
1458 1459 var l = myUsers.length;
1459 1460 var matches = [];
1460 1461
1461 1462 // Match against each name of each contact
1462 1463 for (; i < l; i++) {
1463 1464 contact = myUsers[i];
1464 1465 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1465 1466 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1466 1467 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1467 1468 matches[matches.length] = contact;
1468 1469 }
1469 1470 }
1470 1471 return matches
1471 1472 };
1472 1473
1473 1474 //match all
1474 1475 var matchAll = function (sQuery) {
1475 1476 u = matchUsers(sQuery);
1476 1477 return u
1477 1478 };
1478 1479
1479 1480 // DataScheme for owner
1480 1481 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1481 1482
1482 1483 ownerDS.responseSchema = {
1483 1484 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1484 1485 };
1485 1486
1486 1487 // Instantiate AutoComplete for mentions
1487 1488 var ownerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1488 1489 ownerAC.useShadow = false;
1489 1490 ownerAC.resultTypeList = false;
1490 1491 ownerAC.suppressInputUpdate = true;
1491 1492 ownerAC.animVert = false;
1492 1493 ownerAC.animHoriz = false;
1493 1494 ownerAC.animSpeed = 0.1;
1494 1495
1495 1496 // Helper highlight function for the formatter
1496 1497 var highlightMatch = function (full, snippet, matchindex) {
1497 1498 return full.substring(0, matchindex)
1498 1499 + "<span class='match'>"
1499 1500 + full.substr(matchindex, snippet.length)
1500 1501 + "</span>" + full.substring(matchindex + snippet.length);
1501 1502 };
1502 1503
1503 1504 // Custom formatter to highlight the matching letters
1504 1505 ownerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1505 1506 var org_sQuery = sQuery;
1506 1507 if(this.dataSource.mentionQuery != null){
1507 1508 sQuery = this.dataSource.mentionQuery;
1508 1509 }
1509 1510
1510 1511 var query = sQuery.toLowerCase();
1511 1512 var _gravatar = function(res, em, group){
1512 1513 if (group !== undefined){
1513 1514 em = '/images/icons/group.png'
1514 1515 }
1515 1516 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1516 1517 return tmpl.format(em,res)
1517 1518 }
1518 1519 if (oResultData.nname != undefined) {
1519 1520 var fname = oResultData.fname || "";
1520 1521 var lname = oResultData.lname || "";
1521 1522 var nname = oResultData.nname;
1522 1523
1523 1524 // Guard against null value
1524 1525 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1525 1526 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1526 1527 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1527 1528 displayfname, displaylname, displaynname;
1528 1529
1529 1530 if (fnameMatchIndex > -1) {
1530 1531 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1531 1532 } else {
1532 1533 displayfname = fname;
1533 1534 }
1534 1535
1535 1536 if (lnameMatchIndex > -1) {
1536 1537 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1537 1538 } else {
1538 1539 displaylname = lname;
1539 1540 }
1540 1541
1541 1542 if (nnameMatchIndex > -1) {
1542 1543 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1543 1544 } else {
1544 1545 displaynname = nname ? "(" + nname + ")" : "";
1545 1546 }
1546 1547
1547 1548 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1548 1549 } else {
1549 1550 return '';
1550 1551 }
1551 1552 };
1552 1553
1553 1554 if(ownerAC.itemSelectEvent){
1554 1555 ownerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1555 1556
1556 1557 var myAC = aArgs[0]; // reference back to the AC instance
1557 1558 var elLI = aArgs[1]; // reference to the selected LI element
1558 1559 var oData = aArgs[2]; // object literal of selected item's result data
1559 1560 //fill the autocomplete with value
1560 1561 if (oData.nname != undefined) {
1561 1562 //users
1562 1563 //Replace the mention name with replaced
1563 1564 var re = new RegExp();
1564 1565 var org = myAC.getInputEl().value;
1565 1566 var chunks = myAC.dataSource.chunks
1566 1567 // replace middle chunk(the search term) with actuall match
1567 1568 chunks[1] = chunks[1].replace('@'+myAC.dataSource.mentionQuery,
1568 1569 '@'+oData.nname+' ');
1569 1570 myAC.getInputEl().value = chunks.join('')
1570 1571 YUD.get(myAC.getInputEl()).focus(); // Y U NO WORK !?
1571 1572 } else {
1572 1573 //groups
1573 1574 myAC.getInputEl().value = oData.grname;
1574 1575 YUD.get('perm_new_member_type').value = 'users_group';
1575 1576 }
1576 1577 });
1577 1578 }
1578 1579
1579 1580 // in this keybuffer we will gather current value of search !
1580 1581 // since we need to get this just when someone does `@` then we do the
1581 1582 // search
1582 1583 ownerAC.dataSource.chunks = [];
1583 1584 ownerAC.dataSource.mentionQuery = null;
1584 1585
1585 1586 ownerAC.get_mention = function(msg, max_pos) {
1586 1587 var org = msg;
1587 1588 var re = new RegExp('(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)$')
1588 1589 var chunks = [];
1589 1590
1590 1591
1591 1592 // cut first chunk until curret pos
1592 1593 var to_max = msg.substr(0, max_pos);
1593 1594 var at_pos = Math.max(0,to_max.lastIndexOf('@')-1);
1594 1595 var msg2 = to_max.substr(at_pos);
1595 1596
1596 1597 chunks.push(org.substr(0,at_pos))// prefix chunk
1597 1598 chunks.push(msg2) // search chunk
1598 1599 chunks.push(org.substr(max_pos)) // postfix chunk
1599 1600
1600 1601 // clean up msg2 for filtering and regex match
1601 1602 var msg2 = msg2.lstrip(' ').lstrip('\n');
1602 1603
1603 1604 if(re.test(msg2)){
1604 1605 var unam = re.exec(msg2)[1];
1605 1606 return [unam, chunks];
1606 1607 }
1607 1608 return [null, null];
1608 1609 };
1609 1610
1610 1611 if (ownerAC.textboxKeyUpEvent){
1611 1612 ownerAC.textboxKeyUpEvent.subscribe(function(type, args){
1612 1613
1613 1614 var ac_obj = args[0];
1614 1615 var currentMessage = args[1];
1615 1616 var currentCaretPosition = args[0]._elTextbox.selectionStart;
1616 1617
1617 1618 var unam = ownerAC.get_mention(currentMessage, currentCaretPosition);
1618 1619 var curr_search = null;
1619 1620 if(unam[0]){
1620 1621 curr_search = unam[0];
1621 1622 }
1622 1623
1623 1624 ownerAC.dataSource.chunks = unam[1];
1624 1625 ownerAC.dataSource.mentionQuery = curr_search;
1625 1626
1626 1627 })
1627 1628 }
1628 1629 return {
1629 1630 ownerDS: ownerDS,
1630 1631 ownerAC: ownerAC,
1631 1632 };
1632 1633 }
1633 1634
1634 1635 var addReviewMember = function(id,fname,lname,nname,gravatar_link){
1635 1636 var members = YUD.get('review_members');
1636 1637 var tmpl = '<li id="reviewer_{2}">'+
1637 1638 '<div class="reviewers_member">'+
1638 1639 '<div class="gravatar"><img alt="gravatar" src="{0}"/> </div>'+
1639 1640 '<div style="float:left">{1}</div>'+
1640 1641 '<input type="hidden" value="{2}" name="review_members" />'+
1641 1642 '<span class="delete_icon action_button" onclick="removeReviewMember({2})"></span>'+
1642 1643 '</div>'+
1643 1644 '</li>' ;
1644 1645 var displayname = "{0} {1} ({2})".format(fname,lname,nname);
1645 1646 var element = tmpl.format(gravatar_link,displayname,id);
1646 1647 // check if we don't have this ID already in
1647 1648 var ids = [];
1648 1649 var _els = YUQ('#review_members li');
1649 1650 for (el in _els){
1650 1651 ids.push(_els[el].id)
1651 1652 }
1652 1653 if(ids.indexOf('reviewer_'+id) == -1){
1653 1654 //only add if it's not there
1654 1655 members.innerHTML += element;
1655 1656 }
1656 1657
1657 1658 }
1658 1659
1659 1660 var removeReviewMember = function(reviewer_id, repo_name, pull_request_id){
1660 1661 var el = YUD.get('reviewer_{0}'.format(reviewer_id));
1661 1662 if (el.parentNode !== undefined){
1662 1663 el.parentNode.removeChild(el);
1663 1664 }
1664 1665 }
1665 1666
1666 1667 var updateReviewers = function(reviewers_ids, repo_name, pull_request_id){
1667 1668 if (reviewers_ids === undefined){
1668 1669 var reviewers_ids = [];
1669 1670 var ids = YUQ('#review_members input');
1670 1671 for(var i=0; i<ids.length;i++){
1671 1672 var id = ids[i].value
1672 1673 reviewers_ids.push(id);
1673 1674 }
1674 1675 }
1675 1676 var url = pyroutes.url('pullrequest_update', {"repo_name":repo_name,
1676 1677 "pull_request_id": pull_request_id});
1677 1678 var postData = {'_method':'put',
1678 1679 'reviewers_ids': reviewers_ids};
1679 1680 var success = function(o){
1680 1681 window.location.reload();
1681 1682 }
1682 1683 ajaxPOST(url,postData,success);
1683 1684 }
1684 1685
1685 1686 var PullRequestAutoComplete = function (divid, cont, users_list, groups_list) {
1686 1687 var myUsers = users_list;
1687 1688 var myGroups = groups_list;
1688 1689
1689 1690 // Define a custom search function for the DataSource of users
1690 1691 var matchUsers = function (sQuery) {
1691 1692 // Case insensitive matching
1692 1693 var query = sQuery.toLowerCase();
1693 1694 var i = 0;
1694 1695 var l = myUsers.length;
1695 1696 var matches = [];
1696 1697
1697 1698 // Match against each name of each contact
1698 1699 for (; i < l; i++) {
1699 1700 contact = myUsers[i];
1700 1701 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1701 1702 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1702 1703 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1703 1704 matches[matches.length] = contact;
1704 1705 }
1705 1706 }
1706 1707 return matches;
1707 1708 };
1708 1709
1709 1710 // Define a custom search function for the DataSource of usersGroups
1710 1711 var matchGroups = function (sQuery) {
1711 1712 // Case insensitive matching
1712 1713 var query = sQuery.toLowerCase();
1713 1714 var i = 0;
1714 1715 var l = myGroups.length;
1715 1716 var matches = [];
1716 1717
1717 1718 // Match against each name of each contact
1718 1719 for (; i < l; i++) {
1719 1720 matched_group = myGroups[i];
1720 1721 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1721 1722 matches[matches.length] = matched_group;
1722 1723 }
1723 1724 }
1724 1725 return matches;
1725 1726 };
1726 1727
1727 1728 //match all
1728 1729 var matchAll = function (sQuery) {
1729 1730 u = matchUsers(sQuery);
1730 1731 return u
1731 1732 };
1732 1733
1733 1734 // DataScheme for owner
1734 1735 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1735 1736
1736 1737 ownerDS.responseSchema = {
1737 1738 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1738 1739 };
1739 1740
1740 1741 // Instantiate AutoComplete for mentions
1741 1742 var reviewerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1742 1743 reviewerAC.useShadow = false;
1743 1744 reviewerAC.resultTypeList = false;
1744 1745 reviewerAC.suppressInputUpdate = true;
1745 1746 reviewerAC.animVert = false;
1746 1747 reviewerAC.animHoriz = false;
1747 1748 reviewerAC.animSpeed = 0.1;
1748 1749
1749 1750 // Helper highlight function for the formatter
1750 1751 var highlightMatch = function (full, snippet, matchindex) {
1751 1752 return full.substring(0, matchindex)
1752 1753 + "<span class='match'>"
1753 1754 + full.substr(matchindex, snippet.length)
1754 1755 + "</span>" + full.substring(matchindex + snippet.length);
1755 1756 };
1756 1757
1757 1758 // Custom formatter to highlight the matching letters
1758 1759 reviewerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1759 1760 var org_sQuery = sQuery;
1760 1761 if(this.dataSource.mentionQuery != null){
1761 1762 sQuery = this.dataSource.mentionQuery;
1762 1763 }
1763 1764
1764 1765 var query = sQuery.toLowerCase();
1765 1766 var _gravatar = function(res, em, group){
1766 1767 if (group !== undefined){
1767 1768 em = '/images/icons/group.png'
1768 1769 }
1769 1770 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1770 1771 return tmpl.format(em,res)
1771 1772 }
1772 1773 if (oResultData.nname != undefined) {
1773 1774 var fname = oResultData.fname || "";
1774 1775 var lname = oResultData.lname || "";
1775 1776 var nname = oResultData.nname;
1776 1777
1777 1778 // Guard against null value
1778 1779 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1779 1780 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1780 1781 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1781 1782 displayfname, displaylname, displaynname;
1782 1783
1783 1784 if (fnameMatchIndex > -1) {
1784 1785 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1785 1786 } else {
1786 1787 displayfname = fname;
1787 1788 }
1788 1789
1789 1790 if (lnameMatchIndex > -1) {
1790 1791 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1791 1792 } else {
1792 1793 displaylname = lname;
1793 1794 }
1794 1795
1795 1796 if (nnameMatchIndex > -1) {
1796 1797 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1797 1798 } else {
1798 1799 displaynname = nname ? "(" + nname + ")" : "";
1799 1800 }
1800 1801
1801 1802 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1802 1803 } else {
1803 1804 return '';
1804 1805 }
1805 1806 };
1806 1807
1807 1808 //members cache to catch duplicates
1808 1809 reviewerAC.dataSource.cache = [];
1809 1810 // hack into select event
1810 1811 if(reviewerAC.itemSelectEvent){
1811 1812 reviewerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1812 1813
1813 1814 var myAC = aArgs[0]; // reference back to the AC instance
1814 1815 var elLI = aArgs[1]; // reference to the selected LI element
1815 1816 var oData = aArgs[2]; // object literal of selected item's result data
1816 1817
1817 1818 //fill the autocomplete with value
1818 1819
1819 1820 if (oData.nname != undefined) {
1820 1821 addReviewMember(oData.id, oData.fname, oData.lname, oData.nname,
1821 1822 oData.gravatar_lnk);
1822 1823 myAC.dataSource.cache.push(oData.id);
1823 1824 YUD.get('user').value = ''
1824 1825 }
1825 1826 });
1826 1827 }
1827 1828 return {
1828 1829 ownerDS: ownerDS,
1829 1830 reviewerAC: reviewerAC,
1830 1831 };
1831 1832 }
1832 1833
1833 1834 /**
1834 1835 * QUICK REPO MENU
1835 1836 */
1836 1837 var quick_repo_menu = function(){
1837 1838 YUE.on(YUQ('.quick_repo_menu'),'mouseenter',function(e){
1838 1839 var menu = e.currentTarget.firstElementChild.firstElementChild;
1839 1840 if(YUD.hasClass(menu,'hidden')){
1840 1841 YUD.replaceClass(e.currentTarget,'hidden', 'active');
1841 1842 YUD.replaceClass(menu, 'hidden', 'active');
1842 1843 }
1843 1844 })
1844 1845 YUE.on(YUQ('.quick_repo_menu'),'mouseleave',function(e){
1845 1846 var menu = e.currentTarget.firstElementChild.firstElementChild;
1846 1847 if(YUD.hasClass(menu,'active')){
1847 1848 YUD.replaceClass(e.currentTarget, 'active', 'hidden');
1848 1849 YUD.replaceClass(menu, 'active', 'hidden');
1849 1850 }
1850 1851 })
1851 1852 };
1852 1853
1853 1854
1854 1855 /**
1855 1856 * TABLE SORTING
1856 1857 */
1857 1858
1858 1859 // returns a node from given html;
1859 1860 var fromHTML = function(html){
1860 1861 var _html = document.createElement('element');
1861 1862 _html.innerHTML = html;
1862 1863 return _html;
1863 1864 }
1864 1865 var get_rev = function(node){
1865 1866 var n = node.firstElementChild.firstElementChild;
1866 1867
1867 1868 if (n===null){
1868 1869 return -1
1869 1870 }
1870 1871 else{
1871 1872 out = n.firstElementChild.innerHTML.split(':')[0].replace('r','');
1872 1873 return parseInt(out);
1873 1874 }
1874 1875 }
1875 1876
1876 1877 var get_name = function(node){
1877 1878 var name = node.firstElementChild.children[2].innerHTML;
1878 1879 return name
1879 1880 }
1880 1881 var get_group_name = function(node){
1881 1882 var name = node.firstElementChild.children[1].innerHTML;
1882 1883 return name
1883 1884 }
1884 1885 var get_date = function(node){
1885 1886 var date_ = YUD.getAttribute(node.firstElementChild,'date');
1886 1887 return date_
1887 1888 }
1888 1889
1889 1890 var get_age = function(node){
1890 1891 return node
1891 1892 }
1892 1893
1893 1894 var get_link = function(node){
1894 1895 return node.firstElementChild.text;
1895 1896 }
1896 1897
1897 1898 var revisionSort = function(a, b, desc, field) {
1898 1899
1899 1900 var a_ = fromHTML(a.getData(field));
1900 1901 var b_ = fromHTML(b.getData(field));
1901 1902
1902 1903 // extract revisions from string nodes
1903 1904 a_ = get_rev(a_)
1904 1905 b_ = get_rev(b_)
1905 1906
1906 1907 var comp = YAHOO.util.Sort.compare;
1907 1908 var compState = comp(a_, b_, desc);
1908 1909 return compState;
1909 1910 };
1910 1911 var ageSort = function(a, b, desc, field) {
1911 1912 var a_ = fromHTML(a.getData(field));
1912 1913 var b_ = fromHTML(b.getData(field));
1913 1914
1914 1915 // extract name from table
1915 1916 a_ = get_date(a_)
1916 1917 b_ = get_date(b_)
1917 1918
1918 1919 var comp = YAHOO.util.Sort.compare;
1919 1920 var compState = comp(a_, b_, desc);
1920 1921 return compState;
1921 1922 };
1922 1923
1923 1924 var lastLoginSort = function(a, b, desc, field) {
1924 1925 var a_ = a.getData('last_login_raw') || 0;
1925 1926 var b_ = b.getData('last_login_raw') || 0;
1926 1927
1927 1928 var comp = YAHOO.util.Sort.compare;
1928 1929 var compState = comp(a_, b_, desc);
1929 1930 return compState;
1930 1931 };
1931 1932
1932 1933 var nameSort = function(a, b, desc, field) {
1933 1934 var a_ = fromHTML(a.getData(field));
1934 1935 var b_ = fromHTML(b.getData(field));
1935 1936
1936 1937 // extract name from table
1937 1938 a_ = get_name(a_)
1938 1939 b_ = get_name(b_)
1939 1940
1940 1941 var comp = YAHOO.util.Sort.compare;
1941 1942 var compState = comp(a_, b_, desc);
1942 1943 return compState;
1943 1944 };
1944 1945
1945 1946 var permNameSort = function(a, b, desc, field) {
1946 1947 var a_ = fromHTML(a.getData(field));
1947 1948 var b_ = fromHTML(b.getData(field));
1948 1949 // extract name from table
1949 1950
1950 1951 a_ = a_.children[0].innerHTML;
1951 1952 b_ = b_.children[0].innerHTML;
1952 1953
1953 1954 var comp = YAHOO.util.Sort.compare;
1954 1955 var compState = comp(a_, b_, desc);
1955 1956 return compState;
1956 1957 };
1957 1958
1958 1959 var groupNameSort = function(a, b, desc, field) {
1959 1960 var a_ = fromHTML(a.getData(field));
1960 1961 var b_ = fromHTML(b.getData(field));
1961 1962
1962 1963 // extract name from table
1963 1964 a_ = get_group_name(a_)
1964 1965 b_ = get_group_name(b_)
1965 1966
1966 1967 var comp = YAHOO.util.Sort.compare;
1967 1968 var compState = comp(a_, b_, desc);
1968 1969 return compState;
1969 1970 };
1970 1971 var dateSort = function(a, b, desc, field) {
1971 1972 var a_ = fromHTML(a.getData(field));
1972 1973 var b_ = fromHTML(b.getData(field));
1973 1974
1974 1975 // extract name from table
1975 1976 a_ = get_date(a_)
1976 1977 b_ = get_date(b_)
1977 1978
1978 1979 var comp = YAHOO.util.Sort.compare;
1979 1980 var compState = comp(a_, b_, desc);
1980 1981 return compState;
1981 1982 };
1982 1983
1983 1984 var linkSort = function(a, b, desc, field) {
1984 1985 var a_ = fromHTML(a.getData(field));
1985 1986 var b_ = fromHTML(a.getData(field));
1986 1987
1987 1988 // extract url text from string nodes
1988 1989 a_ = get_link(a_)
1989 1990 b_ = get_link(b_)
1990 1991
1991 1992 var comp = YAHOO.util.Sort.compare;
1992 1993 var compState = comp(a_, b_, desc);
1993 1994 return compState;
1994 1995 }
1995 1996
1996 1997 var addPermAction = function(_html, users_list, groups_list){
1997 1998 var elmts = YUD.getElementsByClassName('last_new_member');
1998 1999 var last_node = elmts[elmts.length-1];
1999 2000 if (last_node){
2000 2001 var next_id = (YUD.getElementsByClassName('new_members')).length;
2001 2002 _html = _html.format(next_id);
2002 2003 last_node.innerHTML = _html;
2003 2004 YUD.setStyle(last_node, 'display', '');
2004 2005 YUD.removeClass(last_node, 'last_new_member');
2005 2006 MembersAutoComplete("perm_new_member_name_"+next_id,
2006 2007 "perm_container_"+next_id, users_list, groups_list);
2007 2008 //create new last NODE
2008 2009 var el = document.createElement('tr');
2009 2010 el.id = 'add_perm_input';
2010 2011 YUD.addClass(el,'last_new_member');
2011 2012 YUD.addClass(el,'new_members');
2012 2013 YUD.insertAfter(el, last_node);
2013 2014 }
2014 2015 }
2015 2016
2016 2017 /* Multi selectors */
2017 2018
2018 2019 var MultiSelectWidget = function(selected_id, available_id, form_id){
2019 2020
2020 2021
2021 2022 //definition of containers ID's
2022 2023 var selected_container = selected_id;
2023 2024 var available_container = available_id;
2024 2025
2025 2026 //temp container for selected storage.
2026 2027 var cache = new Array();
2027 2028 var av_cache = new Array();
2028 2029 var c = YUD.get(selected_container);
2029 2030 var ac = YUD.get(available_container);
2030 2031
2031 2032 //get only selected options for further fullfilment
2032 2033 for(var i = 0;node =c.options[i];i++){
2033 2034 if(node.selected){
2034 2035 //push selected to my temp storage left overs :)
2035 2036 cache.push(node);
2036 2037 }
2037 2038 }
2038 2039
2039 2040 //get all available options to cache
2040 2041 for(var i = 0;node =ac.options[i];i++){
2041 2042 //push selected to my temp storage left overs :)
2042 2043 av_cache.push(node);
2043 2044 }
2044 2045
2045 2046 //fill available only with those not in choosen
2046 2047 ac.options.length=0;
2047 2048 tmp_cache = new Array();
2048 2049
2049 2050 for(var i = 0;node = av_cache[i];i++){
2050 2051 var add = true;
2051 2052 for(var i2 = 0;node_2 = cache[i2];i2++){
2052 2053 if(node.value == node_2.value){
2053 2054 add=false;
2054 2055 break;
2055 2056 }
2056 2057 }
2057 2058 if(add){
2058 2059 tmp_cache.push(new Option(node.text, node.value, false, false));
2059 2060 }
2060 2061 }
2061 2062
2062 2063 for(var i = 0;node = tmp_cache[i];i++){
2063 2064 ac.options[i] = node;
2064 2065 }
2065 2066
2066 2067 function prompts_action_callback(e){
2067 2068
2068 2069 var choosen = YUD.get(selected_container);
2069 2070 var available = YUD.get(available_container);
2070 2071
2071 2072 //get checked and unchecked options from field
2072 2073 function get_checked(from_field){
2073 2074 //temp container for storage.
2074 2075 var sel_cache = new Array();
2075 2076 var oth_cache = new Array();
2076 2077
2077 2078 for(var i = 0;node = from_field.options[i];i++){
2078 2079 if(node.selected){
2079 2080 //push selected fields :)
2080 2081 sel_cache.push(node);
2081 2082 }
2082 2083 else{
2083 2084 oth_cache.push(node)
2084 2085 }
2085 2086 }
2086 2087
2087 2088 return [sel_cache,oth_cache]
2088 2089 }
2089 2090
2090 2091 //fill the field with given options
2091 2092 function fill_with(field,options){
2092 2093 //clear firtst
2093 2094 field.options.length=0;
2094 2095 for(var i = 0;node = options[i];i++){
2095 2096 field.options[i]=new Option(node.text, node.value,
2096 2097 false, false);
2097 2098 }
2098 2099
2099 2100 }
2100 2101 //adds to current field
2101 2102 function add_to(field,options){
2102 2103 for(var i = 0;node = options[i];i++){
2103 2104 field.appendChild(new Option(node.text, node.value,
2104 2105 false, false));
2105 2106 }
2106 2107 }
2107 2108
2108 2109 // add action
2109 2110 if (this.id=='add_element'){
2110 2111 var c = get_checked(available);
2111 2112 add_to(choosen,c[0]);
2112 2113 fill_with(available,c[1]);
2113 2114 }
2114 2115 // remove action
2115 2116 if (this.id=='remove_element'){
2116 2117 var c = get_checked(choosen);
2117 2118 add_to(available,c[0]);
2118 2119 fill_with(choosen,c[1]);
2119 2120 }
2120 2121 // add all elements
2121 2122 if(this.id=='add_all_elements'){
2122 2123 for(var i=0; node = available.options[i];i++){
2123 2124 choosen.appendChild(new Option(node.text,
2124 2125 node.value, false, false));
2125 2126 }
2126 2127 available.options.length = 0;
2127 2128 }
2128 2129 //remove all elements
2129 2130 if(this.id=='remove_all_elements'){
2130 2131 for(var i=0; node = choosen.options[i];i++){
2131 2132 available.appendChild(new Option(node.text,
2132 2133 node.value, false, false));
2133 2134 }
2134 2135 choosen.options.length = 0;
2135 2136 }
2136 2137
2137 2138 }
2138 2139
2139 2140 YUE.addListener(['add_element','remove_element',
2140 2141 'add_all_elements','remove_all_elements'],'click',
2141 2142 prompts_action_callback)
2142 2143 if (form_id !== undefined) {
2143 2144 YUE.addListener(form_id,'submit',function(){
2144 2145 var choosen = YUD.get(selected_container);
2145 2146 for (var i = 0; i < choosen.options.length; i++) {
2146 2147 choosen.options[i].selected = 'selected';
2147 2148 }
2148 2149 });
2149 2150 }
2150 2151 }
@@ -1,373 +1,374 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Edit repository')} ${c.repo_info.repo_name} - ${c.rhodecode_name}
6 6 </%def>
7 7
8 8 <%def name="breadcrumbs_links()">
9 9 ${h.link_to(_(u'Home'),h.url('/'))}
10 10 &raquo;
11 11 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
12 12 &raquo;
13 13 ${_('edit')}
14 14 </%def>
15 15
16 16 <%def name="page_nav()">
17 17 ${self.menu('options')}
18 18 </%def>
19 19
20 20 <%def name="main()">
21 ${self.context_bar('options')}
21 22 <div class="box box-left">
22 23 <!-- box / title -->
23 24 <div class="title">
24 25 ${self.breadcrumbs()}
25 26 </div>
26 27 ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
27 28 <div class="form">
28 29 <!-- fields -->
29 30 <div class="fields">
30 31 <div class="field">
31 32 <div class="label">
32 33 <label for="repo_name">${_('Name')}:</label>
33 34 </div>
34 35 <div class="input">
35 36 ${h.text('repo_name',class_="medium")}
36 37 </div>
37 38 </div>
38 39 <div class="field">
39 40 <div class="label">
40 41 <label for="clone_uri">${_('Clone uri')}:</label>
41 42 </div>
42 43 <div class="input">
43 44 ${h.text('clone_uri',class_="medium")}
44 45 <span class="help-block">${_('Optional http[s] url from which repository should be cloned.')}</span>
45 46 </div>
46 47 </div>
47 48 <div class="field">
48 49 <div class="label">
49 50 <label for="repo_group">${_('Repository group')}:</label>
50 51 </div>
51 52 <div class="input">
52 53 ${h.select('repo_group','',c.repo_groups,class_="medium")}
53 54 <span class="help-block">${_('Optional select a group to put this repository into.')}</span>
54 55 </div>
55 56 </div>
56 57 <div class="field">
57 58 <div class="label">
58 59 <label for="repo_type">${_('Type')}:</label>
59 60 </div>
60 61 <div class="input">
61 62 ${h.select('repo_type','hg',c.backends,class_="medium")}
62 63 </div>
63 64 </div>
64 65 <div class="field">
65 66 <div class="label">
66 67 <label for="repo_landing_rev">${_('Landing revision')}:</label>
67 68 </div>
68 69 <div class="input">
69 70 ${h.select('repo_landing_rev','',c.landing_revs,class_="medium")}
70 71 <span class="help-block">${_('Default revision for files page, downloads, whoosh and readme')}</span>
71 72 </div>
72 73 </div>
73 74 <div class="field">
74 75 <div class="label label-textarea">
75 76 <label for="repo_description">${_('Description')}:</label>
76 77 </div>
77 78 <div class="textarea text-area editor">
78 79 ${h.textarea('repo_description')}
79 80 <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
80 81 </div>
81 82 </div>
82 83
83 84 <div class="field">
84 85 <div class="label label-checkbox">
85 86 <label for="repo_private">${_('Private repository')}:</label>
86 87 </div>
87 88 <div class="checkboxes">
88 89 ${h.checkbox('repo_private',value="True")}
89 90 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
90 91 </div>
91 92 </div>
92 93 <div class="field">
93 94 <div class="label label-checkbox">
94 95 <label for="repo_enable_statistics">${_('Enable statistics')}:</label>
95 96 </div>
96 97 <div class="checkboxes">
97 98 ${h.checkbox('repo_enable_statistics',value="True")}
98 99 <span class="help-block">${_('Enable statistics window on summary page.')}</span>
99 100 </div>
100 101 </div>
101 102 <div class="field">
102 103 <div class="label label-checkbox">
103 104 <label for="repo_enable_downloads">${_('Enable downloads')}:</label>
104 105 </div>
105 106 <div class="checkboxes">
106 107 ${h.checkbox('repo_enable_downloads',value="True")}
107 108 <span class="help-block">${_('Enable download menu on summary page.')}</span>
108 109 </div>
109 110 </div>
110 111 <div class="field">
111 112 <div class="label label-checkbox">
112 113 <label for="repo_enable_locking">${_('Enable locking')}:</label>
113 114 </div>
114 115 <div class="checkboxes">
115 116 ${h.checkbox('repo_enable_locking',value="True")}
116 117 <span class="help-block">${_('Enable lock-by-pulling on repository.')}</span>
117 118 </div>
118 119 </div>
119 120 <div class="field">
120 121 <div class="label">
121 122 <label for="user">${_('Owner')}:</label>
122 123 </div>
123 124 <div class="input input-medium ac">
124 125 <div class="perm_ac">
125 126 ${h.text('user',class_='yui-ac-input')}
126 127 <span class="help-block">${_('Change owner of this repository.')}</span>
127 128 <div id="owner_container"></div>
128 129 </div>
129 130 </div>
130 131 </div>
131 132 %if c.visual.repository_fields:
132 133 ## EXTRA FIELDS
133 134 %for field in c.repo_fields:
134 135 <div class="field">
135 136 <div class="label">
136 137 <label for="${field.field_key_prefixed}">${field.field_label} (${field.field_key}):</label>
137 138 </div>
138 139 <div class="input input-medium">
139 140 ${h.text(field.field_key_prefixed, field.field_value, class_='medium')}
140 141 %if field.field_desc:
141 142 <span class="help-block">${field.field_desc}</span>
142 143 %endif
143 144 </div>
144 145 </div>
145 146 %endfor
146 147 %endif
147 148 <div class="field">
148 149 <div class="label">
149 150 <label for="input">${_('Permissions')}:</label>
150 151 </div>
151 152 <div class="input">
152 153 <%include file="repo_edit_perms.html"/>
153 154 </div>
154 155
155 156 <div class="buttons">
156 157 ${h.submit('save',_('Save'),class_="ui-btn large")}
157 158 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
158 159 </div>
159 160 </div>
160 161 </div>
161 162 </div>
162 163 ${h.end_form()}
163 164 </div>
164 165
165 166 <div class="box box-right">
166 167 <div class="title">
167 168 <h5>${_('Administration')}</h5>
168 169 </div>
169 170
170 171 <h3>${_('Statistics')}</h3>
171 172 ${h.form(url('repo_stats', repo_name=c.repo_info.repo_name),method='delete')}
172 173 <div class="form">
173 174 <div class="fields">
174 175 ${h.submit('reset_stats_%s' % c.repo_info.repo_name,_('Reset current statistics'),class_="ui-btn",onclick="return confirm('"+_('Confirm to remove current statistics')+"');")}
175 176 <div class="field" style="border:none;color:#888">
176 177 <ul>
177 178 <li>${_('Fetched to rev')}: ${c.stats_revision}/${c.repo_last_rev}</li>
178 179 <li>${_('Stats gathered')}: ${c.stats_percentage}%</li>
179 180 </ul>
180 181 </div>
181 182 </div>
182 183 </div>
183 184 ${h.end_form()}
184 185
185 186 %if c.repo_info.clone_uri:
186 187 <h3>${_('Remote')}</h3>
187 188 ${h.form(url('repo_pull', repo_name=c.repo_info.repo_name),method='put')}
188 189 <div class="form">
189 190 <div class="fields">
190 191 ${h.submit('remote_pull_%s' % c.repo_info.repo_name,_('Pull changes from remote location'),class_="ui-btn",onclick="return confirm('"+_('Confirm to pull changes from remote side')+"');")}
191 192 <div class="field" style="border:none">
192 193 <ul>
193 194 <li><a href="${c.repo_info.clone_uri}">${c.repo_info.clone_uri}</a></li>
194 195 </ul>
195 196 </div>
196 197 </div>
197 198 </div>
198 199 ${h.end_form()}
199 200 %endif
200 201
201 202 <h3>${_('Cache')}</h3>
202 203 ${h.form(url('repo_cache', repo_name=c.repo_info.repo_name),method='delete')}
203 204 <div class="form">
204 205 <div class="fields">
205 206 ${h.submit('reset_cache_%s' % c.repo_info.repo_name,_('Invalidate repository cache'),class_="ui-btn",onclick="return confirm('"+_('Confirm to invalidate repository cache')+"');")}
206 207 <div class="field" style="border:none;color:#888">
207 208 <ul>
208 209 <li>${_('Manually invalidate cache for this repository. On first access repository will be cached again')}
209 210 </li>
210 211 </ul>
211 212 </div>
212 213 <div class="field" style="border:none;">
213 214 ${_('List of cached values')}
214 215 <table>
215 216 <tr>
216 217 <th>${_('Prefix')}</th>
217 218 <th>${_('Key')}</th>
218 219 <th>${_('Active')}</th>
219 220 </tr>
220 221 %for cache in c.repo_info.cache_keys:
221 222 <tr>
222 223 <td>${cache.prefix or '-'}</td>
223 224 <td>${cache.cache_key}</td>
224 225 <td>${h.bool2icon(cache.cache_active)}</td>
225 226 </tr>
226 227 %endfor
227 228 </table>
228 229 </div>
229 230 </div>
230 231 </div>
231 232 ${h.end_form()}
232 233
233 234 <h3>${_('Public journal')}</h3>
234 235 ${h.form(url('repo_public_journal', repo_name=c.repo_info.repo_name),method='put')}
235 236 <div class="form">
236 237 ${h.hidden('auth_token',str(h.get_token()))}
237 238 <div class="field">
238 239 %if c.in_public_journal:
239 240 ${h.submit('set_public_%s' % c.repo_info.repo_name,_('Remove from public journal'),class_="ui-btn")}
240 241 %else:
241 242 ${h.submit('set_public_%s' % c.repo_info.repo_name,_('Add to public journal'),class_="ui-btn")}
242 243 %endif
243 244 </div>
244 245 <div class="field" style="border:none;color:#888">
245 246 <ul>
246 247 <li>${_('All actions made on this repository will be accessible to everyone in public journal')}
247 248 </li>
248 249 </ul>
249 250 </div>
250 251 </div>
251 252 ${h.end_form()}
252 253
253 254 <h3>${_('Locking')}</h3>
254 255 ${h.form(url('repo_locking', repo_name=c.repo_info.repo_name),method='put')}
255 256 <div class="form">
256 257 <div class="fields">
257 258 %if c.repo_info.locked[0]:
258 259 ${h.submit('set_unlock' ,_('Unlock locked repo'),class_="ui-btn",onclick="return confirm('"+_('Confirm to unlock repository')+"');")}
259 260 ${'Locked by %s on %s' % (h.person_by_id(c.repo_info.locked[0]),h.fmt_date(h.time_to_datetime(c.repo_info.locked[1])))}
260 261 %else:
261 262 ${h.submit('set_lock',_('lock repo'),class_="ui-btn",onclick="return confirm('"+_('Confirm to lock repository')+"');")}
262 263 ${_('Repository is not locked')}
263 264 %endif
264 265 </div>
265 266 <div class="field" style="border:none;color:#888">
266 267 <ul>
267 268 <li>${_('Force locking on repository. Works only when anonymous access is disabled')}
268 269 </li>
269 270 </ul>
270 271 </div>
271 272 </div>
272 273 ${h.end_form()}
273 274
274 275 <h3>${_('Set as fork of')}</h3>
275 276 ${h.form(url('repo_as_fork', repo_name=c.repo_info.repo_name),method='put')}
276 277 <div class="form">
277 278 <div class="fields">
278 279 ${h.select('id_fork_of','',c.repos_list,class_="medium")}
279 280 ${h.submit('set_as_fork_%s' % c.repo_info.repo_name,_('set'),class_="ui-btn",)}
280 281 </div>
281 282 <div class="field" style="border:none;color:#888">
282 283 <ul>
283 284 <li>${_('''Manually set this repository as a fork of another from the list''')}</li>
284 285 </ul>
285 286 </div>
286 287 </div>
287 288 ${h.end_form()}
288 289
289 290 <h3>${_('Delete')}</h3>
290 291 ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='delete')}
291 292 <div class="form">
292 293 <div class="fields">
293 294 ${h.submit('remove_%s' % c.repo_info.repo_name,_('Remove this repository'),class_="ui-btn red",onclick="return confirm('"+_('Confirm to delete this repository')+"');")}
294 295 %if c.repo_info.forks.count():
295 296 - ${ungettext('this repository has %s fork', 'this repository has %s forks', c.repo_info.forks.count()) % c.repo_info.forks.count()}
296 297 <input type="radio" name="forks" value="detach_forks" checked="checked"/> <label for="forks">${_('Detach forks')}</label>
297 298 <input type="radio" name="forks" value="delete_forks" /> <label for="forks">${_('Delete forks')}</label>
298 299 %endif
299 300 </div>
300 301 <div class="field" style="border:none;color:#888">
301 302 <ul>
302 303 <li>${_('This repository will be renamed in a special way in order to be unaccesible for RhodeCode and VCS systems. If you need to fully delete it from file system please do it manually')}</li>
303 304 </ul>
304 305 </div>
305 306 </div>
306 307 ${h.end_form()}
307 308 </div>
308 309
309 310 ##TODO: this should be controlled by the VISUAL setting
310 311 %if c.visual.repository_fields:
311 312 <div class="box box-left" style="clear:left">
312 313 <!-- box / title -->
313 314 <div class="title">
314 315 <h5>${_('Extra fields')}</h5>
315 316 </div>
316 317
317 318 <div class="emails_wrap">
318 319 <table class="noborder">
319 320 %for field in c.repo_fields:
320 321 <tr>
321 322 <td>${field.field_label} (${field.field_key})</td>
322 323 <td>${field.field_type}</td>
323 324 <td>
324 325 ${h.form(url('delete_repo_fields', repo_name=c.repo_info.repo_name, field_id=field.repo_field_id),method='delete')}
325 326 ${h.submit('remove_%s' % field.repo_field_id, _('delete'), id="remove_field_%s" % field.repo_field_id,
326 327 class_="delete_icon action_button", onclick="return confirm('"+_('Confirm to delete this field: %s') % field.field_key+"');")}
327 328 ${h.end_form()}
328 329 </td>
329 330 </tr>
330 331 %endfor
331 332 </table>
332 333 </div>
333 334
334 335 ${h.form(url('create_repo_fields', repo_name=c.repo_info.repo_name),method='put')}
335 336 <div class="form">
336 337 <!-- fields -->
337 338 <div class="fields">
338 339 <div class="field">
339 340 <div class="label">
340 341 <label for="new_field_key">${_('New field key')}:</label>
341 342 </div>
342 343 <div class="input">
343 344 ${h.text('new_field_key', class_='small')}
344 345 </div>
345 346 </div>
346 347 <div class="field">
347 348 <div class="label">
348 349 <label for="new_field_label">${_('New field label')}:</label>
349 350 </div>
350 351 <div class="input">
351 352 ${h.text('new_field_label', class_='small', placeholder=_('Enter short label'))}
352 353 </div>
353 354 </div>
354 355
355 356 <div class="field">
356 357 <div class="label">
357 358 <label for="new_field_desc">${_('New field description')}:</label>
358 359 </div>
359 360 <div class="input">
360 361 ${h.text('new_field_desc', class_='small', placeholder=_('Enter description of a field'))}
361 362 </div>
362 363 </div>
363 364
364 365 <div class="buttons">
365 366 ${h.submit('save',_('Add'),class_="ui-btn large")}
366 367 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
367 368 </div>
368 369 </div>
369 370 </div>
370 371 ${h.end_form()}
371 372 </div>
372 373 %endif
373 374 </%def>
@@ -1,390 +1,419 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="root.html"/>
3 3
4 4 <!-- HEADER -->
5 5 <div id="header-dd"></div>
6 6 <div id="header">
7 7 <div id="header-inner" class="title">
8 8 <div id="logo">
9 9 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
10 10 </div>
11 11 <!-- MENU -->
12 12 ${self.page_nav()}
13 13 <!-- END MENU -->
14 14 ${self.body()}
15 15 </div>
16 16 </div>
17 17 <!-- END HEADER -->
18 18
19 19 <!-- CONTENT -->
20 20 <div id="content">
21 21 <div class="flash_msg">
22 22 <% messages = h.flash.pop_messages() %>
23 23 % if messages:
24 24 <ul id="flash-messages">
25 25 % for message in messages:
26 26 <li class="${message.category}_msg">${message}</li>
27 27 % endfor
28 28 </ul>
29 29 % endif
30 30 </div>
31 31 <div id="main">
32 32 ${next.main()}
33 33 </div>
34 34 </div>
35 35 <!-- END CONTENT -->
36 36
37 37 <!-- FOOTER -->
38 38 <div id="footer">
39 39 <div id="footer-inner" class="title">
40 40 <div>
41 41 <p class="footer-link">
42 42 <a href="${h.url('bugtracker')}">${_('Submit a bug')}</a>
43 43 </p>
44 44 <p class="footer-link-right">
45 45 <a href="${h.url('rhodecode_official')}">RhodeCode${'-%s' % c.rhodecode_instanceid if c.rhodecode_instanceid else ''}</a>
46 46 ${c.rhodecode_version} &copy; 2010-${h.datetime.today().year} by Marcin Kuzminski
47 47 </p>
48 48 </div>
49 49 </div>
50 50 </div>
51 51 <!-- END FOOTER -->
52 52
53 53 ### MAKO DEFS ###
54 54 <%def name="page_nav()">
55 55 ${self.menu()}
56 56 </%def>
57 57
58 58 <%def name="breadcrumbs()">
59 59 <div class="breadcrumbs">
60 60 ${self.breadcrumbs_links()}
61 61 </div>
62 62 </%def>
63 63
64 <%def name="context_bar(current=None)">
65 %if c.repo_name:
66 ${repo_context_bar(current)}
67 %endif
68 </%def>
69
70 <%def name="repo_context_bar(current=None)">
71 <%
72 def follow_class():
73 if c.repository_following:
74 return h.literal('following')
75 else:
76 return h.literal('follow')
77 %>
78 <%
79 def is_current(selected):
80 if selected == current:
81 return h.literal('class="current"')
82 %>
83
84 <!--- CONTEXT BAR -->
85 <div id="context-bar" class="box">
86 <div id="context-top">
87 <div id= "breadcrumbs">
88 ${h.link_to(_(u'Repositories'),h.url('home'))}
89 Β»
90 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
91 </div>
92 ## TODO: this check feels wrong, it would be better to have a check for permissions
93 ## also it feels like a job for the controller
94 %if c.rhodecode_user.username != 'default':
95 <ul id="context-actions" class="horizontal-list">
96 <li>
97 <button class="${follow_class()}" onclick="javascript:toggleFollowingRepo(this,${c.rhodecode_db_repo.repo_id},'${str(h.get_token())}');">
98 <!--span class="icon show-follow follow"></span>
99 <span class="icon show-following following"></span-->
100 <span class="show-follow">${_('Follow')}</span>
101 <span class="show-following">${_('Unfollow')}</span>
102 </button>
103 </li>
104 <li><a href="${h.url('repo_fork_home',repo_name=c.repo_name)}" class="fork">${_('Fork')}</a></li>
105 %if h.is_hg(c.rhodecode_repo):
106 <li><a href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="pull-request">${_('Pull Request')}</a></li>
107 %endif
108 </ul>
109 %endif
110 </div>
111 <div id="context-state">
112 <button id="revision-changer">
113 <span class="branch-name">graphics/shader-move</span>
114 <span class="revision">@73318:8d3d6ee94072</span>
115 </button>
116 <ul id="context-pages" class="horizontal-list">
117 <li ${is_current('summary')}><a href="${h.url('summary_home', repo_name=c.repo_name)}" class="summary">${_('Summary')}</a></li>
118 <li ${is_current('changelog')}><a href="${h.url('changelog_home', repo_name=c.repo_name)}" class="changelogs">${_('Changelogs')}</a></li>
119 <li ${is_current('files')}><a href="${h.url('files_home', repo_name=c.repo_name)}" class="files"></span>${_('Files')}</a></li>
120 <li>
121 <a href="#" id="branch_tag_switcher_2" class="dropdown switch-to"></span>${_('Switch To')}</a>
122 <ul id="switch_to_list_2" class="switch_to submenu">
123 <li><a href="#">${_('loading...')}</a></li>
124 </ul>
125 </li>
126 <li ${is_current('options')}>
127 <a href="#" class="dropdown options"></span>Options</a>
128 <ul>
129 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
130 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
131 <li>${h.link_to(_('repository settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
132 %else:
133 <li>${h.link_to(_('repository settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
134 %endif
135 %endif
136 %if c.rhodecode_db_repo.fork:
137 <li>${h.link_to(_('compare fork'),h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default'),class_='compare_request')}</li>
138 %endif
139 <li>${h.link_to(_('lightweight changelog'),h.url('shortlog_home',repo_name=c.repo_name),class_='shortlog')}</li>
140 <li>${h.link_to(_('search'),h.url('search_repo',repo_name=c.repo_name),class_='search')}</li>
141
142 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
143 %if c.rhodecode_db_repo.locked[0]:
144 <li>${h.link_to(_('unlock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_del')}</li>
145 %else:
146 <li>${h.link_to(_('lock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_add')}</li>
147 %endif
148 %endif
149
150 % if h.HasPermissionAll('hg.admin')('access admin main page'):
151 <li>
152 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin childs')}
153 <%def name="admin_menu()">
154 <ul class="admin_menu">
155 <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li>
156 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
157 <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
158 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
159 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
160 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
161 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
162 <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li>
163 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
164 </ul>
165 </%def>
166 ## ADMIN MENU
167 ${admin_menu()}
168 </li>
169 ## if you're a admin of any groups, show admin menu for it
170 % elif c.rhodecode_user.groups_admin:
171 <li>
172 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
173 <%def name="admin_menu_simple()">
174 <ul>
175 <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
176 </ul>
177 </%def>
178 ## ADMIN MENU
179 ${admin_menu_simple()}
180 </li>
181 % endif
182 </ul>
183 </li>
184 <li ${is_current('showpullrequest')}><a href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}" title="${_('Show Pull Requests')}" class="pull-request">1</a></li>
185 </ul>
186 </div>
187 </div>
188 <script type="text/javascript">
189 YUE.on('branch_tag_switcher_2','mouseover',function(){
190 var loaded = YUD.hasClass('branch_tag_switcher_2','loaded');
191 if(!loaded){
192 YUD.addClass('branch_tag_switcher_2','loaded');
193 ypjax("${h.url('branch_tag_switcher',repo_name=c.repo_name)}",'switch_to_list_2',
194 function(o){},
195 function(o){YUD.removeClass('branch_tag_switcher_2','loaded');}
196 ,null);
197 }
198 return false;
199 });
200 </script>
201 <!--- END CONTEXT BAR -->
202 </%def>
203
64 204 <%def name="usermenu()">
65 205 ## USER MENU
66 206 <li>
67 207 <a class="menu_link" id="quick_login_link">
68 208 <span class="icon" style="padding:5px 5px 0px 5px">
69 209 <img src="${h.gravatar_url(c.rhodecode_user.email,20)}" alt="avatar">
70 210 </span>
71 211 %if c.rhodecode_user.username != 'default':
72 212 <span class="menu_link_user">${c.rhodecode_user.username}</span>
73 213 %if c.unread_notifications != 0:
74 214 <span class="menu_link_notifications">${c.unread_notifications}</span>
75 215 %endif
76 216 %else:
77 217 <span>${_('Not logged in')}</span>
78 218 %endif
79 219 </a>
80 220
81 221 <div class="user-menu">
82 222 <div id="quick_login">
83 223 %if c.rhodecode_user.username == 'default':
84 224 <h4>${_('Login to your account')}</h4>
85 225 ${h.form(h.url('login_home',came_from=h.url.current()))}
86 226 <div class="form">
87 227 <div class="fields">
88 228 <div class="field">
89 229 <div class="label">
90 230 <label for="username">${_('Username')}:</label>
91 231 </div>
92 232 <div class="input">
93 233 ${h.text('username',class_='focus',size=40)}
94 234 </div>
95 235
96 236 </div>
97 237 <div class="field">
98 238 <div class="label">
99 239 <label for="password">${_('Password')}:</label>
100 240 </div>
101 241 <div class="input">
102 242 ${h.password('password',class_='focus',size=40)}
103 243 </div>
104 244
105 245 </div>
106 246 <div class="buttons">
107 247 <div class="password_forgoten">${h.link_to(_('Forgot password ?'),h.url('reset_password'))}</div>
108 248 <div class="register">
109 249 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
110 250 ${h.link_to(_("Don't have an account ?"),h.url('register'))}
111 251 %endif
112 252 </div>
113 253 <div class="submit">
114 254 ${h.submit('sign_in',_('Log In'),class_="ui-btn xsmall")}
115 255 </div>
116 256 </div>
117 257 </div>
118 258 </div>
119 259 ${h.end_form()}
120 260 %else:
121 261 <div class="links_left">
122 262 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
123 263 <div class="email">${c.rhodecode_user.email}</div>
124 264 <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,48)}" /></div>
125 265 <div class="notifications"><a href="${h.url('notifications')}">${_('Notifications')}</a></div>
126 266 <div class="unread"><a href="${h.url('notifications')}">${_('Unread')}: ${c.unread_notifications}</a></div>
127 267 </div>
128 268 <div class="links_right">
129 269 <ol class="links">
130 270 <li>${h.link_to(_(u'Home'),h.url('home'))}</li>
131 271 <li>${h.link_to(_(u'Journal'),h.url('journal'))}</li>
132 272 <li>${h.link_to(_(u'My account'),h.url('admin_settings_my_account'))}</li>
133 273 <li class="logout">${h.link_to(_(u'Log Out'),h.url('logout_home'))}</li>
134 274 </ol>
135 275 </div>
136 276 %endif
137 277 </div>
138 278 </div>
139 279
140 280 </li>
141 281 </%def>
142 282
143 283 <%def name="menu(current=None)">
144 284 <%
145 285 def is_current(selected):
146 286 if selected == current:
147 287 return h.literal('class="current"')
148 288 %>
149 289 <ul id="quick">
150 290 <!-- repo switcher -->
151 291 <li ${is_current('home')}>
152 292 <a class="menu_link" id="repo_switcher" title="${_('Switch repository')}" href="${h.url('home')}">
153 293 <span class="icon">
154 294 <img src="${h.url('/images/icons/database.png')}" alt="${_('Products')}" />
155 295 </span>
156 296 <span>${_('Repositories')}</span>
157 297 </a>
158 298 <ul id="repo_switcher_list" class="repo_switcher">
159 299 <li>
160 300 <a href="#">${_('loading...')}</a>
161 301 </li>
162 302 </ul>
163 303 </li>
164 304 ## we render this menu only not for those pages
165 305 %if current not in ['home','admin', 'search', 'journal']:
166 306 ##REGULAR MENU
167 <li ${is_current('summary')}>
168 <a class="menu_link" title="${_('Summary page')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
169 <span class="icon">
170 <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
171 </span>
172 <span>${_('Summary')}</span>
173 </a>
174 </li>
175 <li ${is_current('changelog')}>
176 <a class="menu_link" title="${_('Changeset list')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
177 <span class="icon">
178 <img src="${h.url('/images/icons/time.png')}" alt="${_('Changelog')}" />
179 </span>
180 <span>${_('Changelog')}</span>
181 </a>
182 </li>
183 <li ${is_current('switch_to')}>
184 <a class="menu_link" id="branch_tag_switcher" title="${_('Switch to')}" href="#">
185 <span class="icon">
186 <img src="${h.url('/images/icons/arrow_switch.png')}" alt="${_('Switch to')}" />
187 </span>
188 <span>${_('Switch to')}</span>
189 </a>
190 <ul id="switch_to_list" class="switch_to">
191 <li><a href="#">${_('loading...')}</a></li>
192 </ul>
193 </li>
194 <li ${is_current('files')}>
195 <a class="menu_link" title="${_('Show repository content')}" href="${h.url('files_home',repo_name=c.repo_name)}">
196 <span class="icon">
197 <img src="${h.url('/images/icons/file.png')}" alt="${_('Files')}" />
198 </span>
199 <span>${_('Files')}</span>
200 </a>
201 </li>
202 <li ${is_current('options')}>
203 <a class="menu_link" title="${_('Options')}" href="#">
204 <span class="icon">
205 <img src="${h.url('/images/icons/table_gear.png')}" alt="${_('Admin')}" />
206 </span>
207 <span>${_('Options')}</span>
208 </a>
209 <ul>
210 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
211 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
212 <li>${h.link_to(_('repository settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
213 %else:
214 <li>${h.link_to(_('repository settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
215 %endif
216 %endif
217
218 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
219 %if h.is_hg(c.rhodecode_repo):
220 <li>${h.link_to(_('open new pull request'),h.url('pullrequest_home',repo_name=c.repo_name),class_='pull_request')}</li>
221 %endif
222 %if c.rhodecode_db_repo.fork:
223 <li>${h.link_to(_('compare fork'),h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default'),class_='compare_request')}</li>
224 %endif
225 <li>${h.link_to(_('lightweight changelog'),h.url('shortlog_home',repo_name=c.repo_name),class_='shortlog')}</li>
226 <li>${h.link_to(_('search'),h.url('search_repo',repo_name=c.repo_name),class_='search')}</li>
227
228 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
229 %if c.rhodecode_db_repo.locked[0]:
230 <li>${h.link_to(_('unlock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_del')}</li>
231 %else:
232 <li>${h.link_to(_('lock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_add')}</li>
233 %endif
234 %endif
235
236 % if h.HasPermissionAll('hg.admin')('access admin main page'):
237 <li>
238 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
239 <%def name="admin_menu()">
240 <ul>
241 <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li>
242 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
243 <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
244 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
245 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
246 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
247 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
248 <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li>
249 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
250 </ul>
251 </%def>
252 ## ADMIN MENU
253 ${admin_menu()}
254 </li>
255 ## if you're a admin of any groups, show admin menu for it
256 % elif c.rhodecode_user.groups_admin:
257 <li>
258 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
259 <%def name="admin_menu_simple()">
260 <ul>
261 <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
262 </ul>
263 </%def>
264 ## ADMIN MENU
265 ${admin_menu_simple()}
266 </li>
267 % endif
268 </ul>
269 </li>
270 307 <li>
271 308 <a class="menu_link" title="${_('Followers')}" href="${h.url('repo_followers_home',repo_name=c.repo_name)}">
272 309 <span class="icon_short">
273 310 <img src="${h.url('/images/icons/heart.png')}" alt="${_('Followers')}" />
274 311 </span>
275 312 <span id="current_followers_count" class="short">${c.repository_followers}</span>
276 313 </a>
277 314 </li>
278 315 <li>
279 316 <a class="menu_link" title="${_('Forks')}" href="${h.url('repo_forks_home',repo_name=c.repo_name)}">
280 317 <span class="icon_short">
281 318 <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Forks')}" />
282 319 </span>
283 320 <span class="short">${c.repository_forks}</span>
284 321 </a>
285 322 </li>
286 <li>
287 <a class="menu_link" title="${_('Pull requests')}" href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}">
288 <span class="icon_short">
289 <img src="${h.url('/images/icons/arrow_join.png')}" alt="${_('Pull requests')}" />
290 </span>
291 <span class="short">${c.repository_pull_requests}</span>
292 </a>
293 </li>
294 323 ${usermenu()}
295 324 <script type="text/javascript">
296 325 YUE.on('branch_tag_switcher','mouseover',function(){
297 326 var loaded = YUD.hasClass('branch_tag_switcher','loaded');
298 327 if(!loaded){
299 328 YUD.addClass('branch_tag_switcher','loaded');
300 329 ypjax("${h.url('branch_tag_switcher',repo_name=c.repo_name)}",'switch_to_list',
301 330 function(o){},
302 331 function(o){YUD.removeClass('branch_tag_switcher','loaded');}
303 332 ,null);
304 333 }
305 334 return false;
306 335 });
307 336 </script>
308 337 %else:
309 338 ##ROOT MENU
310 339 %if c.rhodecode_user.username != 'default':
311 340 <li ${is_current('journal')}>
312 341 <a class="menu_link" title="${_('Show recent activity')}" href="${h.url('journal')}">
313 342 <span class="icon">
314 343 <img src="${h.url('/images/icons/book.png')}" alt="${_('Journal')}" />
315 344 </span>
316 345 <span>${_('Journal')}</span>
317 346 </a>
318 347 </li>
319 348 %else:
320 349 <li ${is_current('journal')}>
321 350 <a class="menu_link" title="${_('Public journal')}" href="${h.url('public_journal')}">
322 351 <span class="icon">
323 352 <img src="${h.url('/images/icons/book.png')}" alt="${_('Public journal')}" />
324 353 </span>
325 354 <span>${_('Public journal')}</span>
326 355 </a>
327 356 </li>
328 357 %endif
329 358 <li ${is_current('search')}>
330 359 <a class="menu_link" title="${_('Search in repositories')}" href="${h.url('search')}">
331 360 <span class="icon">
332 361 <img src="${h.url('/images/icons/search_16.png')}" alt="${_('Search')}" />
333 362 </span>
334 363 <span>${_('Search')}</span>
335 364 </a>
336 365 </li>
337 366 % if h.HasPermissionAll('hg.admin')('access admin main page'):
338 367 <li ${is_current('admin')}>
339 368 <a class="menu_link" title="${_('Admin')}" href="${h.url('admin_home')}">
340 369 <span class="icon">
341 370 <img src="${h.url('/images/icons/cog_edit.png')}" alt="${_('Admin')}" />
342 371 </span>
343 372 <span>${_('Admin')}</span>
344 373 </a>
345 374 ${admin_menu()}
346 375 </li>
347 376 % elif c.rhodecode_user.groups_admin:
348 377 <li ${is_current('admin')}>
349 378 <a class="menu_link" title="${_('Admin')}" href="${h.url('admin_home')}">
350 379 <span class="icon">
351 380 <img src="${h.url('/images/icons/cog_edit.png')}" alt="${_('Admin')}" />
352 381 </span>
353 382 <span>${_('Admin')}</span>
354 383 </a>
355 384 ${admin_menu_simple()}
356 385 </li>
357 386 % endif
358 387 ${usermenu()}
359 388 %endif
360 389 <script type="text/javascript">
361 390 YUE.on('repo_switcher','mouseover',function(){
362 391 var target = 'q_filter_rs';
363 392 var qfilter_activate = function(){
364 393 var nodes = YUQ('ul#repo_switcher_list li a.repo_name');
365 394 var func = function(node){
366 395 return node.parentNode;
367 396 }
368 397 q_filter(target,nodes,func);
369 398 }
370 399
371 400 var loaded = YUD.hasClass('repo_switcher','loaded');
372 401 if(!loaded){
373 402 YUD.addClass('repo_switcher','loaded');
374 403 ypjax("${h.url('repo_switcher')}",'repo_switcher_list',
375 404 function(o){qfilter_activate();YUD.get(target).focus()},
376 405 function(o){YUD.removeClass('repo_switcher','loaded');}
377 406 ,null);
378 407 }else{
379 408 YUD.get(target).focus();
380 409 }
381 410 return false;
382 411 });
383 412
384 413 YUE.on('header-dd', 'click',function(e){
385 414 YUD.addClass('header-inner', 'hover');
386 415 YUD.addClass('content', 'hover');
387 416 });
388 417
389 418 </script>
390 419 </%def>
@@ -1,111 +1,113 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <!DOCTYPE html>
3 3 <html xmlns="http://www.w3.org/1999/xhtml">
4 4 <head>
5 5 <title>${self.title()}</title>
6 6 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7 7 <meta name="robots" content="index, nofollow"/>
8 8 <link rel="icon" href="${h.url('/images/icons/database_gear.png')}" type="image/png" />
9 9
10 10 ## CSS ###
11 11 <%def name="css()">
12 12 <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css', ver=c.rhodecode_version)}" media="screen"/>
13 13 <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css', ver=c.rhodecode_version)}"/>
14
15 <link rel="stylesheet" type="text/css" href="${h.url('/css/contextbar.css', ver=c.rhodecode_version)}"/>
14 16 ## EXTRA FOR CSS
15 17 ${self.css_extra()}
16 18 </%def>
17 19 <%def name="css_extra()">
18 20 </%def>
19 21
20 22 ${self.css()}
21 23
22 24 %if c.ga_code:
23 25 <!-- Analytics -->
24 26 <script type="text/javascript">
25 27 var _gaq = _gaq || [];
26 28 _gaq.push(['_setAccount', '${c.ga_code}']);
27 29 _gaq.push(['_trackPageview']);
28 30
29 31 (function() {
30 32 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
31 33 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
32 34 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
33 35 })();
34 36 </script>
35 37 %endif
36 38
37 39 ## JAVASCRIPT ##
38 40 <%def name="js()">
39 41 <script type="text/javascript">
40 42 //JS translations map
41 43 var TRANSLATION_MAP = {
42 44 'add another comment':'${_("add another comment")}',
43 45 'Stop following this repository':"${_('Stop following this repository')}",
44 46 'Start following this repository':"${_('Start following this repository')}",
45 47 'Group':"${_('Group')}",
46 48 'members':"${_('members')}",
47 49 'loading...':"${_('loading...')}",
48 50 'search truncated': "${_('search truncated')}",
49 51 'no matching files': "${_('no matching files')}",
50 52 'Open new pull request': "${_('Open new pull request')}",
51 53 'Open new pull request for selected changesets': "${_('Open new pull request for selected changesets')}",
52 54 'Show selected changes __S -> __E': "${_('Show selected changes __S -> __E')}",
53 55 'Selection link': "${_('Selection link')}",
54 56 };
55 57 var _TM = TRANSLATION_MAP;
56 58
57 59 var TOGGLE_FOLLOW_URL = "${h.url('toggle_following')}";
58 60
59 61 </script>
60 62 <script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.rhodecode_version)}"></script>
61 63 <!--[if lt IE 9]>
62 64 <script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script>
63 65 <![endif]-->
64 66 <script type="text/javascript" src="${h.url('/js/yui.flot.js', ver=c.rhodecode_version)}"></script>
65 67 <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.rhodecode_version)}"></script>
66 68 <script type="text/javascript" src="${h.url('/js/pyroutes_map.js', ver=c.rhodecode_version)}"></script>
67 69 <script type="text/javascript" src="${h.url('/js/rhodecode.js', ver=c.rhodecode_version)}"></script>
68 70 ## EXTRA FOR JS
69 71 ${self.js_extra()}
70 72 <script type="text/javascript">
71 73 (function(window,undefined){
72 74 // Prepare
73 75 var History = window.History; // Note: We are using a capital H instead of a lower h
74 76 if ( !History.enabled ) {
75 77 // History.js is disabled for this browser.
76 78 // This is because we can optionally choose to support HTML4 browsers or not.
77 79 return false;
78 80 }
79 81 })(window);
80 82
81 83 YUE.onDOMReady(function(){
82 84 tooltip_activate();
83 85 show_more_event();
84 86 show_changeset_tooltip();
85 87 // routes registration
86 88 pyroutes.register('toggle_following', "${h.url('toggle_following')}");
87 89 pyroutes.register('changeset_info', "${h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s')}", ['repo_name', 'revision']);
88 90 pyroutes.register('repo_size', "${h.url('repo_size', repo_name='%(repo_name)s')}", ['repo_name']);
89 91 })
90 92 </script>
91 93 </%def>
92 94 <%def name="js_extra()"></%def>
93 95 ${self.js()}
94 96 <%def name="head_extra()"></%def>
95 97 ${self.head_extra()}
96 98 </head>
97 99 <body id="body">
98 100 ## IE hacks
99 101 <!--[if IE 7]>
100 102 <script>YUD.addClass(document.body,'ie7')</script>
101 103 <![endif]-->
102 104 <!--[if IE 8]>
103 105 <script>YUD.addClass(document.body,'ie8')</script>
104 106 <![endif]-->
105 107 <!--[if IE 9]>
106 108 <script>YUD.addClass(document.body,'ie9')</script>
107 109 <![endif]-->
108 110
109 111 ${next.body()}
110 112 </body>
111 113 </html>
@@ -1,306 +1,307 b''
1 1 ## -*- coding: utf-8 -*-
2 2
3 3 <%inherit file="/base/base.html"/>
4 4
5 5 <%def name="title()">
6 6 ${_('%s Changelog') % c.repo_name} - ${c.rhodecode_name}
7 7 </%def>
8 8
9 9 <%def name="breadcrumbs_links()">
10 10 ${h.link_to(_(u'Home'),h.url('/'))}
11 11 &raquo;
12 12 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
13 13 &raquo;
14 14 <% size = c.size if c.size <= c.total_cs else c.total_cs %>
15 15 ${_('changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
16 16 </%def>
17 17
18 18 <%def name="page_nav()">
19 19 ${self.menu('changelog')}
20 20 </%def>
21 21
22 22 <%def name="main()">
23 ${self.context_bar('changelog')}
23 24 <div class="box">
24 25 <!-- box / title -->
25 26 <div class="title">
26 27 ${self.breadcrumbs()}
27 28 </div>
28 29 <div class="table">
29 30 % if c.pagination:
30 31 <div id="graph">
31 32 <div id="graph_nodes">
32 33 <canvas id="graph_canvas"></canvas>
33 34 </div>
34 35 <div id="graph_content">
35 36 <div class="info_box" style="clear: both;padding: 10px 6px;vertical-align: right;text-align: right;">
36 37 <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a>
37 38 <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a>
38 39
39 40 %if c.rhodecode_db_repo.fork:
40 41 <a title="${_('compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default')}" class="ui-btn small">${_('Compare fork with parent')}</a>
41 42 %endif
42 43 %if h.is_hg(c.rhodecode_repo):
43 44 <a id="open_new_pr" href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('open new pull request')}</a>
44 45 %endif
45 46 </div>
46 47 <div class="container_header">
47 48 ${h.form(h.url.current(),method='get')}
48 49 <div class="info_box" style="float:left">
49 50 ${h.submit('set',_('Show'),class_="ui-btn")}
50 51 ${h.text('size',size=1,value=c.size)}
51 52 ${_('revisions')}
52 53 </div>
53 54 ${h.end_form()}
54 55 <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
55 56 </div>
56 57
57 58 %for cnt,cs in enumerate(c.pagination):
58 59 <div id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
59 60 <div class="left">
60 61 <div>
61 62 ${h.checkbox(cs.raw_id,class_="changeset_range")}
62 63 <span class="tooltip" title="${h.tooltip(h.age(cs.date))}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}"><span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span></a></span>
63 64 </div>
64 65 <div class="author">
65 66 <div class="gravatar">
66 67 <img alt="gravatar" src="${h.gravatar_url(h.email_or_none(cs.author),16)}"/>
67 68 </div>
68 69 <div title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</div>
69 70 </div>
70 71 <div class="date">${h.fmt_date(cs.date)}</div>
71 72 </div>
72 73 <div class="mid">
73 74 <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
74 75 <div class="expand"><span class="expandtext">&darr; ${_('show more')} &darr;</span></div>
75 76 </div>
76 77 <div class="right">
77 78 <div class="changes">
78 79 <div id="changed_total_${cs.raw_id}" style="float:right;" class="changed_total tooltip" title="${h.tooltip(_('Affected number of files, click to show more details'))}">${len(cs.affected_files)}</div>
79 80 <div class="comments-container">
80 81 %if len(c.comments.get(cs.raw_id,[])) > 0:
81 82 <div class="comments-cnt" title="${('comments')}">
82 83 <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
83 84 <div class="comments-cnt">${len(c.comments[cs.raw_id])}</div>
84 85 <img src="${h.url('/images/icons/comments.png')}">
85 86 </a>
86 87 </div>
87 88 %endif
88 89 </div>
89 90 <div class="changeset-status-container">
90 91 %if c.statuses.get(cs.raw_id):
91 92 <div title="${_('Changeset status')}" class="changeset-status-lbl">${c.statuses.get(cs.raw_id)[1]}</div>
92 93 <div class="changeset-status-ico">
93 94 %if c.statuses.get(cs.raw_id)[2]:
94 95 <a class="tooltip" title="${_('Click to open associated pull request #%s' % c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" /></a>
95 96 %else:
96 97 <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
97 98 %endif
98 99 </div>
99 100 %endif
100 101 </div>
101 102 </div>
102 103 %if cs.parents:
103 104 %for p_cs in reversed(cs.parents):
104 105 <div class="parent">${_('Parent')}
105 106 <span class="changeset_id">${p_cs.revision}:<span class="changeset_hash">${h.link_to(h.short_id(p_cs.raw_id),
106 107 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}</span></span>
107 108 </div>
108 109 %endfor
109 110 %else:
110 111 <div class="parent">${_('No parents')}</div>
111 112 %endif
112 113
113 114 <span class="logtags">
114 115 %if len(cs.parents)>1:
115 116 <span class="merge">${_('merge')}</span>
116 117 %endif
117 118 %if cs.branch:
118 119 <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}">
119 120 ${h.link_to(h.shorter(cs.branch),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
120 121 </span>
121 122 %endif
122 123 %if h.is_hg(c.rhodecode_repo):
123 124 %for book in cs.bookmarks:
124 125 <span class="bookbook" title="${'%s %s' % (_('bookmark'),book)}">
125 126 ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
126 127 </span>
127 128 %endfor
128 129 %endif
129 130 %for tag in cs.tags:
130 131 <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}">
131 132 ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span>
132 133 %endfor
133 134 </span>
134 135 </div>
135 136 </div>
136 137
137 138 %endfor
138 139 <div class="pagination-wh pagination-left">
139 140 ${c.pagination.pager('$link_previous ~2~ $link_next')}
140 141 </div>
141 142 </div>
142 143 </div>
143 144
144 145 <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
145 146 <script type="text/javascript">
146 147 YAHOO.util.Event.onDOMReady(function(){
147 148
148 149 //Monitor range checkboxes and build a link to changesets
149 150 //ranges
150 151 var checkboxes = YUD.getElementsByClassName('changeset_range');
151 152 var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
152 153 var pr_tmpl = "${h.url('pullrequest_home',repo_name=c.repo_name)}";
153 154 YUE.on(checkboxes,'click',function(e){
154 155 var clicked_cb = e.currentTarget;
155 156 var checked_checkboxes = [];
156 157 for (pos in checkboxes){
157 158 if(checkboxes[pos].checked){
158 159 checked_checkboxes.push(checkboxes[pos]);
159 160 }
160 161 }
161 162 if(YUD.get('open_new_pr')){
162 163 if(checked_checkboxes.length>0){
163 164 // modify open pull request to show we have selected cs
164 165 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets'];
165 166
166 167 }else{
167 168 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request'];
168 169 }
169 170 }
170 171
171 172 if(checked_checkboxes.length>0){
172 173 var rev_end = checked_checkboxes[0].name;
173 174 var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
174 175
175 176 // now select all checkboxes in the middle.
176 177 var checked = false;
177 178 for (var i=0; i<checkboxes.length; i++){
178 179 var cb = checkboxes[i];
179 180 var rev = cb.name;
180 181
181 182 if (rev == rev_end){
182 183 checked = true;
183 184 }
184 185 if (checked){
185 186 cb.checked = true;
186 187 }
187 188 else{
188 189 cb.checked = false;
189 190 }
190 191 if (rev == rev_start){
191 192 checked = false;
192 193 }
193 194
194 195 }
195 196
196 197 var url = url_tmpl.replace('__REVRANGE__',
197 198 rev_start+'...'+rev_end);
198 199
199 200 var link = _TM['Show selected changes __S -> __E'];
200 201 link = link.replace('__S',rev_start.substr(0,6));
201 202 link = link.replace('__E',rev_end.substr(0,6));
202 203 YUD.get('rev_range_container').href = url;
203 204 YUD.get('rev_range_container').innerHTML = link;
204 205 YUD.setStyle('rev_range_container','display','');
205 206 YUD.setStyle('rev_range_clear','display','');
206 207
207 208 YUD.get('open_new_pr').href = pr_tmpl + '?rev_start={0}&rev_end={1}'.format(rev_start,rev_end);
208 209
209 210 }
210 211 else{
211 212 YUD.setStyle('rev_range_container','display','none');
212 213 YUD.setStyle('rev_range_clear','display','none');
213 214 }
214 215 });
215 216 YUE.on('rev_range_clear','click',function(e){
216 217 for (var i=0; i<checkboxes.length; i++){
217 218 var cb = checkboxes[i];
218 219 cb.checked = false;
219 220 }
220 221 YUE.preventDefault(e);
221 222 })
222 223 var msgs = YUQ('.message');
223 224 // get first element height
224 225 var el = YUQ('#graph_content .container')[0];
225 226 var row_h = el.clientHeight;
226 227 for(var i=0;i<msgs.length;i++){
227 228 var m = msgs[i];
228 229
229 230 var h = m.clientHeight;
230 231 var pad = YUD.getStyle(m,'padding');
231 232 if(h > row_h){
232 233 var offset = row_h - (h+12);
233 234 YUD.setStyle(m.nextElementSibling,'display','block');
234 235 YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
235 236 };
236 237 }
237 238 YUE.on(YUQ('.expand'),'click',function(e){
238 239 var elem = e.currentTarget.parentNode.parentNode;
239 240 YUD.setStyle(e.currentTarget,'display','none');
240 241 YUD.setStyle(elem,'height','auto');
241 242
242 243 //redraw the graph, line_count and jsdata are global vars
243 244 set_canvas(100);
244 245
245 246 var r = new BranchRenderer();
246 247 r.render(jsdata,100,line_count);
247 248
248 249 })
249 250
250 251 // Fetch changeset details
251 252 YUE.on(YUD.getElementsByClassName('changed_total'),'click',function(e){
252 253 var id = e.currentTarget.id;
253 254 var url = "${h.url('changelog_details',repo_name=c.repo_name,cs='__CS__')}";
254 255 var url = url.replace('__CS__',id.replace('changed_total_',''));
255 256 ypjax(url,id,function(){tooltip_activate()});
256 257 });
257 258
258 259 // change branch filter
259 260 YUE.on(YUD.get('branch_filter'),'change',function(e){
260 261 var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
261 262 var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
262 263 var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
263 264 var url = url.replace('__BRANCH__',selected_branch);
264 265 if(selected_branch != ''){
265 266 window.location = url;
266 267 }else{
267 268 window.location = url_main;
268 269 }
269 270
270 271 });
271 272
272 273 function set_canvas(width) {
273 274 var c = document.getElementById('graph_nodes');
274 275 var t = document.getElementById('graph_content');
275 276 canvas = document.getElementById('graph_canvas');
276 277 var div_h = t.clientHeight;
277 278 c.style.height=div_h+'px';
278 279 canvas.setAttribute('height',div_h);
279 280 c.style.height=width+'px';
280 281 canvas.setAttribute('width',width);
281 282 };
282 283 var heads = 1;
283 284 var line_count = 0;
284 285 var jsdata = ${c.jsdata|n};
285 286
286 287 for (var i=0;i<jsdata.length;i++) {
287 288 var in_l = jsdata[i][2];
288 289 for (var j in in_l) {
289 290 var m = in_l[j][1];
290 291 if (m > line_count)
291 292 line_count = m;
292 293 }
293 294 }
294 295 set_canvas(100);
295 296
296 297 var r = new BranchRenderer();
297 298 r.render(jsdata,100,line_count);
298 299
299 300 });
300 301 </script>
301 302 %else:
302 303 ${_('There are no changes yet')}
303 304 %endif
304 305 </div>
305 306 </div>
306 307 </%def>
@@ -1,161 +1,162 b''
1 1 <%inherit file="/base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${_('%s files') % c.repo_name} - ${c.rhodecode_name}
5 5 </%def>
6 6
7 7 <%def name="breadcrumbs_links()">
8 8 ${h.link_to(_(u'Home'),h.url('/'))}
9 9 &raquo;
10 10 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
11 11 &raquo;
12 12 ${_('files')}
13 13 %if c.file:
14 14 @ r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)}
15 15 %endif
16 16 </%def>
17 17
18 18 <%def name="page_nav()">
19 19 ${self.menu('files')}
20 20 </%def>
21 21
22 22 <%def name="main()">
23 ${self.context_bar('files')}
23 24 <div class="box">
24 25 <!-- box / title -->
25 26 <div class="title">
26 27 ${self.breadcrumbs()}
27 28 <ul class="links">
28 29 <li>
29 30 <span style="text-transform: uppercase;"><a href="#">${_('branch')}: ${c.changeset.branch}</a></span>
30 31 </li>
31 32 </ul>
32 33 </div>
33 34 <div class="table">
34 35 <div id="files_data">
35 36 <%include file='files_ypjax.html'/>
36 37 </div>
37 38 </div>
38 39 </div>
39 40
40 41 <script type="text/javascript">
41 42 var CACHE = {};
42 43 var CACHE_EXPIRE = 5*60*1000; //cache for 5*60s
43 44 //used to construct links from the search list
44 45 var url_base = '${h.url("files_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}';
45 46 //send the nodelist request to this url
46 47 var node_list_url = '${h.url("files_nodelist_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}';
47 48 // send the node history requst to this url
48 49 var node_history_url = '${h.url("files_history_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}';
49 50
50 51 var ypjax_links = function(){
51 52 YUE.on(YUQ('.ypjax-link'), 'click',function(e){
52 53
53 54 //don't do ypjax on middle click
54 55 if(e.which == 2 || !History.enabled){
55 56 return true;
56 57 }
57 58
58 59 var el = e.currentTarget;
59 60 var url = el.href;
60 61
61 62 var _base_url = '${h.url("files_home",repo_name=c.repo_name,revision='',f_path='')}';
62 63 _base_url = _base_url.replace('//','/')
63 64
64 65 //extract rev and the f_path from url.
65 66 parts = url.split(_base_url)
66 67 if(parts.length != 2){
67 68 return false;
68 69 }
69 70
70 71 var parts2 = parts[1].split('/');
71 72 var rev = parts2.shift(); // pop the first element which is the revision
72 73 var f_path = parts2.join('/');
73 74
74 75 var title = "${_('%s files') % c.repo_name}" + " - " + f_path;
75 76
76 77 var _node_list_url = node_list_url.replace('__REV__',rev).replace('__FPATH__', f_path);
77 78 var _url_base = url_base.replace('__REV__',rev);
78 79
79 80 // Change our States and save some data for handling events
80 81 var data = {url:url,title:title, url_base:_url_base,
81 82 node_list_url:_node_list_url, rev:rev, f_path:f_path};
82 83 History.pushState(data, title, url);
83 84
84 85 //now we're sure that we can do ypjax things
85 86 YUE.preventDefault(e);
86 87 return false;
87 88 });
88 89 }
89 90
90 91 var callbacks = function(State){
91 92 ypjax_links();
92 93 tooltip_activate();
93 94 fileBrowserListeners(State.url, State.data.node_list_url, State.data.url_base);
94 95
95 96 if(YUD.get('hlcode')){
96 97 YUE.on('hlcode', 'mouseup', getSelectionLink);
97 98 }
98 99 //console.log(State);
99 100 if(YUD.get('load_node_history')){
100 101 //remove all listeners due to problems of history state
101 102 YUE.removeListener('load_node_history', 'click');
102 103 YUE.on('load_node_history', 'click', function(e){
103 104 var _url = node_history_url.replace('__REV__',State.data.rev).replace('__FPATH__', State.data.f_path);
104 105 ypjax(_url, 'node_history', function(o){
105 106 tooltip_activate();
106 107 })
107 108 });
108 109 }
109 110 // Inform Google Analytics of the change
110 111 if ( typeof window.pageTracker !== 'undefined' ) {
111 112 window.pageTracker._trackPageview(State.url);
112 113 }
113 114 }
114 115
115 116 YUE.onDOMReady(function(){
116 117 ypjax_links();
117 118 var container = 'files_data';
118 119 //Bind to StateChange Event
119 120 History.Adapter.bind(window,'statechange',function(){
120 121 var State = History.getState();
121 122 cache_key = State.url;
122 123 //check if we have this request in cache maybe ?
123 124 var _cache_obj = CACHE[cache_key];
124 125 var _cur_time = new Date().getTime();
125 126 // get from cache if it's there and not yet expired !
126 127 if(_cache_obj !== undefined && _cache_obj[0] > _cur_time){
127 128 YUD.get(container).innerHTML=_cache_obj[1];
128 129 YUD.setStyle(container,'opacity','1.0');
129 130
130 131 //callbacks after ypjax call
131 132 callbacks(State);
132 133 }
133 134 else{
134 135 ypjax(State.url,container,function(o){
135 136 //callbacks after ypjax call
136 137 callbacks(State);
137 138 if (o !== undefined){
138 139 //store our request in cache
139 140 var _expire_on = new Date().getTime()+CACHE_EXPIRE;
140 141 CACHE[cache_key] = [_expire_on, o.responseText];
141 142 }
142 143 });
143 144 }
144 145 });
145 146
146 147 // init the search filter
147 148 var _State = {
148 149 url: "${h.url.current()}",
149 150 data: {
150 151 node_list_url: node_list_url.replace('__REV__',"${c.changeset.raw_id}").replace('__FPATH__', "${h.safe_unicode(c.file.path)}"),
151 152 url_base: url_base.replace('__REV__',"${c.changeset.raw_id}"),
152 153 rev:"${c.changeset.raw_id}",
153 154 f_path: "${h.safe_unicode(c.file.path)}"
154 155 }
155 156 }
156 157 fileBrowserListeners(_State.url, _State.data.node_list_url, _State.data.url_base);
157 158 });
158 159
159 160 </script>
160 161
161 162 </%def>
@@ -1,44 +1,44 b''
1 1 <%inherit file="/base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${c.repo_name} ${_('all pull requests')}
5 5 </%def>
6 6
7 7 <%def name="breadcrumbs_links()">
8 8 ${h.link_to(_(u'Home'),h.url('/'))}
9 9 &raquo;
10 10 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
11 11 &raquo;
12 12 ${_('pull requests')}
13 13 </%def>
14 14
15 15 <%def name="main()">
16
16 ${self.context_bar('showpullrequest')}
17 17 <div class="box">
18 18 <!-- box / title -->
19 19 <div class="title">
20 20 ${self.breadcrumbs()}
21 21 </div>
22 22
23 23 %for pr in c.pull_requests:
24 24 <div>
25 25 <h4 style="border:0px;padding:0px">
26 26 %if pr.is_closed():
27 27 <img src="${h.url('/images/icons/lock_go.png')}" title="${_('Closed')}"/>
28 28 %endif
29 29 <img src="${h.url('/images/icons/flag_status_%s.png' % str(pr.last_review_status))}" />
30 30 <a href="${h.url('pullrequest_show',repo_name=c.repo_name,pull_request_id=pr.pull_request_id)}">
31 31 ${_('Pull request #%s opened by %s on %s') % (pr.pull_request_id, pr.author.full_name, h.fmt_date(pr.created_on))}
32 32 </a>
33 33 </h4>
34 34 <h5 style="border:0px;padding-bottom:0px">${_('Title')}: ${pr.title}</h5>
35 35 <div style="padding:0px 24px">${pr.description}</div>
36 36 <div style="border-bottom: 1px solid #DDD;margin:10px 20px;padding-bottom:10px"></div>
37 37 </div>
38 38 %endfor
39 39
40 40 </div>
41 41
42 42 <script type="text/javascript"></script>
43 43
44 44 </%def>
@@ -1,91 +1,91 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3 3
4 4 <%def name="title()">
5 5 %if c.repo_name:
6 6 ${_('Search repository')} ${c.repo_name} - ${c.rhodecode_name}
7 7 %else:
8 8 ${_('Search in all repositories')}
9 9 %endif
10 10 </%def>
11 11
12 12 <%def name="breadcrumbs_links()">
13 13 %if c.repo_name:
14 14 ${h.link_to(_(u'Home'),h.url('/'))}
15 15 &raquo;
16 16 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
17 17 &raquo;
18 18 ${_('search')}
19 19 %else:
20 20 ${_('search in all repositories')}
21 21 %endif
22 22 %if c.cur_query:
23 23 &raquo;
24 24 ${c.cur_query}
25 25 %endif
26 26 </%def>
27 27
28 28 <%def name="page_nav()">
29 29 %if c.repo_name:
30 30 ${self.menu('options')}
31 31 %else:
32 32 ${self.menu('search')}
33 33 %endif
34 34 </%def>
35 35 <%def name="main()">
36
36 ${self.context_bar('options')}
37 37 <div class="box">
38 38 <!-- box / title -->
39 39 <div class="title">
40 40 ${self.breadcrumbs()}
41 41 </div>
42 42 <!-- end box / title -->
43 43 %if c.repo_name:
44 44 ${h.form(h.url('search_repo',repo_name=c.repo_name),method='get')}
45 45 %else:
46 46 ${h.form(h.url('search'),method='get')}
47 47 %endif
48 48 <div class="form">
49 49 <div class="fields">
50 50 <div class="field field-first field-noborder">
51 51 <div class="label">
52 52 <label for="q">${_('Search term')}</label>
53 53 </div>
54 54 <div class="input">${h.text('q',c.cur_query,class_="small")}
55 55 <div class="button highlight">
56 56 <input type="submit" value="${_('Search')}" class="ui-button"/>
57 57 </div>
58 58 </div>
59 59 <div style="font-weight: bold;clear:Both;margin-left:200px">${c.runtime}</div>
60 60 </div>
61 61
62 62 <div class="field">
63 63 <div class="label">
64 64 <label for="type">${_('Search in')}</label>
65 65 </div>
66 66 <div class="select">
67 67 ${h.select('type',c.cur_type,[('content',_('File contents')),
68 68 ('commit',_('Commit messages')),
69 69 ('path',_('File names')),
70 70 ##('repository',_('Repository names')),
71 71 ])}
72 72 </div>
73 73 </div>
74 74
75 75 </div>
76 76 </div>
77 77 ${h.end_form()}
78 78 <div class="search">
79 79 %if c.cur_type == 'content':
80 80 <%include file='search_content.html'/>
81 81 %elif c.cur_type == 'path':
82 82 <%include file='search_path.html'/>
83 83 %elif c.cur_type == 'commit':
84 84 <%include file='search_commit.html'/>
85 85 %elif c.cur_type == 'repository':
86 86 <%include file='search_repository.html'/>
87 87 %endif
88 88 </div>
89 89 </div>
90 90
91 91 </%def>
@@ -1,39 +1,40 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3 3
4 4 <%def name="title()">
5 5 ${_('%s Shortlog') % c.repo_name} - ${c.rhodecode_name}
6 6 </%def>
7 7
8 8
9 9 <%def name="breadcrumbs_links()">
10 10 ${h.link_to(_(u'Home'),h.url('/'))}
11 11 &raquo;
12 12 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
13 13 &raquo;
14 14 %if c.file_history:
15 15 ${h.link_to(_('shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}
16 16 &raquo;
17 17 ${c.file_history}
18 18 %else:
19 19 ${_('shortlog')}
20 20 %endif
21 21 </%def>
22 22
23 23 <%def name="page_nav()">
24 24 ${self.menu('shortlog')}
25 25 </%def>
26 26 <%def name="main()">
27 ${self.context_bar('options')}
27 28 <div class="box">
28 29 <!-- box / title -->
29 30 <div class="title">
30 31 ${self.breadcrumbs()}
31 32 </div>
32 33 <!-- end box / title -->
33 34 <div class="table">
34 35 <div id="shortlog_data">
35 36 ${c.shortlog_data}
36 37 </div>
37 38 </div>
38 39 </div>
39 40 </%def>
@@ -1,725 +1,726 b''
1 1 <%inherit file="/base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${_('%s Summary') % c.repo_name} - ${c.rhodecode_name}
5 5 </%def>
6 6
7 7 <%def name="breadcrumbs_links()">
8 8 ${h.link_to(_(u'Home'),h.url('/'))}
9 9 &raquo;
10 10 ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
11 11 &raquo;
12 12 ${_('summary')}
13 13 </%def>
14 14
15 15 <%def name="page_nav()">
16 16 ${self.menu('summary')}
17 17 </%def>
18 18
19 19 <%def name="head_extra()">
20 20 <link href="${h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('repo %s ATOM feed') % c.repo_name}" type="application/atom+xml" />
21 21 <link href="${h.url('rss_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('repo %s RSS feed') % c.repo_name}" type="application/rss+xml" />
22 22 </%def>
23 23
24 24 <%def name="main()">
25 ${self.context_bar('summary')}
25 26 <%
26 27 summary = lambda n:{False:'summary-short'}.get(n)
27 28 %>
28 29 %if c.show_stats:
29 30 <div class="box box-left">
30 31 %else:
31 32 <div class="box">
32 33 %endif
33 34 <!-- box / title -->
34 35 <div class="title">
35 36 ${self.breadcrumbs()}
36 37 </div>
37 38 <!-- end box / title -->
38 39 <div class="form">
39 40 <div id="summary" class="fields">
40 41
41 42 <div class="field">
42 43 <div class="label-summary">
43 44 <label>${_('Name')}:</label>
44 45 </div>
45 46 <div class="input ${summary(c.show_stats)}">
46 47 <div style="float:right;padding:5px 0px 0px 5px">
47 48 %if c.rhodecode_user.username != 'default':
48 49 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='atom_icon')}
49 50 %else:
50 51 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name),class_='atom_icon')}
51 52 %endif
52 53 </div>
53 54 %if c.rhodecode_user.username != 'default':
54 55 %if c.following:
55 56 <span id="follow_toggle" class="following tooltip" title="${_('Stop following this repository')}"
56 57 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
57 58 </span>
58 59 %else:
59 60 <span id="follow_toggle" class="follow tooltip" title="${_('Start following this repository')}"
60 61 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
61 62 </span>
62 63 %endif
63 64 <div style="float:right;padding:0px 0px 0px 0px">
64 65 <span class="reposize tooltip" title="${_('Click to show size of repository')}"
65 66 onclick="javascript:showRepoSize('repo_size','${c.dbrepo.repo_name}','${str(h.get_token())}')">
66 67 </span>
67 68 <span id="repo_size"></span>
68 69 </div>
69 70 %endif:
70 71
71 72 ## locking icon
72 73 %if c.rhodecode_db_repo.enable_locking:
73 74 %if c.rhodecode_db_repo.locked[0]:
74 75 <span class="locking_locked tooltip" title="${_('Repository locked by %s') % h.person_by_id(c.rhodecode_db_repo.locked[0])}"></span>
75 76 %else:
76 77 <span class="locking_unlocked tooltip" title="${_('Repository unlocked')}"></span>
77 78 %endif
78 79 %endif
79 80 ##REPO TYPE
80 81 %if h.is_hg(c.dbrepo):
81 82 <img style="margin-bottom:2px" class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
82 83 %endif
83 84 %if h.is_git(c.dbrepo):
84 85 <img style="margin-bottom:2px" class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
85 86 %endif
86 87
87 88 ##PUBLIC/PRIVATE
88 89 %if c.dbrepo.private:
89 90 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
90 91 %else:
91 92 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
92 93 %endif
93 94
94 95 ##REPO NAME
95 96 <span class="repo_name" title="${_('Non changable ID %s') % c.dbrepo.repo_id}">${h.repo_link(c.dbrepo.groups_and_repo)}</span>
96 97
97 98 ##FORK
98 99 %if c.dbrepo.fork:
99 <div style="margin-top:5px;clear:both"">
100 <div style="margin-top:5px;clear:both">
100 101 <a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}"><img class="icon" alt="${_('public')}" title="${_('Fork of')} ${c.dbrepo.fork.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/>
101 102 ${_('Fork of')} ${c.dbrepo.fork.repo_name}
102 103 </a>
103 104 </div>
104 105 %endif
105 106 ##REMOTE
106 107 %if c.dbrepo.clone_uri:
107 108 <div style="margin-top:5px;clear:both">
108 109 <a href="${h.url(str(h.hide_credentials(c.dbrepo.clone_uri)))}"><img class="icon" alt="${_('remote clone')}" title="${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}" src="${h.url('/images/icons/connect.png')}"/>
109 110 ${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}
110 111 </a>
111 112 </div>
112 113 %endif
113 114 </div>
114 115 </div>
115 116
116 117 <div class="field">
117 118 <div class="label-summary">
118 119 <label>${_('Description')}:</label>
119 120 </div>
120 121 %if c.visual.stylify_metatags:
121 122 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(h.desc_stylize(c.dbrepo.description))}</div>
122 123 %else:
123 124 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(c.dbrepo.description)}</div>
124 125 %endif
125 126 </div>
126 127
127 128 <div class="field">
128 129 <div class="label-summary">
129 130 <label>${_('Contact')}:</label>
130 131 </div>
131 132 <div class="input ${summary(c.show_stats)}">
132 133 <div class="gravatar">
133 134 <img alt="gravatar" src="${h.gravatar_url(c.dbrepo.user.email)}"/>
134 135 </div>
135 136 ${_('Username')}: ${c.dbrepo.user.username}<br/>
136 137 ${_('Name')}: ${c.dbrepo.user.name} ${c.dbrepo.user.lastname}<br/>
137 138 ${_('Email')}: <a href="mailto:${c.dbrepo.user.email}">${c.dbrepo.user.email}</a>
138 139 </div>
139 140 </div>
140 141
141 142 <div class="field">
142 143 <div class="label-summary">
143 144 <label>${_('Clone url')}:</label>
144 145 </div>
145 146 <div class="input ${summary(c.show_stats)}">
146 147 <input style="width:80%" type="text" id="clone_url" readonly="readonly" value="${c.clone_repo_url}"/>
147 148 <input style="display:none;width:80%" type="text" id="clone_url_id" readonly="readonly" value="${c.clone_repo_url_id}"/>
148 149 <div style="display:none" id="clone_by_name" class="ui-btn clone">${_('Show by Name')}</div>
149 150 <div id="clone_by_id" class="ui-btn clone">${_('Show by ID')}</div>
150 151 </div>
151 152 </div>
152 153
153 154 <div class="field">
154 155 <div class="label-summary">
155 156 <label>${_('Trending files')}:</label>
156 157 </div>
157 158 <div class="input ${summary(c.show_stats)}">
158 159 %if c.show_stats:
159 160 <div id="lang_stats"></div>
160 161 %else:
161 162 ${_('Statistics are disabled for this repository')}
162 163 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
163 164 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
164 165 %endif
165 166 %endif
166 167 </div>
167 168 </div>
168 169
169 170 <div class="field">
170 171 <div class="label-summary">
171 172 <label>${_('Download')}:</label>
172 173 </div>
173 174 <div class="input ${summary(c.show_stats)}">
174 175 %if len(c.rhodecode_repo.revisions) == 0:
175 176 ${_('There are no downloads yet')}
176 177 %elif c.enable_downloads is False:
177 178 ${_('Downloads are disabled for this repository')}
178 179 %if h.HasPermissionAll('hg.admin')('enable downloads on from summary'):
179 180 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
180 181 %endif
181 182 %else:
182 183 ${h.select('download_options',c.rhodecode_repo.get_changeset().raw_id,c.download_options)}
183 184 <span id="${'zip_link'}">${h.link_to(_('Download as zip'), h.url('files_archive_home',repo_name=c.dbrepo.repo_name,fname='tip.zip'),class_="archive_icon ui-btn")}</span>
184 185 <span style="vertical-align: bottom">
185 186 <input id="archive_subrepos" type="checkbox" name="subrepos" />
186 187 <label for="archive_subrepos" class="tooltip" title="${h.tooltip(_('Check this to download archive with subrepos'))}" >${_('with subrepos')}</label>
187 188 </span>
188 189 %endif
189 190 </div>
190 191 </div>
191 192 </div>
192 193 </div>
193 194 </div>
194 195
195 196 %if c.show_stats:
196 197 <div class="box box-right" style="min-height:455px">
197 198 <!-- box / title -->
198 199 <div class="title">
199 200 <h5>${_('Commit activity by day / author')}</h5>
200 201 </div>
201 202
202 203 <div class="graph">
203 204 <div style="padding:0 10px 10px 17px;">
204 205 %if c.no_data:
205 206 ${c.no_data_msg}
206 207 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
207 208 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
208 209 %endif
209 210 %else:
210 211 ${_('Stats gathered: ')} ${c.stats_percentage}%
211 212 %endif
212 213 </div>
213 214 <div id="commit_history" style="width:450px;height:300px;float:left"></div>
214 215 <div style="clear: both;height: 10px"></div>
215 216 <div id="overview" style="width:450px;height:100px;float:left"></div>
216 217
217 218 <div id="legend_data" style="clear:both;margin-top:10px;">
218 219 <div id="legend_container"></div>
219 220 <div id="legend_choices">
220 221 <table id="legend_choices_tables" class="noborder" style="font-size:smaller;color:#545454"></table>
221 222 </div>
222 223 </div>
223 224 </div>
224 225 </div>
225 226 %endif
226 227
227 228 <div class="box">
228 229 <div class="title">
229 230 <div class="breadcrumbs">
230 231 %if c.repo_changesets:
231 232 ${h.link_to(_('Latest changes'),h.url('changelog_home',repo_name=c.repo_name))}
232 233 %else:
233 234 ${_('Quick start')}
234 235 %endif
235 236 </div>
236 237 </div>
237 238 <div class="table">
238 239 <div id="shortlog_data">
239 240 <%include file='../shortlog/shortlog_data.html'/>
240 241 </div>
241 242 </div>
242 243 </div>
243 244
244 245 %if c.readme_data:
245 246 <div id="readme" class="anchor">
246 247 <div class="box" style="background-color: #FAFAFA">
247 248 <div class="title" title="${_("Readme file at revision '%s'" % c.rhodecode_db_repo.landing_rev)}">
248 249 <div class="breadcrumbs">
249 250 <a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a>
250 251 <a class="permalink" href="#readme" title="${_('Permalink to this readme')}">&para;</a>
251 252 </div>
252 253 </div>
253 254 <div class="readme">
254 255 <div class="readme_box">
255 256 ${c.readme_data|n}
256 257 </div>
257 258 </div>
258 259 </div>
259 260 </div>
260 261 %endif
261 262
262 263 <script type="text/javascript">
263 264 var clone_url = 'clone_url';
264 265 YUE.on(clone_url,'click',function(e){
265 266 if(YUD.hasClass(clone_url,'selected')){
266 267 return
267 268 }
268 269 else{
269 270 YUD.addClass(clone_url,'selected');
270 271 YUD.get(clone_url).select();
271 272 }
272 273 })
273 274
274 275 YUE.on('clone_by_name','click',function(e){
275 276 // show url by name and hide name button
276 277 YUD.setStyle('clone_url','display','');
277 278 YUD.setStyle('clone_by_name','display','none');
278 279
279 280 // hide url by id and show name button
280 281 YUD.setStyle('clone_by_id','display','');
281 282 YUD.setStyle('clone_url_id','display','none');
282 283
283 284 })
284 285 YUE.on('clone_by_id','click',function(e){
285 286
286 287 // show url by id and hide id button
287 288 YUD.setStyle('clone_by_id','display','none');
288 289 YUD.setStyle('clone_url_id','display','');
289 290
290 291 // hide url by name and show id button
291 292 YUD.setStyle('clone_by_name','display','');
292 293 YUD.setStyle('clone_url','display','none');
293 294 })
294 295
295 296
296 297 var tmpl_links = {};
297 298 %for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
298 299 tmpl_links["${archive['type']}"] = '${h.link_to('__NAME__', h.url('files_archive_home',repo_name=c.dbrepo.repo_name, fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_='archive_icon ui-btn')}';
299 300 %endfor
300 301
301 302 YUE.on(['download_options','archive_subrepos'],'change',function(e){
302 303 var sm = YUD.get('download_options');
303 304 var new_cs = sm.options[sm.selectedIndex];
304 305
305 306 for(k in tmpl_links){
306 307 var s = YUD.get(k+'_link');
307 308 if(s){
308 309 var title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}";
309 310 title_tmpl= title_tmpl.replace('__CS_NAME__',new_cs.text);
310 311 title_tmpl = title_tmpl.replace('__CS_EXT__',k);
311 312
312 313 var url = tmpl_links[k].replace('__CS__',new_cs.value);
313 314 var subrepos = YUD.get('archive_subrepos').checked;
314 315 url = url.replace('__SUB__',subrepos);
315 316 url = url.replace('__NAME__',title_tmpl);
316 317 s.innerHTML = url
317 318 }
318 319 }
319 320 });
320 321 </script>
321 322 %if c.show_stats:
322 323 <script type="text/javascript">
323 324 var data = ${c.trending_languages|n};
324 325 var total = 0;
325 326 var no_data = true;
326 327 var tbl = document.createElement('table');
327 328 tbl.setAttribute('class','trending_language_tbl');
328 329 var cnt = 0;
329 330 for (var i=0;i<data.length;i++){
330 331 total+= data[i][1].count;
331 332 }
332 333 for (var i=0;i<data.length;i++){
333 334 cnt += 1;
334 335 no_data = false;
335 336
336 337 var hide = cnt>2;
337 338 var tr = document.createElement('tr');
338 339 if (hide){
339 340 tr.setAttribute('style','display:none');
340 341 tr.setAttribute('class','stats_hidden');
341 342 }
342 343 var k = data[i][0];
343 344 var obj = data[i][1];
344 345 var percentage = Math.round((obj.count/total*100),2);
345 346
346 347 var td1 = document.createElement('td');
347 348 td1.width = 150;
348 349 var trending_language_label = document.createElement('div');
349 350 trending_language_label.innerHTML = obj.desc+" ("+k+")";
350 351 td1.appendChild(trending_language_label);
351 352
352 353 var td2 = document.createElement('td');
353 354 td2.setAttribute('style','padding-right:14px !important');
354 355 var trending_language = document.createElement('div');
355 356 var nr_files = obj.count+" ${_('files')}";
356 357
357 358 trending_language.title = k+" "+nr_files;
358 359
359 360 if (percentage>22){
360 361 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
361 362 }
362 363 else{
363 364 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
364 365 }
365 366
366 367 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
367 368 trending_language.style.width=percentage+"%";
368 369 td2.appendChild(trending_language);
369 370
370 371 tr.appendChild(td1);
371 372 tr.appendChild(td2);
372 373 tbl.appendChild(tr);
373 374 if(cnt == 3){
374 375 var show_more = document.createElement('tr');
375 376 var td = document.createElement('td');
376 377 lnk = document.createElement('a');
377 378
378 379 lnk.href='#';
379 380 lnk.innerHTML = "${_('show more')}";
380 381 lnk.id='code_stats_show_more';
381 382 td.appendChild(lnk);
382 383
383 384 show_more.appendChild(td);
384 385 show_more.appendChild(document.createElement('td'));
385 386 tbl.appendChild(show_more);
386 387 }
387 388
388 389 }
389 390
390 391 YUD.get('lang_stats').appendChild(tbl);
391 392 YUE.on('code_stats_show_more','click',function(){
392 393 l = YUD.getElementsByClassName('stats_hidden')
393 394 for (e in l){
394 395 YUD.setStyle(l[e],'display','');
395 396 };
396 397 YUD.setStyle(YUD.get('code_stats_show_more'),
397 398 'display','none');
398 399 });
399 400 </script>
400 401 <script type="text/javascript">
401 402 /**
402 403 * Plots summary graph
403 404 *
404 405 * @class SummaryPlot
405 406 * @param {from} initial from for detailed graph
406 407 * @param {to} initial to for detailed graph
407 408 * @param {dataset}
408 409 * @param {overview_dataset}
409 410 */
410 411 function SummaryPlot(from,to,dataset,overview_dataset) {
411 412 var initial_ranges = {
412 413 "xaxis":{
413 414 "from":from,
414 415 "to":to,
415 416 },
416 417 };
417 418 var dataset = dataset;
418 419 var overview_dataset = [overview_dataset];
419 420 var choiceContainer = YUD.get("legend_choices");
420 421 var choiceContainerTable = YUD.get("legend_choices_tables");
421 422 var plotContainer = YUD.get('commit_history');
422 423 var overviewContainer = YUD.get('overview');
423 424
424 425 var plot_options = {
425 426 bars: {show:true,align:'center',lineWidth:4},
426 427 legend: {show:true, container:"legend_container"},
427 428 points: {show:true,radius:0,fill:false},
428 429 yaxis: {tickDecimals:0,},
429 430 xaxis: {
430 431 mode: "time",
431 432 timeformat: "%d/%m",
432 433 min:from,
433 434 max:to,
434 435 },
435 436 grid: {
436 437 hoverable: true,
437 438 clickable: true,
438 439 autoHighlight:true,
439 440 color: "#999"
440 441 },
441 442 //selection: {mode: "x"}
442 443 };
443 444 var overview_options = {
444 445 legend:{show:false},
445 446 bars: {show:true,barWidth: 2,},
446 447 shadowSize: 0,
447 448 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
448 449 yaxis: {ticks: 3, min: 0,tickDecimals:0,},
449 450 grid: {color: "#999",},
450 451 selection: {mode: "x"}
451 452 };
452 453
453 454 /**
454 455 *get dummy data needed in few places
455 456 */
456 457 function getDummyData(label){
457 458 return {"label":label,
458 459 "data":[{"time":0,
459 460 "commits":0,
460 461 "added":0,
461 462 "changed":0,
462 463 "removed":0,
463 464 }],
464 465 "schema":["commits"],
465 466 "color":'#ffffff',
466 467 }
467 468 }
468 469
469 470 /**
470 471 * generate checkboxes accordindly to data
471 472 * @param keys
472 473 * @returns
473 474 */
474 475 function generateCheckboxes(data) {
475 476 //append checkboxes
476 477 var i = 0;
477 478 choiceContainerTable.innerHTML = '';
478 479 for(var pos in data) {
479 480
480 481 data[pos].color = i;
481 482 i++;
482 483 if(data[pos].label != ''){
483 484 choiceContainerTable.innerHTML +=
484 485 '<tr><td><input type="checkbox" id="id_user_{0}" name="{0}" checked="checked" /> \
485 486 <label for="id_user_{0}">{0}</label></td></tr>'.format(data[pos].label);
486 487 }
487 488 }
488 489 }
489 490
490 491 /**
491 492 * ToolTip show
492 493 */
493 494 function showTooltip(x, y, contents) {
494 495 var div=document.getElementById('tooltip');
495 496 if(!div) {
496 497 div = document.createElement('div');
497 498 div.id="tooltip";
498 499 div.style.position="absolute";
499 500 div.style.border='1px solid #fdd';
500 501 div.style.padding='2px';
501 502 div.style.backgroundColor='#fee';
502 503 document.body.appendChild(div);
503 504 }
504 505 YUD.setStyle(div, 'opacity', 0);
505 506 div.innerHTML = contents;
506 507 div.style.top=(y + 5) + "px";
507 508 div.style.left=(x + 5) + "px";
508 509
509 510 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
510 511 anim.animate();
511 512 }
512 513
513 514 /**
514 515 * This function will detect if selected period has some changesets
515 516 for this user if it does this data is then pushed for displaying
516 517 Additionally it will only display users that are selected by the checkbox
517 518 */
518 519 function getDataAccordingToRanges(ranges) {
519 520
520 521 var data = [];
521 522 var new_dataset = {};
522 523 var keys = [];
523 524 var max_commits = 0;
524 525 for(var key in dataset){
525 526
526 527 for(var ds in dataset[key].data){
527 528 commit_data = dataset[key].data[ds];
528 529 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
529 530
530 531 if(new_dataset[key] === undefined){
531 532 new_dataset[key] = {data:[],schema:["commits"],label:key};
532 533 }
533 534 new_dataset[key].data.push(commit_data);
534 535 }
535 536 }
536 537 if (new_dataset[key] !== undefined){
537 538 data.push(new_dataset[key]);
538 539 }
539 540 }
540 541
541 542 if (data.length > 0){
542 543 return data;
543 544 }
544 545 else{
545 546 //just return dummy data for graph to plot itself
546 547 return [getDummyData('')];
547 548 }
548 549 }
549 550
550 551 /**
551 552 * redraw using new checkbox data
552 553 */
553 554 function plotchoiced(e,args){
554 555 var cur_data = args[0];
555 556 var cur_ranges = args[1];
556 557
557 558 var new_data = [];
558 559 var inputs = choiceContainer.getElementsByTagName("input");
559 560
560 561 //show only checked labels
561 562 for(var i=0; i<inputs.length; i++) {
562 563 var checkbox_key = inputs[i].name;
563 564
564 565 if(inputs[i].checked){
565 566 for(var d in cur_data){
566 567 if(cur_data[d].label == checkbox_key){
567 568 new_data.push(cur_data[d]);
568 569 }
569 570 }
570 571 }
571 572 else{
572 573 //push dummy data to not hide the label
573 574 new_data.push(getDummyData(checkbox_key));
574 575 }
575 576 }
576 577
577 578 var new_options = YAHOO.lang.merge(plot_options, {
578 579 xaxis: {
579 580 min: cur_ranges.xaxis.from,
580 581 max: cur_ranges.xaxis.to,
581 582 mode:"time",
582 583 timeformat: "%d/%m",
583 584 },
584 585 });
585 586 if (!new_data){
586 587 new_data = [[0,1]];
587 588 }
588 589 // do the zooming
589 590 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
590 591
591 592 plot.subscribe("plotselected", plotselected);
592 593
593 594 //resubscribe plothover
594 595 plot.subscribe("plothover", plothover);
595 596
596 597 // don't fire event on the overview to prevent eternal loop
597 598 overview.setSelection(cur_ranges, true);
598 599
599 600 }
600 601
601 602 /**
602 603 * plot only selected items from overview
603 604 * @param ranges
604 605 * @returns
605 606 */
606 607 function plotselected(ranges,cur_data) {
607 608 //updates the data for new plot
608 609 var data = getDataAccordingToRanges(ranges);
609 610 generateCheckboxes(data);
610 611
611 612 var new_options = YAHOO.lang.merge(plot_options, {
612 613 xaxis: {
613 614 min: ranges.xaxis.from,
614 615 max: ranges.xaxis.to,
615 616 mode:"time",
616 617 timeformat: "%d/%m",
617 618 },
618 619 });
619 620 // do the zooming
620 621 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
621 622
622 623 plot.subscribe("plotselected", plotselected);
623 624
624 625 //resubscribe plothover
625 626 plot.subscribe("plothover", plothover);
626 627
627 628 // don't fire event on the overview to prevent eternal loop
628 629 overview.setSelection(ranges, true);
629 630
630 631 //resubscribe choiced
631 632 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
632 633 }
633 634
634 635 var previousPoint = null;
635 636
636 637 function plothover(o) {
637 638 var pos = o.pos;
638 639 var item = o.item;
639 640
640 641 //YUD.get("x").innerHTML = pos.x.toFixed(2);
641 642 //YUD.get("y").innerHTML = pos.y.toFixed(2);
642 643 if (item) {
643 644 if (previousPoint != item.datapoint) {
644 645 previousPoint = item.datapoint;
645 646
646 647 var tooltip = YUD.get("tooltip");
647 648 if(tooltip) {
648 649 tooltip.parentNode.removeChild(tooltip);
649 650 }
650 651 var x = item.datapoint.x.toFixed(2);
651 652 var y = item.datapoint.y.toFixed(2);
652 653
653 654 if (!item.series.label){
654 655 item.series.label = 'commits';
655 656 }
656 657 var d = new Date(x*1000);
657 658 var fd = d.toDateString()
658 659 var nr_commits = parseInt(y);
659 660
660 661 var cur_data = dataset[item.series.label].data[item.dataIndex];
661 662 var added = cur_data.added;
662 663 var changed = cur_data.changed;
663 664 var removed = cur_data.removed;
664 665
665 666 var nr_commits_suffix = " ${_('commits')} ";
666 667 var added_suffix = " ${_('files added')} ";
667 668 var changed_suffix = " ${_('files changed')} ";
668 669 var removed_suffix = " ${_('files removed')} ";
669 670
670 671
671 672 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
672 673 if(added==1){added_suffix=" ${_('file added')} ";}
673 674 if(changed==1){changed_suffix=" ${_('file changed')} ";}
674 675 if(removed==1){removed_suffix=" ${_('file removed')} ";}
675 676
676 677 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
677 678 +'<br/>'+
678 679 nr_commits + nr_commits_suffix+'<br/>'+
679 680 added + added_suffix +'<br/>'+
680 681 changed + changed_suffix + '<br/>'+
681 682 removed + removed_suffix + '<br/>');
682 683 }
683 684 }
684 685 else {
685 686 var tooltip = YUD.get("tooltip");
686 687
687 688 if(tooltip) {
688 689 tooltip.parentNode.removeChild(tooltip);
689 690 }
690 691 previousPoint = null;
691 692 }
692 693 }
693 694
694 695 /**
695 696 * MAIN EXECUTION
696 697 */
697 698
698 699 var data = getDataAccordingToRanges(initial_ranges);
699 700 generateCheckboxes(data);
700 701
701 702 //main plot
702 703 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
703 704
704 705 //overview
705 706 var overview = YAHOO.widget.Flot(overviewContainer,
706 707 overview_dataset, overview_options);
707 708
708 709 //show initial selection on overview
709 710 overview.setSelection(initial_ranges);
710 711
711 712 plot.subscribe("plotselected", plotselected);
712 713 plot.subscribe("plothover", plothover)
713 714
714 715 overview.subscribe("plotselected", function (ranges) {
715 716 plot.setSelection(ranges);
716 717 });
717 718
718 719 // user choices on overview
719 720 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
720 721 }
721 722 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
722 723 </script>
723 724 %endif
724 725
725 726 </%def>
General Comments 0
You need to be logged in to leave comments. Login now