##// END OF EJS Templates
Unified the paginators for pylons and YUI....
marcink -
r3776:13241a40 beta
parent child Browse files
Show More
@@ -1,149 +1,149 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.admin
3 rhodecode.controllers.admin.admin
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Controller for Admin panel of Rhodecode
6 Controller for Admin panel of Rhodecode
7
7
8 :created_on: Apr 7, 2010
8 :created_on: Apr 7, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27
27
28 from pylons import request, tmpl_context as c, url
28 from pylons import request, tmpl_context as c, url
29 from sqlalchemy.orm import joinedload
29 from sqlalchemy.orm import joinedload
30 from webhelpers.paginate import Page
31 from whoosh.qparser.default import QueryParser
30 from whoosh.qparser.default import QueryParser
31 from whoosh.qparser.dateparse import DateParserPlugin
32 from whoosh import query
32 from whoosh import query
33 from sqlalchemy.sql.expression import or_, and_, func
33 from sqlalchemy.sql.expression import or_, and_, func
34
34
35 from rhodecode.model.db import UserLog, User
35 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
36 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
36 from rhodecode.lib.base import BaseController, render
37 from rhodecode.lib.base import BaseController, render
37 from rhodecode.model.db import UserLog, User
38 from rhodecode.lib.utils2 import safe_int, remove_prefix, remove_suffix
38 from rhodecode.lib.utils2 import safe_int, remove_prefix, remove_suffix
39 from rhodecode.lib.indexers import JOURNAL_SCHEMA
39 from rhodecode.lib.indexers import JOURNAL_SCHEMA
40 from whoosh.qparser.dateparse import DateParserPlugin
40 from rhodecode.lib.helpers import Page
41
41
42
42
43 log = logging.getLogger(__name__)
43 log = logging.getLogger(__name__)
44
44
45
45
46 def _journal_filter(user_log, search_term):
46 def _journal_filter(user_log, search_term):
47 """
47 """
48 Filters sqlalchemy user_log based on search_term with whoosh Query language
48 Filters sqlalchemy user_log based on search_term with whoosh Query language
49 http://packages.python.org/Whoosh/querylang.html
49 http://packages.python.org/Whoosh/querylang.html
50
50
51 :param user_log:
51 :param user_log:
52 :param search_term:
52 :param search_term:
53 """
53 """
54 log.debug('Initial search term: %r' % search_term)
54 log.debug('Initial search term: %r' % search_term)
55 qry = None
55 qry = None
56 if search_term:
56 if search_term:
57 qp = QueryParser('repository', schema=JOURNAL_SCHEMA)
57 qp = QueryParser('repository', schema=JOURNAL_SCHEMA)
58 qp.add_plugin(DateParserPlugin())
58 qp.add_plugin(DateParserPlugin())
59 qry = qp.parse(unicode(search_term))
59 qry = qp.parse(unicode(search_term))
60 log.debug('Filtering using parsed query %r' % qry)
60 log.debug('Filtering using parsed query %r' % qry)
61
61
62 def wildcard_handler(col, wc_term):
62 def wildcard_handler(col, wc_term):
63 if wc_term.startswith('*') and not wc_term.endswith('*'):
63 if wc_term.startswith('*') and not wc_term.endswith('*'):
64 #postfix == endswith
64 #postfix == endswith
65 wc_term = remove_prefix(wc_term, prefix='*')
65 wc_term = remove_prefix(wc_term, prefix='*')
66 return func.lower(col).endswith(wc_term)
66 return func.lower(col).endswith(wc_term)
67 elif wc_term.startswith('*') and wc_term.endswith('*'):
67 elif wc_term.startswith('*') and wc_term.endswith('*'):
68 #wildcard == ilike
68 #wildcard == ilike
69 wc_term = remove_prefix(wc_term, prefix='*')
69 wc_term = remove_prefix(wc_term, prefix='*')
70 wc_term = remove_suffix(wc_term, suffix='*')
70 wc_term = remove_suffix(wc_term, suffix='*')
71 return func.lower(col).contains(wc_term)
71 return func.lower(col).contains(wc_term)
72
72
73 def get_filterion(field, val, term):
73 def get_filterion(field, val, term):
74
74
75 if field == 'repository':
75 if field == 'repository':
76 field = getattr(UserLog, 'repository_name')
76 field = getattr(UserLog, 'repository_name')
77 elif field == 'ip':
77 elif field == 'ip':
78 field = getattr(UserLog, 'user_ip')
78 field = getattr(UserLog, 'user_ip')
79 elif field == 'date':
79 elif field == 'date':
80 field = getattr(UserLog, 'action_date')
80 field = getattr(UserLog, 'action_date')
81 elif field == 'username':
81 elif field == 'username':
82 field = getattr(UserLog, 'username')
82 field = getattr(UserLog, 'username')
83 else:
83 else:
84 field = getattr(UserLog, field)
84 field = getattr(UserLog, field)
85 log.debug('filter field: %s val=>%s' % (field, val))
85 log.debug('filter field: %s val=>%s' % (field, val))
86
86
87 #sql filtering
87 #sql filtering
88 if isinstance(term, query.Wildcard):
88 if isinstance(term, query.Wildcard):
89 return wildcard_handler(field, val)
89 return wildcard_handler(field, val)
90 elif isinstance(term, query.Prefix):
90 elif isinstance(term, query.Prefix):
91 return func.lower(field).startswith(func.lower(val))
91 return func.lower(field).startswith(func.lower(val))
92 elif isinstance(term, query.DateRange):
92 elif isinstance(term, query.DateRange):
93 return and_(field >= val[0], field <= val[1])
93 return and_(field >= val[0], field <= val[1])
94 return func.lower(field) == func.lower(val)
94 return func.lower(field) == func.lower(val)
95
95
96 if isinstance(qry, (query.And, query.Term, query.Prefix, query.Wildcard,
96 if isinstance(qry, (query.And, query.Term, query.Prefix, query.Wildcard,
97 query.DateRange)):
97 query.DateRange)):
98 if not isinstance(qry, query.And):
98 if not isinstance(qry, query.And):
99 qry = [qry]
99 qry = [qry]
100 for term in qry:
100 for term in qry:
101 field = term.fieldname
101 field = term.fieldname
102 val = (term.text if not isinstance(term, query.DateRange)
102 val = (term.text if not isinstance(term, query.DateRange)
103 else [term.startdate, term.enddate])
103 else [term.startdate, term.enddate])
104 user_log = user_log.filter(get_filterion(field, val, term))
104 user_log = user_log.filter(get_filterion(field, val, term))
105 elif isinstance(qry, query.Or):
105 elif isinstance(qry, query.Or):
106 filters = []
106 filters = []
107 for term in qry:
107 for term in qry:
108 field = term.fieldname
108 field = term.fieldname
109 val = (term.text if not isinstance(term, query.DateRange)
109 val = (term.text if not isinstance(term, query.DateRange)
110 else [term.startdate, term.enddate])
110 else [term.startdate, term.enddate])
111 filters.append(get_filterion(field, val, term))
111 filters.append(get_filterion(field, val, term))
112 user_log = user_log.filter(or_(*filters))
112 user_log = user_log.filter(or_(*filters))
113
113
114 return user_log
114 return user_log
115
115
116
116
117 class AdminController(BaseController):
117 class AdminController(BaseController):
118
118
119 @LoginRequired()
119 @LoginRequired()
120 def __before__(self):
120 def __before__(self):
121 super(AdminController, self).__before__()
121 super(AdminController, self).__before__()
122
122
123 @HasPermissionAllDecorator('hg.admin')
123 @HasPermissionAllDecorator('hg.admin')
124 def index(self):
124 def index(self):
125 users_log = UserLog.query()\
125 users_log = UserLog.query()\
126 .options(joinedload(UserLog.user))\
126 .options(joinedload(UserLog.user))\
127 .options(joinedload(UserLog.repository))
127 .options(joinedload(UserLog.repository))
128
128
129 #FILTERING
129 #FILTERING
130 c.search_term = request.GET.get('filter')
130 c.search_term = request.GET.get('filter')
131 try:
131 try:
132 users_log = _journal_filter(users_log, c.search_term)
132 users_log = _journal_filter(users_log, c.search_term)
133 except Exception:
133 except Exception:
134 # we want this to crash for now
134 # we want this to crash for now
135 raise
135 raise
136
136
137 users_log = users_log.order_by(UserLog.action_date.desc())
137 users_log = users_log.order_by(UserLog.action_date.desc())
138
138
139 p = safe_int(request.GET.get('page', 1), 1)
139 p = safe_int(request.GET.get('page', 1), 1)
140
140
141 def url_generator(**kw):
141 def url_generator(**kw):
142 return url.current(filter=c.search_term, **kw)
142 return url.current(filter=c.search_term, **kw)
143
143
144 c.users_log = Page(users_log, page=p, items_per_page=10, url=url_generator)
144 c.users_log = Page(users_log, page=p, items_per_page=10, url=url_generator)
145 c.log_data = render('admin/admin_log.html')
145 c.log_data = render('admin/admin_log.html')
146
146
147 if request.environ.get('HTTP_X_PARTIAL_XHR'):
147 if request.environ.get('HTTP_X_PARTIAL_XHR'):
148 return c.log_data
148 return c.log_data
149 return render('admin/admin.html')
149 return render('admin/admin.html')
@@ -1,173 +1,171 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.notifications
3 rhodecode.controllers.admin.notifications
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 notifications controller for RhodeCode
6 notifications controller for RhodeCode
7
7
8 :created_on: Nov 23, 2010
8 :created_on: Nov 23, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from pylons import request
29 from pylons import request
30 from pylons import tmpl_context as c, url
30 from pylons import tmpl_context as c, url
31 from pylons.controllers.util import redirect, abort
31 from pylons.controllers.util import redirect, abort
32
32
33 from webhelpers.paginate import Page
33 from rhodecode.model.db import Notification
34
34 from rhodecode.model.notification import NotificationModel
35 from rhodecode.model.meta import Session
36 from rhodecode.lib.auth import LoginRequired, NotAnonymous
35 from rhodecode.lib.base import BaseController, render
37 from rhodecode.lib.base import BaseController, render
36 from rhodecode.model.db import Notification
37
38 from rhodecode.model.notification import NotificationModel
39 from rhodecode.lib.auth import LoginRequired, NotAnonymous
40 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
41 from rhodecode.model.meta import Session
39 from rhodecode.lib.helpers import Page
42 from rhodecode.lib.utils2 import safe_int
40 from rhodecode.lib.utils2 import safe_int
43
41
44
42
45 log = logging.getLogger(__name__)
43 log = logging.getLogger(__name__)
46
44
47
45
48 class NotificationsController(BaseController):
46 class NotificationsController(BaseController):
49 """REST Controller styled on the Atom Publishing Protocol"""
47 """REST Controller styled on the Atom Publishing Protocol"""
50 # To properly map this controller, ensure your config/routing.py
48 # To properly map this controller, ensure your config/routing.py
51 # file has a resource setup:
49 # file has a resource setup:
52 # map.resource('notification', 'notifications', controller='_admin/notifications',
50 # map.resource('notification', 'notifications', controller='_admin/notifications',
53 # path_prefix='/_admin', name_prefix='_admin_')
51 # path_prefix='/_admin', name_prefix='_admin_')
54
52
55 @LoginRequired()
53 @LoginRequired()
56 @NotAnonymous()
54 @NotAnonymous()
57 def __before__(self):
55 def __before__(self):
58 super(NotificationsController, self).__before__()
56 super(NotificationsController, self).__before__()
59
57
60 def index(self, format='html'):
58 def index(self, format='html'):
61 """GET /_admin/notifications: All items in the collection"""
59 """GET /_admin/notifications: All items in the collection"""
62 # url('notifications')
60 # url('notifications')
63 c.user = self.rhodecode_user
61 c.user = self.rhodecode_user
64 notif = NotificationModel().get_for_user(self.rhodecode_user.user_id,
62 notif = NotificationModel().get_for_user(self.rhodecode_user.user_id,
65 filter_=request.GET.getall('type'))
63 filter_=request.GET.getall('type'))
66
64
67 p = safe_int(request.GET.get('page', 1), 1)
65 p = safe_int(request.GET.get('page', 1), 1)
68 c.notifications = Page(notif, page=p, items_per_page=10)
66 c.notifications = Page(notif, page=p, items_per_page=10)
69 c.pull_request_type = Notification.TYPE_PULL_REQUEST
67 c.pull_request_type = Notification.TYPE_PULL_REQUEST
70 c.comment_type = [Notification.TYPE_CHANGESET_COMMENT,
68 c.comment_type = [Notification.TYPE_CHANGESET_COMMENT,
71 Notification.TYPE_PULL_REQUEST_COMMENT]
69 Notification.TYPE_PULL_REQUEST_COMMENT]
72
70
73 _current_filter = request.GET.getall('type')
71 _current_filter = request.GET.getall('type')
74 c.current_filter = 'all'
72 c.current_filter = 'all'
75 if _current_filter == [c.pull_request_type]:
73 if _current_filter == [c.pull_request_type]:
76 c.current_filter = 'pull_request'
74 c.current_filter = 'pull_request'
77 elif _current_filter == c.comment_type:
75 elif _current_filter == c.comment_type:
78 c.current_filter = 'comment'
76 c.current_filter = 'comment'
79
77
80 return render('admin/notifications/notifications.html')
78 return render('admin/notifications/notifications.html')
81
79
82 def mark_all_read(self):
80 def mark_all_read(self):
83 if request.environ.get('HTTP_X_PARTIAL_XHR'):
81 if request.environ.get('HTTP_X_PARTIAL_XHR'):
84 nm = NotificationModel()
82 nm = NotificationModel()
85 # mark all read
83 # mark all read
86 nm.mark_all_read_for_user(self.rhodecode_user.user_id,
84 nm.mark_all_read_for_user(self.rhodecode_user.user_id,
87 filter_=request.GET.getall('type'))
85 filter_=request.GET.getall('type'))
88 Session().commit()
86 Session().commit()
89 c.user = self.rhodecode_user
87 c.user = self.rhodecode_user
90 notif = nm.get_for_user(self.rhodecode_user.user_id,
88 notif = nm.get_for_user(self.rhodecode_user.user_id,
91 filter_=request.GET.getall('type'))
89 filter_=request.GET.getall('type'))
92 c.notifications = Page(notif, page=1, items_per_page=10)
90 c.notifications = Page(notif, page=1, items_per_page=10)
93 return render('admin/notifications/notifications_data.html')
91 return render('admin/notifications/notifications_data.html')
94
92
95 def create(self):
93 def create(self):
96 """POST /_admin/notifications: Create a new item"""
94 """POST /_admin/notifications: Create a new item"""
97 # url('notifications')
95 # url('notifications')
98
96
99 def new(self, format='html'):
97 def new(self, format='html'):
100 """GET /_admin/notifications/new: Form to create a new item"""
98 """GET /_admin/notifications/new: Form to create a new item"""
101 # url('new_notification')
99 # url('new_notification')
102
100
103 def update(self, notification_id):
101 def update(self, notification_id):
104 """PUT /_admin/notifications/id: Update an existing item"""
102 """PUT /_admin/notifications/id: Update an existing item"""
105 # Forms posted to this method should contain a hidden field:
103 # Forms posted to this method should contain a hidden field:
106 # <input type="hidden" name="_method" value="PUT" />
104 # <input type="hidden" name="_method" value="PUT" />
107 # Or using helpers:
105 # Or using helpers:
108 # h.form(url('notification', notification_id=ID),
106 # h.form(url('notification', notification_id=ID),
109 # method='put')
107 # method='put')
110 # url('notification', notification_id=ID)
108 # url('notification', notification_id=ID)
111 try:
109 try:
112 no = Notification.get(notification_id)
110 no = Notification.get(notification_id)
113 owner = all(un.user.user_id == c.rhodecode_user.user_id
111 owner = all(un.user.user_id == c.rhodecode_user.user_id
114 for un in no.notifications_to_users)
112 for un in no.notifications_to_users)
115 if h.HasPermissionAny('hg.admin')() or owner:
113 if h.HasPermissionAny('hg.admin')() or owner:
116 NotificationModel().mark_read(c.rhodecode_user.user_id, no)
114 NotificationModel().mark_read(c.rhodecode_user.user_id, no)
117 Session().commit()
115 Session().commit()
118 return 'ok'
116 return 'ok'
119 except Exception:
117 except Exception:
120 Session().rollback()
118 Session().rollback()
121 log.error(traceback.format_exc())
119 log.error(traceback.format_exc())
122 return 'fail'
120 return 'fail'
123
121
124 def delete(self, notification_id):
122 def delete(self, notification_id):
125 """DELETE /_admin/notifications/id: Delete an existing item"""
123 """DELETE /_admin/notifications/id: Delete an existing item"""
126 # Forms posted to this method should contain a hidden field:
124 # Forms posted to this method should contain a hidden field:
127 # <input type="hidden" name="_method" value="DELETE" />
125 # <input type="hidden" name="_method" value="DELETE" />
128 # Or using helpers:
126 # Or using helpers:
129 # h.form(url('notification', notification_id=ID),
127 # h.form(url('notification', notification_id=ID),
130 # method='delete')
128 # method='delete')
131 # url('notification', notification_id=ID)
129 # url('notification', notification_id=ID)
132
130
133 try:
131 try:
134 no = Notification.get(notification_id)
132 no = Notification.get(notification_id)
135 owner = all(un.user.user_id == c.rhodecode_user.user_id
133 owner = all(un.user.user_id == c.rhodecode_user.user_id
136 for un in no.notifications_to_users)
134 for un in no.notifications_to_users)
137 if h.HasPermissionAny('hg.admin')() or owner:
135 if h.HasPermissionAny('hg.admin')() or owner:
138 NotificationModel().delete(c.rhodecode_user.user_id, no)
136 NotificationModel().delete(c.rhodecode_user.user_id, no)
139 Session().commit()
137 Session().commit()
140 return 'ok'
138 return 'ok'
141 except Exception:
139 except Exception:
142 Session().rollback()
140 Session().rollback()
143 log.error(traceback.format_exc())
141 log.error(traceback.format_exc())
144 return 'fail'
142 return 'fail'
145
143
146 def show(self, notification_id, format='html'):
144 def show(self, notification_id, format='html'):
147 """GET /_admin/notifications/id: Show a specific item"""
145 """GET /_admin/notifications/id: Show a specific item"""
148 # url('notification', notification_id=ID)
146 # url('notification', notification_id=ID)
149 c.user = self.rhodecode_user
147 c.user = self.rhodecode_user
150 no = Notification.get(notification_id)
148 no = Notification.get(notification_id)
151
149
152 owner = any(un.user.user_id == c.rhodecode_user.user_id
150 owner = any(un.user.user_id == c.rhodecode_user.user_id
153 for un in no.notifications_to_users)
151 for un in no.notifications_to_users)
154
152
155 if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner):
153 if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner):
156 unotification = NotificationModel()\
154 unotification = NotificationModel()\
157 .get_user_notification(c.user.user_id, no)
155 .get_user_notification(c.user.user_id, no)
158
156
159 # if this association to user is not valid, we don't want to show
157 # if this association to user is not valid, we don't want to show
160 # this message
158 # this message
161 if unotification:
159 if unotification:
162 if not unotification.read:
160 if not unotification.read:
163 unotification.mark_as_read()
161 unotification.mark_as_read()
164 Session().commit()
162 Session().commit()
165 c.notification = no
163 c.notification = no
166
164
167 return render('admin/notifications/show_notification.html')
165 return render('admin/notifications/show_notification.html')
168
166
169 return abort(403)
167 return abort(403)
170
168
171 def edit(self, notification_id, format='html'):
169 def edit(self, notification_id, format='html'):
172 """GET /_admin/notifications/id/edit: Form to edit an existing item"""
170 """GET /_admin/notifications/id/edit: Form to edit an existing item"""
173 # url('edit_notification', notification_id=ID)
171 # url('edit_notification', notification_id=ID)
@@ -1,379 +1,379 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.journal
3 rhodecode.controllers.journal
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Journal controller for pylons
6 Journal controller for pylons
7
7
8 :created_on: Nov 21, 2010
8 :created_on: Nov 21, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import logging
25 import logging
26 from itertools import groupby
26 from itertools import groupby
27
27
28 from sqlalchemy import or_
28 from sqlalchemy import or_
29 from sqlalchemy.orm import joinedload
29 from sqlalchemy.orm import joinedload
30 from sqlalchemy.sql.expression import func
30 from sqlalchemy.sql.expression import func
31
31
32 from webhelpers.paginate import Page
33 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
32 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
34
33
35 from webob.exc import HTTPBadRequest
34 from webob.exc import HTTPBadRequest
36 from pylons import request, tmpl_context as c, response, url
35 from pylons import request, tmpl_context as c, response, url
37 from pylons.i18n.translation import _
36 from pylons.i18n.translation import _
38
37
38 from rhodecode.controllers.admin.admin import _journal_filter
39 from rhodecode.model.db import UserLog, UserFollowing, Repository, User
40 from rhodecode.model.meta import Session
41 from rhodecode.model.repo import RepoModel
39 import rhodecode.lib.helpers as h
42 import rhodecode.lib.helpers as h
43 from rhodecode.lib.helpers import Page
40 from rhodecode.lib.auth import LoginRequired, NotAnonymous
44 from rhodecode.lib.auth import LoginRequired, NotAnonymous
41 from rhodecode.lib.base import BaseController, render
45 from rhodecode.lib.base import BaseController, render
42 from rhodecode.model.db import UserLog, UserFollowing, Repository, User
43 from rhodecode.model.meta import Session
44 from rhodecode.lib.utils2 import safe_int, AttributeDict
46 from rhodecode.lib.utils2 import safe_int, AttributeDict
45 from rhodecode.controllers.admin.admin import _journal_filter
46 from rhodecode.model.repo import RepoModel
47 from rhodecode.lib.compat import json
47 from rhodecode.lib.compat import json
48
48
49 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
50
50
51
51
52 class JournalController(BaseController):
52 class JournalController(BaseController):
53
53
54 def __before__(self):
54 def __before__(self):
55 super(JournalController, self).__before__()
55 super(JournalController, self).__before__()
56 self.language = 'en-us'
56 self.language = 'en-us'
57 self.ttl = "5"
57 self.ttl = "5"
58 self.feed_nr = 20
58 self.feed_nr = 20
59 c.search_term = request.GET.get('filter')
59 c.search_term = request.GET.get('filter')
60
60
61 def _get_daily_aggregate(self, journal):
61 def _get_daily_aggregate(self, journal):
62 groups = []
62 groups = []
63 for k, g in groupby(journal, lambda x: x.action_as_day):
63 for k, g in groupby(journal, lambda x: x.action_as_day):
64 user_group = []
64 user_group = []
65 #groupby username if it's a present value, else fallback to journal username
65 #groupby username if it's a present value, else fallback to journal username
66 for _, g2 in groupby(list(g), lambda x: x.user.username if x.user else x.username):
66 for _, g2 in groupby(list(g), lambda x: x.user.username if x.user else x.username):
67 l = list(g2)
67 l = list(g2)
68 user_group.append((l[0].user, l))
68 user_group.append((l[0].user, l))
69
69
70 groups.append((k, user_group,))
70 groups.append((k, user_group,))
71
71
72 return groups
72 return groups
73
73
74 def _get_journal_data(self, following_repos):
74 def _get_journal_data(self, following_repos):
75 repo_ids = [x.follows_repository.repo_id for x in following_repos
75 repo_ids = [x.follows_repository.repo_id for x in following_repos
76 if x.follows_repository is not None]
76 if x.follows_repository is not None]
77 user_ids = [x.follows_user.user_id for x in following_repos
77 user_ids = [x.follows_user.user_id for x in following_repos
78 if x.follows_user is not None]
78 if x.follows_user is not None]
79
79
80 filtering_criterion = None
80 filtering_criterion = None
81
81
82 if repo_ids and user_ids:
82 if repo_ids and user_ids:
83 filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
83 filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
84 UserLog.user_id.in_(user_ids))
84 UserLog.user_id.in_(user_ids))
85 if repo_ids and not user_ids:
85 if repo_ids and not user_ids:
86 filtering_criterion = UserLog.repository_id.in_(repo_ids)
86 filtering_criterion = UserLog.repository_id.in_(repo_ids)
87 if not repo_ids and user_ids:
87 if not repo_ids and user_ids:
88 filtering_criterion = UserLog.user_id.in_(user_ids)
88 filtering_criterion = UserLog.user_id.in_(user_ids)
89 if filtering_criterion is not None:
89 if filtering_criterion is not None:
90 journal = self.sa.query(UserLog)\
90 journal = self.sa.query(UserLog)\
91 .options(joinedload(UserLog.user))\
91 .options(joinedload(UserLog.user))\
92 .options(joinedload(UserLog.repository))
92 .options(joinedload(UserLog.repository))
93 #filter
93 #filter
94 try:
94 try:
95 journal = _journal_filter(journal, c.search_term)
95 journal = _journal_filter(journal, c.search_term)
96 except Exception:
96 except Exception:
97 # we want this to crash for now
97 # we want this to crash for now
98 raise
98 raise
99 journal = journal.filter(filtering_criterion)\
99 journal = journal.filter(filtering_criterion)\
100 .order_by(UserLog.action_date.desc())
100 .order_by(UserLog.action_date.desc())
101 else:
101 else:
102 journal = []
102 journal = []
103
103
104 return journal
104 return journal
105
105
106 def _atom_feed(self, repos, public=True):
106 def _atom_feed(self, repos, public=True):
107 journal = self._get_journal_data(repos)
107 journal = self._get_journal_data(repos)
108 if public:
108 if public:
109 _link = url('public_journal_atom', qualified=True)
109 _link = url('public_journal_atom', qualified=True)
110 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
110 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
111 'atom feed')
111 'atom feed')
112 else:
112 else:
113 _link = url('journal_atom', qualified=True)
113 _link = url('journal_atom', qualified=True)
114 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'atom feed')
114 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'atom feed')
115
115
116 feed = Atom1Feed(title=_desc,
116 feed = Atom1Feed(title=_desc,
117 link=_link,
117 link=_link,
118 description=_desc,
118 description=_desc,
119 language=self.language,
119 language=self.language,
120 ttl=self.ttl)
120 ttl=self.ttl)
121
121
122 for entry in journal[:self.feed_nr]:
122 for entry in journal[:self.feed_nr]:
123 user = entry.user
123 user = entry.user
124 if user is None:
124 if user is None:
125 #fix deleted users
125 #fix deleted users
126 user = AttributeDict({'short_contact': entry.username,
126 user = AttributeDict({'short_contact': entry.username,
127 'email': '',
127 'email': '',
128 'full_contact': ''})
128 'full_contact': ''})
129 action, action_extra, ico = h.action_parser(entry, feed=True)
129 action, action_extra, ico = h.action_parser(entry, feed=True)
130 title = "%s - %s %s" % (user.short_contact, action(),
130 title = "%s - %s %s" % (user.short_contact, action(),
131 entry.repository.repo_name)
131 entry.repository.repo_name)
132 desc = action_extra()
132 desc = action_extra()
133 _url = None
133 _url = None
134 if entry.repository is not None:
134 if entry.repository is not None:
135 _url = url('changelog_home',
135 _url = url('changelog_home',
136 repo_name=entry.repository.repo_name,
136 repo_name=entry.repository.repo_name,
137 qualified=True)
137 qualified=True)
138
138
139 feed.add_item(title=title,
139 feed.add_item(title=title,
140 pubdate=entry.action_date,
140 pubdate=entry.action_date,
141 link=_url or url('', qualified=True),
141 link=_url or url('', qualified=True),
142 author_email=user.email,
142 author_email=user.email,
143 author_name=user.full_contact,
143 author_name=user.full_contact,
144 description=desc)
144 description=desc)
145
145
146 response.content_type = feed.mime_type
146 response.content_type = feed.mime_type
147 return feed.writeString('utf-8')
147 return feed.writeString('utf-8')
148
148
149 def _rss_feed(self, repos, public=True):
149 def _rss_feed(self, repos, public=True):
150 journal = self._get_journal_data(repos)
150 journal = self._get_journal_data(repos)
151 if public:
151 if public:
152 _link = url('public_journal_atom', qualified=True)
152 _link = url('public_journal_atom', qualified=True)
153 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
153 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
154 'rss feed')
154 'rss feed')
155 else:
155 else:
156 _link = url('journal_atom', qualified=True)
156 _link = url('journal_atom', qualified=True)
157 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'rss feed')
157 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'rss feed')
158
158
159 feed = Rss201rev2Feed(title=_desc,
159 feed = Rss201rev2Feed(title=_desc,
160 link=_link,
160 link=_link,
161 description=_desc,
161 description=_desc,
162 language=self.language,
162 language=self.language,
163 ttl=self.ttl)
163 ttl=self.ttl)
164
164
165 for entry in journal[:self.feed_nr]:
165 for entry in journal[:self.feed_nr]:
166 user = entry.user
166 user = entry.user
167 if user is None:
167 if user is None:
168 #fix deleted users
168 #fix deleted users
169 user = AttributeDict({'short_contact': entry.username,
169 user = AttributeDict({'short_contact': entry.username,
170 'email': '',
170 'email': '',
171 'full_contact': ''})
171 'full_contact': ''})
172 action, action_extra, ico = h.action_parser(entry, feed=True)
172 action, action_extra, ico = h.action_parser(entry, feed=True)
173 title = "%s - %s %s" % (user.short_contact, action(),
173 title = "%s - %s %s" % (user.short_contact, action(),
174 entry.repository.repo_name)
174 entry.repository.repo_name)
175 desc = action_extra()
175 desc = action_extra()
176 _url = None
176 _url = None
177 if entry.repository is not None:
177 if entry.repository is not None:
178 _url = url('changelog_home',
178 _url = url('changelog_home',
179 repo_name=entry.repository.repo_name,
179 repo_name=entry.repository.repo_name,
180 qualified=True)
180 qualified=True)
181
181
182 feed.add_item(title=title,
182 feed.add_item(title=title,
183 pubdate=entry.action_date,
183 pubdate=entry.action_date,
184 link=_url or url('', qualified=True),
184 link=_url or url('', qualified=True),
185 author_email=user.email,
185 author_email=user.email,
186 author_name=user.full_contact,
186 author_name=user.full_contact,
187 description=desc)
187 description=desc)
188
188
189 response.content_type = feed.mime_type
189 response.content_type = feed.mime_type
190 return feed.writeString('utf-8')
190 return feed.writeString('utf-8')
191
191
192 @LoginRequired()
192 @LoginRequired()
193 @NotAnonymous()
193 @NotAnonymous()
194 def index(self):
194 def index(self):
195 # Return a rendered template
195 # Return a rendered template
196 p = safe_int(request.GET.get('page', 1), 1)
196 p = safe_int(request.GET.get('page', 1), 1)
197 c.user = User.get(self.rhodecode_user.user_id)
197 c.user = User.get(self.rhodecode_user.user_id)
198 c.following = self.sa.query(UserFollowing)\
198 c.following = self.sa.query(UserFollowing)\
199 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
199 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
200 .options(joinedload(UserFollowing.follows_repository))\
200 .options(joinedload(UserFollowing.follows_repository))\
201 .all()
201 .all()
202
202
203 journal = self._get_journal_data(c.following)
203 journal = self._get_journal_data(c.following)
204
204
205 def url_generator(**kw):
205 def url_generator(**kw):
206 return url.current(filter=c.search_term, **kw)
206 return url.current(filter=c.search_term, **kw)
207
207
208 c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
208 c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
209 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
209 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
210
210
211 c.journal_data = render('journal/journal_data.html')
211 c.journal_data = render('journal/journal_data.html')
212 if request.environ.get('HTTP_X_PARTIAL_XHR'):
212 if request.environ.get('HTTP_X_PARTIAL_XHR'):
213 return c.journal_data
213 return c.journal_data
214
214
215 repos_list = Session().query(Repository)\
215 repos_list = Session().query(Repository)\
216 .filter(Repository.user_id ==
216 .filter(Repository.user_id ==
217 self.rhodecode_user.user_id)\
217 self.rhodecode_user.user_id)\
218 .order_by(func.lower(Repository.repo_name)).all()
218 .order_by(func.lower(Repository.repo_name)).all()
219
219
220 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
220 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
221 admin=True)
221 admin=True)
222 #json used to render the grid
222 #json used to render the grid
223 c.data = json.dumps(repos_data)
223 c.data = json.dumps(repos_data)
224
224
225 watched_repos_data = []
225 watched_repos_data = []
226
226
227 ## watched repos
227 ## watched repos
228 _render = RepoModel._render_datatable
228 _render = RepoModel._render_datatable
229
229
230 def quick_menu(repo_name):
230 def quick_menu(repo_name):
231 return _render('quick_menu', repo_name)
231 return _render('quick_menu', repo_name)
232
232
233 def repo_lnk(name, rtype, private, fork_of):
233 def repo_lnk(name, rtype, private, fork_of):
234 return _render('repo_name', name, rtype, private, fork_of,
234 return _render('repo_name', name, rtype, private, fork_of,
235 short_name=False, admin=False)
235 short_name=False, admin=False)
236
236
237 def last_rev(repo_name, cs_cache):
237 def last_rev(repo_name, cs_cache):
238 return _render('revision', repo_name, cs_cache.get('revision'),
238 return _render('revision', repo_name, cs_cache.get('revision'),
239 cs_cache.get('raw_id'), cs_cache.get('author'),
239 cs_cache.get('raw_id'), cs_cache.get('author'),
240 cs_cache.get('message'))
240 cs_cache.get('message'))
241
241
242 def desc(desc):
242 def desc(desc):
243 from pylons import tmpl_context as c
243 from pylons import tmpl_context as c
244 if c.visual.stylify_metatags:
244 if c.visual.stylify_metatags:
245 return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
245 return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
246 else:
246 else:
247 return h.urlify_text(h.truncate(desc, 60))
247 return h.urlify_text(h.truncate(desc, 60))
248
248
249 def repo_actions(repo_name):
249 def repo_actions(repo_name):
250 return _render('repo_actions', repo_name)
250 return _render('repo_actions', repo_name)
251
251
252 def owner_actions(user_id, username):
252 def owner_actions(user_id, username):
253 return _render('user_name', user_id, username)
253 return _render('user_name', user_id, username)
254
254
255 def toogle_follow(repo_id):
255 def toogle_follow(repo_id):
256 return _render('toggle_follow', repo_id)
256 return _render('toggle_follow', repo_id)
257
257
258 for entry in c.following:
258 for entry in c.following:
259 repo = entry.follows_repository
259 repo = entry.follows_repository
260 cs_cache = repo.changeset_cache
260 cs_cache = repo.changeset_cache
261 row = {
261 row = {
262 "menu": quick_menu(repo.repo_name),
262 "menu": quick_menu(repo.repo_name),
263 "raw_name": repo.repo_name.lower(),
263 "raw_name": repo.repo_name.lower(),
264 "name": repo_lnk(repo.repo_name, repo.repo_type,
264 "name": repo_lnk(repo.repo_name, repo.repo_type,
265 repo.private, repo.fork),
265 repo.private, repo.fork),
266 "last_changeset": last_rev(repo.repo_name, cs_cache),
266 "last_changeset": last_rev(repo.repo_name, cs_cache),
267 "raw_tip": cs_cache.get('revision'),
267 "raw_tip": cs_cache.get('revision'),
268 "action": toogle_follow(repo.repo_id)
268 "action": toogle_follow(repo.repo_id)
269 }
269 }
270
270
271 watched_repos_data.append(row)
271 watched_repos_data.append(row)
272
272
273 c.watched_data = json.dumps({
273 c.watched_data = json.dumps({
274 "totalRecords": len(c.following),
274 "totalRecords": len(c.following),
275 "startIndex": 0,
275 "startIndex": 0,
276 "sort": "name",
276 "sort": "name",
277 "dir": "asc",
277 "dir": "asc",
278 "records": watched_repos_data
278 "records": watched_repos_data
279 })
279 })
280 return render('journal/journal.html')
280 return render('journal/journal.html')
281
281
282 @LoginRequired(api_access=True)
282 @LoginRequired(api_access=True)
283 @NotAnonymous()
283 @NotAnonymous()
284 def journal_atom(self):
284 def journal_atom(self):
285 """
285 """
286 Produce an atom-1.0 feed via feedgenerator module
286 Produce an atom-1.0 feed via feedgenerator module
287 """
287 """
288 following = self.sa.query(UserFollowing)\
288 following = self.sa.query(UserFollowing)\
289 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
289 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
290 .options(joinedload(UserFollowing.follows_repository))\
290 .options(joinedload(UserFollowing.follows_repository))\
291 .all()
291 .all()
292 return self._atom_feed(following, public=False)
292 return self._atom_feed(following, public=False)
293
293
294 @LoginRequired(api_access=True)
294 @LoginRequired(api_access=True)
295 @NotAnonymous()
295 @NotAnonymous()
296 def journal_rss(self):
296 def journal_rss(self):
297 """
297 """
298 Produce an rss feed via feedgenerator module
298 Produce an rss feed via feedgenerator module
299 """
299 """
300 following = self.sa.query(UserFollowing)\
300 following = self.sa.query(UserFollowing)\
301 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
301 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
302 .options(joinedload(UserFollowing.follows_repository))\
302 .options(joinedload(UserFollowing.follows_repository))\
303 .all()
303 .all()
304 return self._rss_feed(following, public=False)
304 return self._rss_feed(following, public=False)
305
305
306 @LoginRequired()
306 @LoginRequired()
307 @NotAnonymous()
307 @NotAnonymous()
308 def toggle_following(self):
308 def toggle_following(self):
309 cur_token = request.POST.get('auth_token')
309 cur_token = request.POST.get('auth_token')
310 token = h.get_token()
310 token = h.get_token()
311 if cur_token == token:
311 if cur_token == token:
312
312
313 user_id = request.POST.get('follows_user_id')
313 user_id = request.POST.get('follows_user_id')
314 if user_id:
314 if user_id:
315 try:
315 try:
316 self.scm_model.toggle_following_user(user_id,
316 self.scm_model.toggle_following_user(user_id,
317 self.rhodecode_user.user_id)
317 self.rhodecode_user.user_id)
318 Session.commit()
318 Session.commit()
319 return 'ok'
319 return 'ok'
320 except Exception:
320 except Exception:
321 raise HTTPBadRequest()
321 raise HTTPBadRequest()
322
322
323 repo_id = request.POST.get('follows_repo_id')
323 repo_id = request.POST.get('follows_repo_id')
324 if repo_id:
324 if repo_id:
325 try:
325 try:
326 self.scm_model.toggle_following_repo(repo_id,
326 self.scm_model.toggle_following_repo(repo_id,
327 self.rhodecode_user.user_id)
327 self.rhodecode_user.user_id)
328 Session.commit()
328 Session.commit()
329 return 'ok'
329 return 'ok'
330 except Exception:
330 except Exception:
331 raise HTTPBadRequest()
331 raise HTTPBadRequest()
332
332
333 log.debug('token mismatch %s vs %s' % (cur_token, token))
333 log.debug('token mismatch %s vs %s' % (cur_token, token))
334 raise HTTPBadRequest()
334 raise HTTPBadRequest()
335
335
336 @LoginRequired()
336 @LoginRequired()
337 def public_journal(self):
337 def public_journal(self):
338 # Return a rendered template
338 # Return a rendered template
339 p = safe_int(request.GET.get('page', 1), 1)
339 p = safe_int(request.GET.get('page', 1), 1)
340
340
341 c.following = self.sa.query(UserFollowing)\
341 c.following = self.sa.query(UserFollowing)\
342 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
342 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
343 .options(joinedload(UserFollowing.follows_repository))\
343 .options(joinedload(UserFollowing.follows_repository))\
344 .all()
344 .all()
345
345
346 journal = self._get_journal_data(c.following)
346 journal = self._get_journal_data(c.following)
347
347
348 c.journal_pager = Page(journal, page=p, items_per_page=20)
348 c.journal_pager = Page(journal, page=p, items_per_page=20)
349
349
350 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
350 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
351
351
352 c.journal_data = render('journal/journal_data.html')
352 c.journal_data = render('journal/journal_data.html')
353 if request.environ.get('HTTP_X_PARTIAL_XHR'):
353 if request.environ.get('HTTP_X_PARTIAL_XHR'):
354 return c.journal_data
354 return c.journal_data
355 return render('journal/public_journal.html')
355 return render('journal/public_journal.html')
356
356
357 @LoginRequired(api_access=True)
357 @LoginRequired(api_access=True)
358 def public_journal_atom(self):
358 def public_journal_atom(self):
359 """
359 """
360 Produce an atom-1.0 feed via feedgenerator module
360 Produce an atom-1.0 feed via feedgenerator module
361 """
361 """
362 c.following = self.sa.query(UserFollowing)\
362 c.following = self.sa.query(UserFollowing)\
363 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
363 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
364 .options(joinedload(UserFollowing.follows_repository))\
364 .options(joinedload(UserFollowing.follows_repository))\
365 .all()
365 .all()
366
366
367 return self._atom_feed(c.following)
367 return self._atom_feed(c.following)
368
368
369 @LoginRequired(api_access=True)
369 @LoginRequired(api_access=True)
370 def public_journal_rss(self):
370 def public_journal_rss(self):
371 """
371 """
372 Produce an rss2 feed via feedgenerator module
372 Produce an rss2 feed via feedgenerator module
373 """
373 """
374 c.following = self.sa.query(UserFollowing)\
374 c.following = self.sa.query(UserFollowing)\
375 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
375 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
376 .options(joinedload(UserFollowing.follows_repository))\
376 .options(joinedload(UserFollowing.follows_repository))\
377 .all()
377 .all()
378
378
379 return self._rss_feed(c.following)
379 return self._rss_feed(c.following)
@@ -1,146 +1,144 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.search
3 rhodecode.controllers.search
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Search controller for RhodeCode
6 Search controller for RhodeCode
7
7
8 :created_on: Aug 7, 2010
8 :created_on: Aug 7, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import logging
25 import logging
26 import traceback
26 import traceback
27 import urllib
27 import urllib
28 from pylons.i18n.translation import _
28 from pylons.i18n.translation import _
29 from pylons import request, config, tmpl_context as c
29 from pylons import request, config, tmpl_context as c
30
30
31 from whoosh.index import open_dir, EmptyIndexError
32 from whoosh.qparser import QueryParser, QueryParserError
33 from whoosh.query import Phrase, Wildcard, Term, Prefix
34 from webhelpers.util import update_params
35
31 from rhodecode.lib.auth import LoginRequired
36 from rhodecode.lib.auth import LoginRequired
32 from rhodecode.lib.base import BaseRepoController, render
37 from rhodecode.lib.base import BaseRepoController, render
33 from rhodecode.lib.indexers import CHGSETS_SCHEMA, SCHEMA, CHGSET_IDX_NAME, \
38 from rhodecode.lib.indexers import CHGSETS_SCHEMA, SCHEMA, CHGSET_IDX_NAME, \
34 IDX_NAME, WhooshResultWrapper
39 IDX_NAME, WhooshResultWrapper
35
36 from webhelpers.paginate import Page
37 from webhelpers.util import update_params
38
39 from whoosh.index import open_dir, EmptyIndexError
40 from whoosh.qparser import QueryParser, QueryParserError
41 from whoosh.query import Phrase, Wildcard, Term, Prefix
42 from rhodecode.model.repo import RepoModel
40 from rhodecode.model.repo import RepoModel
43 from rhodecode.lib.utils2 import safe_str, safe_int
41 from rhodecode.lib.utils2 import safe_str, safe_int
44
42 from rhodecode.lib.helpers import Page
45
43
46 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
47
45
48
46
49 class SearchController(BaseRepoController):
47 class SearchController(BaseRepoController):
50
48
51 def __before__(self):
49 def __before__(self):
52 super(SearchController, self).__before__()
50 super(SearchController, self).__before__()
53
51
54 @LoginRequired()
52 @LoginRequired()
55 def index(self, repo_name=None):
53 def index(self, repo_name=None):
56 c.repo_name = repo_name
54 c.repo_name = repo_name
57 c.formated_results = []
55 c.formated_results = []
58 c.runtime = ''
56 c.runtime = ''
59 c.cur_query = request.GET.get('q', None)
57 c.cur_query = request.GET.get('q', None)
60 c.cur_type = request.GET.get('type', 'content')
58 c.cur_type = request.GET.get('type', 'content')
61 c.cur_search = search_type = {'content': 'content',
59 c.cur_search = search_type = {'content': 'content',
62 'commit': 'message',
60 'commit': 'message',
63 'path': 'path',
61 'path': 'path',
64 'repository': 'repository'
62 'repository': 'repository'
65 }.get(c.cur_type, 'content')
63 }.get(c.cur_type, 'content')
66
64
67 index_name = {
65 index_name = {
68 'content': IDX_NAME,
66 'content': IDX_NAME,
69 'commit': CHGSET_IDX_NAME,
67 'commit': CHGSET_IDX_NAME,
70 'path': IDX_NAME
68 'path': IDX_NAME
71 }.get(c.cur_type, IDX_NAME)
69 }.get(c.cur_type, IDX_NAME)
72
70
73 schema_defn = {
71 schema_defn = {
74 'content': SCHEMA,
72 'content': SCHEMA,
75 'commit': CHGSETS_SCHEMA,
73 'commit': CHGSETS_SCHEMA,
76 'path': SCHEMA
74 'path': SCHEMA
77 }.get(c.cur_type, SCHEMA)
75 }.get(c.cur_type, SCHEMA)
78
76
79 log.debug('IDX: %s' % index_name)
77 log.debug('IDX: %s' % index_name)
80 log.debug('SCHEMA: %s' % schema_defn)
78 log.debug('SCHEMA: %s' % schema_defn)
81
79
82 if c.cur_query:
80 if c.cur_query:
83 cur_query = c.cur_query.lower()
81 cur_query = c.cur_query.lower()
84 log.debug(cur_query)
82 log.debug(cur_query)
85
83
86 if c.cur_query:
84 if c.cur_query:
87 p = safe_int(request.GET.get('page', 1), 1)
85 p = safe_int(request.GET.get('page', 1), 1)
88 highlight_items = set()
86 highlight_items = set()
89 try:
87 try:
90 idx = open_dir(config['app_conf']['index_dir'],
88 idx = open_dir(config['app_conf']['index_dir'],
91 indexname=index_name)
89 indexname=index_name)
92 searcher = idx.searcher()
90 searcher = idx.searcher()
93
91
94 qp = QueryParser(search_type, schema=schema_defn)
92 qp = QueryParser(search_type, schema=schema_defn)
95 if c.repo_name:
93 if c.repo_name:
96 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
94 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
97 try:
95 try:
98 query = qp.parse(unicode(cur_query))
96 query = qp.parse(unicode(cur_query))
99 # extract words for highlight
97 # extract words for highlight
100 if isinstance(query, Phrase):
98 if isinstance(query, Phrase):
101 highlight_items.update(query.words)
99 highlight_items.update(query.words)
102 elif isinstance(query, Prefix):
100 elif isinstance(query, Prefix):
103 highlight_items.add(query.text)
101 highlight_items.add(query.text)
104 else:
102 else:
105 for i in query.all_terms():
103 for i in query.all_terms():
106 if i[0] in ['content', 'message']:
104 if i[0] in ['content', 'message']:
107 highlight_items.add(i[1])
105 highlight_items.add(i[1])
108
106
109 matcher = query.matcher(searcher)
107 matcher = query.matcher(searcher)
110
108
111 log.debug('query: %s' % query)
109 log.debug('query: %s' % query)
112 log.debug('hl terms: %s' % highlight_items)
110 log.debug('hl terms: %s' % highlight_items)
113 results = searcher.search(query)
111 results = searcher.search(query)
114 res_ln = len(results)
112 res_ln = len(results)
115 c.runtime = '%s results (%.3f seconds)' % (
113 c.runtime = '%s results (%.3f seconds)' % (
116 res_ln, results.runtime
114 res_ln, results.runtime
117 )
115 )
118
116
119 def url_generator(**kw):
117 def url_generator(**kw):
120 q = urllib.quote(safe_str(c.cur_query))
118 q = urllib.quote(safe_str(c.cur_query))
121 return update_params("?q=%s&type=%s" \
119 return update_params("?q=%s&type=%s" \
122 % (q, safe_str(c.cur_type)), **kw)
120 % (q, safe_str(c.cur_type)), **kw)
123 repo_location = RepoModel().repos_path
121 repo_location = RepoModel().repos_path
124 c.formated_results = Page(
122 c.formated_results = Page(
125 WhooshResultWrapper(search_type, searcher, matcher,
123 WhooshResultWrapper(search_type, searcher, matcher,
126 highlight_items, repo_location),
124 highlight_items, repo_location),
127 page=p,
125 page=p,
128 item_count=res_ln,
126 item_count=res_ln,
129 items_per_page=10,
127 items_per_page=10,
130 url=url_generator
128 url=url_generator
131 )
129 )
132
130
133 except QueryParserError:
131 except QueryParserError:
134 c.runtime = _('Invalid search query. Try quoting it.')
132 c.runtime = _('Invalid search query. Try quoting it.')
135 searcher.close()
133 searcher.close()
136 except (EmptyIndexError, IOError):
134 except (EmptyIndexError, IOError):
137 log.error(traceback.format_exc())
135 log.error(traceback.format_exc())
138 log.error('Empty Index data')
136 log.error('Empty Index data')
139 c.runtime = _('There is no index to search in. '
137 c.runtime = _('There is no index to search in. '
140 'Please run whoosh indexer')
138 'Please run whoosh indexer')
141 except (Exception):
139 except (Exception):
142 log.error(traceback.format_exc())
140 log.error(traceback.format_exc())
143 c.runtime = _('An error occurred during this search operation')
141 c.runtime = _('An error occurred during this search operation')
144
142
145 # Return a rendered template
143 # Return a rendered template
146 return render('/search/search.html')
144 return render('/search/search.html')
@@ -1,1206 +1,1343 b''
1 """Helper functions
1 """Helper functions
2
2
3 Consists of functions to typically be used within templates, but also
3 Consists of functions to typically be used within templates, but also
4 available to Controllers. This module is available to both as 'h'.
4 available to Controllers. This module is available to both as 'h'.
5 """
5 """
6 import random
6 import random
7 import hashlib
7 import hashlib
8 import StringIO
8 import StringIO
9 import urllib
9 import urllib
10 import math
10 import math
11 import logging
11 import logging
12 import re
12 import re
13 import urlparse
13 import urlparse
14 import textwrap
14 import textwrap
15
15
16 from datetime import datetime
16 from datetime import datetime
17 from pygments.formatters.html import HtmlFormatter
17 from pygments.formatters.html import HtmlFormatter
18 from pygments import highlight as code_highlight
18 from pygments import highlight as code_highlight
19 from pylons import url, request, config
19 from pylons import url, request, config
20 from pylons.i18n.translation import _, ungettext
20 from pylons.i18n.translation import _, ungettext
21 from hashlib import md5
21 from hashlib import md5
22
22
23 from webhelpers.html import literal, HTML, escape
23 from webhelpers.html import literal, HTML, escape
24 from webhelpers.html.tools import *
24 from webhelpers.html.tools import *
25 from webhelpers.html.builder import make_tag
25 from webhelpers.html.builder import make_tag
26 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
26 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
27 end_form, file, form, hidden, image, javascript_link, link_to, \
27 end_form, file, form, hidden, image, javascript_link, link_to, \
28 link_to_if, link_to_unless, ol, required_legend, select, stylesheet_link, \
28 link_to_if, link_to_unless, ol, required_legend, select, stylesheet_link, \
29 submit, text, password, textarea, title, ul, xml_declaration, radio
29 submit, text, password, textarea, title, ul, xml_declaration, radio
30 from webhelpers.html.tools import auto_link, button_to, highlight, \
30 from webhelpers.html.tools import auto_link, button_to, highlight, \
31 js_obfuscate, mail_to, strip_links, strip_tags, tag_re
31 js_obfuscate, mail_to, strip_links, strip_tags, tag_re
32 from webhelpers.number import format_byte_size, format_bit_size
32 from webhelpers.number import format_byte_size, format_bit_size
33 from webhelpers.pylonslib import Flash as _Flash
33 from webhelpers.pylonslib import Flash as _Flash
34 from webhelpers.pylonslib.secure_form import secure_form
34 from webhelpers.pylonslib.secure_form import secure_form
35 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
35 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
36 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
36 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
37 replace_whitespace, urlify, truncate, wrap_paragraphs
37 replace_whitespace, urlify, truncate, wrap_paragraphs
38 from webhelpers.date import time_ago_in_words
38 from webhelpers.date import time_ago_in_words
39 from webhelpers.paginate import Page
39 from webhelpers.paginate import Page as _Page
40 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
40 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
41 convert_boolean_attrs, NotGiven, _make_safe_id_component
41 convert_boolean_attrs, NotGiven, _make_safe_id_component
42
42
43 from rhodecode.lib.annotate import annotate_highlight
43 from rhodecode.lib.annotate import annotate_highlight
44 from rhodecode.lib.utils import repo_name_slug, get_custom_lexer
44 from rhodecode.lib.utils import repo_name_slug, get_custom_lexer
45 from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \
45 from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \
46 get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict,\
46 get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict,\
47 safe_int
47 safe_int
48 from rhodecode.lib.markup_renderer import MarkupRenderer
48 from rhodecode.lib.markup_renderer import MarkupRenderer
49 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
49 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
50 from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyChangeset
50 from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyChangeset
51 from rhodecode.config.conf import DATE_FORMAT, DATETIME_FORMAT
51 from rhodecode.config.conf import DATE_FORMAT, DATETIME_FORMAT
52 from rhodecode.model.changeset_status import ChangesetStatusModel
52 from rhodecode.model.changeset_status import ChangesetStatusModel
53 from rhodecode.model.db import URL_SEP, Permission
53 from rhodecode.model.db import URL_SEP, Permission
54
54
55 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
56
56
57
57
58 html_escape_table = {
58 html_escape_table = {
59 "&": "&amp;",
59 "&": "&amp;",
60 '"': "&quot;",
60 '"': "&quot;",
61 "'": "&apos;",
61 "'": "&apos;",
62 ">": "&gt;",
62 ">": "&gt;",
63 "<": "&lt;",
63 "<": "&lt;",
64 }
64 }
65
65
66
66
67 def html_escape(text):
67 def html_escape(text):
68 """Produce entities within text."""
68 """Produce entities within text."""
69 return "".join(html_escape_table.get(c, c) for c in text)
69 return "".join(html_escape_table.get(c, c) for c in text)
70
70
71
71
72 def shorter(text, size=20):
72 def shorter(text, size=20):
73 postfix = '...'
73 postfix = '...'
74 if len(text) > size:
74 if len(text) > size:
75 return text[:size - len(postfix)] + postfix
75 return text[:size - len(postfix)] + postfix
76 return text
76 return text
77
77
78
78
79 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
79 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
80 """
80 """
81 Reset button
81 Reset button
82 """
82 """
83 _set_input_attrs(attrs, type, name, value)
83 _set_input_attrs(attrs, type, name, value)
84 _set_id_attr(attrs, id, name)
84 _set_id_attr(attrs, id, name)
85 convert_boolean_attrs(attrs, ["disabled"])
85 convert_boolean_attrs(attrs, ["disabled"])
86 return HTML.input(**attrs)
86 return HTML.input(**attrs)
87
87
88 reset = _reset
88 reset = _reset
89 safeid = _make_safe_id_component
89 safeid = _make_safe_id_component
90
90
91
91
92 def FID(raw_id, path):
92 def FID(raw_id, path):
93 """
93 """
94 Creates a uniqe ID for filenode based on it's hash of path and revision
94 Creates a uniqe ID for filenode based on it's hash of path and revision
95 it's safe to use in urls
95 it's safe to use in urls
96
96
97 :param raw_id:
97 :param raw_id:
98 :param path:
98 :param path:
99 """
99 """
100
100
101 return 'C-%s-%s' % (short_id(raw_id), md5(safe_str(path)).hexdigest()[:12])
101 return 'C-%s-%s' % (short_id(raw_id), md5(safe_str(path)).hexdigest()[:12])
102
102
103
103
104 def get_token():
104 def get_token():
105 """Return the current authentication token, creating one if one doesn't
105 """Return the current authentication token, creating one if one doesn't
106 already exist.
106 already exist.
107 """
107 """
108 token_key = "_authentication_token"
108 token_key = "_authentication_token"
109 from pylons import session
109 from pylons import session
110 if not token_key in session:
110 if not token_key in session:
111 try:
111 try:
112 token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
112 token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
113 except AttributeError: # Python < 2.4
113 except AttributeError: # Python < 2.4
114 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
114 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
115 session[token_key] = token
115 session[token_key] = token
116 if hasattr(session, 'save'):
116 if hasattr(session, 'save'):
117 session.save()
117 session.save()
118 return session[token_key]
118 return session[token_key]
119
119
120
120
121 class _GetError(object):
121 class _GetError(object):
122 """Get error from form_errors, and represent it as span wrapped error
122 """Get error from form_errors, and represent it as span wrapped error
123 message
123 message
124
124
125 :param field_name: field to fetch errors for
125 :param field_name: field to fetch errors for
126 :param form_errors: form errors dict
126 :param form_errors: form errors dict
127 """
127 """
128
128
129 def __call__(self, field_name, form_errors):
129 def __call__(self, field_name, form_errors):
130 tmpl = """<span class="error_msg">%s</span>"""
130 tmpl = """<span class="error_msg">%s</span>"""
131 if form_errors and field_name in form_errors:
131 if form_errors and field_name in form_errors:
132 return literal(tmpl % form_errors.get(field_name))
132 return literal(tmpl % form_errors.get(field_name))
133
133
134 get_error = _GetError()
134 get_error = _GetError()
135
135
136
136
137 class _ToolTip(object):
137 class _ToolTip(object):
138
138
139 def __call__(self, tooltip_title, trim_at=50):
139 def __call__(self, tooltip_title, trim_at=50):
140 """
140 """
141 Special function just to wrap our text into nice formatted
141 Special function just to wrap our text into nice formatted
142 autowrapped text
142 autowrapped text
143
143
144 :param tooltip_title:
144 :param tooltip_title:
145 """
145 """
146 tooltip_title = escape(tooltip_title)
146 tooltip_title = escape(tooltip_title)
147 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
147 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
148 return tooltip_title
148 return tooltip_title
149 tooltip = _ToolTip()
149 tooltip = _ToolTip()
150
150
151
151
152 class _FilesBreadCrumbs(object):
152 class _FilesBreadCrumbs(object):
153
153
154 def __call__(self, repo_name, rev, paths):
154 def __call__(self, repo_name, rev, paths):
155 if isinstance(paths, str):
155 if isinstance(paths, str):
156 paths = safe_unicode(paths)
156 paths = safe_unicode(paths)
157 url_l = [link_to(repo_name, url('files_home',
157 url_l = [link_to(repo_name, url('files_home',
158 repo_name=repo_name,
158 repo_name=repo_name,
159 revision=rev, f_path=''),
159 revision=rev, f_path=''),
160 class_='ypjax-link')]
160 class_='ypjax-link')]
161 paths_l = paths.split('/')
161 paths_l = paths.split('/')
162 for cnt, p in enumerate(paths_l):
162 for cnt, p in enumerate(paths_l):
163 if p != '':
163 if p != '':
164 url_l.append(link_to(p,
164 url_l.append(link_to(p,
165 url('files_home',
165 url('files_home',
166 repo_name=repo_name,
166 repo_name=repo_name,
167 revision=rev,
167 revision=rev,
168 f_path='/'.join(paths_l[:cnt + 1])
168 f_path='/'.join(paths_l[:cnt + 1])
169 ),
169 ),
170 class_='ypjax-link'
170 class_='ypjax-link'
171 )
171 )
172 )
172 )
173
173
174 return literal('/'.join(url_l))
174 return literal('/'.join(url_l))
175
175
176 files_breadcrumbs = _FilesBreadCrumbs()
176 files_breadcrumbs = _FilesBreadCrumbs()
177
177
178
178
179 class CodeHtmlFormatter(HtmlFormatter):
179 class CodeHtmlFormatter(HtmlFormatter):
180 """
180 """
181 My code Html Formatter for source codes
181 My code Html Formatter for source codes
182 """
182 """
183
183
184 def wrap(self, source, outfile):
184 def wrap(self, source, outfile):
185 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
185 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
186
186
187 def _wrap_code(self, source):
187 def _wrap_code(self, source):
188 for cnt, it in enumerate(source):
188 for cnt, it in enumerate(source):
189 i, t = it
189 i, t = it
190 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
190 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
191 yield i, t
191 yield i, t
192
192
193 def _wrap_tablelinenos(self, inner):
193 def _wrap_tablelinenos(self, inner):
194 dummyoutfile = StringIO.StringIO()
194 dummyoutfile = StringIO.StringIO()
195 lncount = 0
195 lncount = 0
196 for t, line in inner:
196 for t, line in inner:
197 if t:
197 if t:
198 lncount += 1
198 lncount += 1
199 dummyoutfile.write(line)
199 dummyoutfile.write(line)
200
200
201 fl = self.linenostart
201 fl = self.linenostart
202 mw = len(str(lncount + fl - 1))
202 mw = len(str(lncount + fl - 1))
203 sp = self.linenospecial
203 sp = self.linenospecial
204 st = self.linenostep
204 st = self.linenostep
205 la = self.lineanchors
205 la = self.lineanchors
206 aln = self.anchorlinenos
206 aln = self.anchorlinenos
207 nocls = self.noclasses
207 nocls = self.noclasses
208 if sp:
208 if sp:
209 lines = []
209 lines = []
210
210
211 for i in range(fl, fl + lncount):
211 for i in range(fl, fl + lncount):
212 if i % st == 0:
212 if i % st == 0:
213 if i % sp == 0:
213 if i % sp == 0:
214 if aln:
214 if aln:
215 lines.append('<a href="#%s%d" class="special">%*d</a>' %
215 lines.append('<a href="#%s%d" class="special">%*d</a>' %
216 (la, i, mw, i))
216 (la, i, mw, i))
217 else:
217 else:
218 lines.append('<span class="special">%*d</span>' % (mw, i))
218 lines.append('<span class="special">%*d</span>' % (mw, i))
219 else:
219 else:
220 if aln:
220 if aln:
221 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
221 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
222 else:
222 else:
223 lines.append('%*d' % (mw, i))
223 lines.append('%*d' % (mw, i))
224 else:
224 else:
225 lines.append('')
225 lines.append('')
226 ls = '\n'.join(lines)
226 ls = '\n'.join(lines)
227 else:
227 else:
228 lines = []
228 lines = []
229 for i in range(fl, fl + lncount):
229 for i in range(fl, fl + lncount):
230 if i % st == 0:
230 if i % st == 0:
231 if aln:
231 if aln:
232 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
232 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
233 else:
233 else:
234 lines.append('%*d' % (mw, i))
234 lines.append('%*d' % (mw, i))
235 else:
235 else:
236 lines.append('')
236 lines.append('')
237 ls = '\n'.join(lines)
237 ls = '\n'.join(lines)
238
238
239 # in case you wonder about the seemingly redundant <div> here: since the
239 # in case you wonder about the seemingly redundant <div> here: since the
240 # content in the other cell also is wrapped in a div, some browsers in
240 # content in the other cell also is wrapped in a div, some browsers in
241 # some configurations seem to mess up the formatting...
241 # some configurations seem to mess up the formatting...
242 if nocls:
242 if nocls:
243 yield 0, ('<table class="%stable">' % self.cssclass +
243 yield 0, ('<table class="%stable">' % self.cssclass +
244 '<tr><td><div class="linenodiv" '
244 '<tr><td><div class="linenodiv" '
245 'style="background-color: #f0f0f0; padding-right: 10px">'
245 'style="background-color: #f0f0f0; padding-right: 10px">'
246 '<pre style="line-height: 125%">' +
246 '<pre style="line-height: 125%">' +
247 ls + '</pre></div></td><td id="hlcode" class="code">')
247 ls + '</pre></div></td><td id="hlcode" class="code">')
248 else:
248 else:
249 yield 0, ('<table class="%stable">' % self.cssclass +
249 yield 0, ('<table class="%stable">' % self.cssclass +
250 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
250 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
251 ls + '</pre></div></td><td id="hlcode" class="code">')
251 ls + '</pre></div></td><td id="hlcode" class="code">')
252 yield 0, dummyoutfile.getvalue()
252 yield 0, dummyoutfile.getvalue()
253 yield 0, '</td></tr></table>'
253 yield 0, '</td></tr></table>'
254
254
255
255
256 def pygmentize(filenode, **kwargs):
256 def pygmentize(filenode, **kwargs):
257 """
257 """
258 pygmentize function using pygments
258 pygmentize function using pygments
259
259
260 :param filenode:
260 :param filenode:
261 """
261 """
262 lexer = get_custom_lexer(filenode.extension) or filenode.lexer
262 lexer = get_custom_lexer(filenode.extension) or filenode.lexer
263 return literal(code_highlight(filenode.content, lexer,
263 return literal(code_highlight(filenode.content, lexer,
264 CodeHtmlFormatter(**kwargs)))
264 CodeHtmlFormatter(**kwargs)))
265
265
266
266
267 def pygmentize_annotation(repo_name, filenode, **kwargs):
267 def pygmentize_annotation(repo_name, filenode, **kwargs):
268 """
268 """
269 pygmentize function for annotation
269 pygmentize function for annotation
270
270
271 :param filenode:
271 :param filenode:
272 """
272 """
273
273
274 color_dict = {}
274 color_dict = {}
275
275
276 def gen_color(n=10000):
276 def gen_color(n=10000):
277 """generator for getting n of evenly distributed colors using
277 """generator for getting n of evenly distributed colors using
278 hsv color and golden ratio. It always return same order of colors
278 hsv color and golden ratio. It always return same order of colors
279
279
280 :returns: RGB tuple
280 :returns: RGB tuple
281 """
281 """
282
282
283 def hsv_to_rgb(h, s, v):
283 def hsv_to_rgb(h, s, v):
284 if s == 0.0:
284 if s == 0.0:
285 return v, v, v
285 return v, v, v
286 i = int(h * 6.0) # XXX assume int() truncates!
286 i = int(h * 6.0) # XXX assume int() truncates!
287 f = (h * 6.0) - i
287 f = (h * 6.0) - i
288 p = v * (1.0 - s)
288 p = v * (1.0 - s)
289 q = v * (1.0 - s * f)
289 q = v * (1.0 - s * f)
290 t = v * (1.0 - s * (1.0 - f))
290 t = v * (1.0 - s * (1.0 - f))
291 i = i % 6
291 i = i % 6
292 if i == 0:
292 if i == 0:
293 return v, t, p
293 return v, t, p
294 if i == 1:
294 if i == 1:
295 return q, v, p
295 return q, v, p
296 if i == 2:
296 if i == 2:
297 return p, v, t
297 return p, v, t
298 if i == 3:
298 if i == 3:
299 return p, q, v
299 return p, q, v
300 if i == 4:
300 if i == 4:
301 return t, p, v
301 return t, p, v
302 if i == 5:
302 if i == 5:
303 return v, p, q
303 return v, p, q
304
304
305 golden_ratio = 0.618033988749895
305 golden_ratio = 0.618033988749895
306 h = 0.22717784590367374
306 h = 0.22717784590367374
307
307
308 for _ in xrange(n):
308 for _ in xrange(n):
309 h += golden_ratio
309 h += golden_ratio
310 h %= 1
310 h %= 1
311 HSV_tuple = [h, 0.95, 0.95]
311 HSV_tuple = [h, 0.95, 0.95]
312 RGB_tuple = hsv_to_rgb(*HSV_tuple)
312 RGB_tuple = hsv_to_rgb(*HSV_tuple)
313 yield map(lambda x: str(int(x * 256)), RGB_tuple)
313 yield map(lambda x: str(int(x * 256)), RGB_tuple)
314
314
315 cgenerator = gen_color()
315 cgenerator = gen_color()
316
316
317 def get_color_string(cs):
317 def get_color_string(cs):
318 if cs in color_dict:
318 if cs in color_dict:
319 col = color_dict[cs]
319 col = color_dict[cs]
320 else:
320 else:
321 col = color_dict[cs] = cgenerator.next()
321 col = color_dict[cs] = cgenerator.next()
322 return "color: rgb(%s)! important;" % (', '.join(col))
322 return "color: rgb(%s)! important;" % (', '.join(col))
323
323
324 def url_func(repo_name):
324 def url_func(repo_name):
325
325
326 def _url_func(changeset):
326 def _url_func(changeset):
327 author = changeset.author
327 author = changeset.author
328 date = changeset.date
328 date = changeset.date
329 message = tooltip(changeset.message)
329 message = tooltip(changeset.message)
330
330
331 tooltip_html = ("<div style='font-size:0.8em'><b>Author:</b>"
331 tooltip_html = ("<div style='font-size:0.8em'><b>Author:</b>"
332 " %s<br/><b>Date:</b> %s</b><br/><b>Message:"
332 " %s<br/><b>Date:</b> %s</b><br/><b>Message:"
333 "</b> %s<br/></div>")
333 "</b> %s<br/></div>")
334
334
335 tooltip_html = tooltip_html % (author, date, message)
335 tooltip_html = tooltip_html % (author, date, message)
336 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
336 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
337 short_id(changeset.raw_id))
337 short_id(changeset.raw_id))
338 uri = link_to(
338 uri = link_to(
339 lnk_format,
339 lnk_format,
340 url('changeset_home', repo_name=repo_name,
340 url('changeset_home', repo_name=repo_name,
341 revision=changeset.raw_id),
341 revision=changeset.raw_id),
342 style=get_color_string(changeset.raw_id),
342 style=get_color_string(changeset.raw_id),
343 class_='tooltip',
343 class_='tooltip',
344 title=tooltip_html
344 title=tooltip_html
345 )
345 )
346
346
347 uri += '\n'
347 uri += '\n'
348 return uri
348 return uri
349 return _url_func
349 return _url_func
350
350
351 return literal(annotate_highlight(filenode, url_func(repo_name), **kwargs))
351 return literal(annotate_highlight(filenode, url_func(repo_name), **kwargs))
352
352
353
353
354 def is_following_repo(repo_name, user_id):
354 def is_following_repo(repo_name, user_id):
355 from rhodecode.model.scm import ScmModel
355 from rhodecode.model.scm import ScmModel
356 return ScmModel().is_following_repo(repo_name, user_id)
356 return ScmModel().is_following_repo(repo_name, user_id)
357
357
358 flash = _Flash()
358 flash = _Flash()
359
359
360 #==============================================================================
360 #==============================================================================
361 # SCM FILTERS available via h.
361 # SCM FILTERS available via h.
362 #==============================================================================
362 #==============================================================================
363 from rhodecode.lib.vcs.utils import author_name, author_email
363 from rhodecode.lib.vcs.utils import author_name, author_email
364 from rhodecode.lib.utils2 import credentials_filter, age as _age
364 from rhodecode.lib.utils2 import credentials_filter, age as _age
365 from rhodecode.model.db import User, ChangesetStatus
365 from rhodecode.model.db import User, ChangesetStatus
366
366
367 age = lambda x, y=False: _age(x, y)
367 age = lambda x, y=False: _age(x, y)
368 capitalize = lambda x: x.capitalize()
368 capitalize = lambda x: x.capitalize()
369 email = author_email
369 email = author_email
370 short_id = lambda x: x[:12]
370 short_id = lambda x: x[:12]
371 hide_credentials = lambda x: ''.join(credentials_filter(x))
371 hide_credentials = lambda x: ''.join(credentials_filter(x))
372
372
373
373
374 def show_id(cs):
374 def show_id(cs):
375 """
375 """
376 Configurable function that shows ID
376 Configurable function that shows ID
377 by default it's r123:fffeeefffeee
377 by default it's r123:fffeeefffeee
378
378
379 :param cs: changeset instance
379 :param cs: changeset instance
380 """
380 """
381 from rhodecode import CONFIG
381 from rhodecode import CONFIG
382 def_len = safe_int(CONFIG.get('show_sha_length', 12))
382 def_len = safe_int(CONFIG.get('show_sha_length', 12))
383 show_rev = str2bool(CONFIG.get('show_revision_number', True))
383 show_rev = str2bool(CONFIG.get('show_revision_number', True))
384
384
385 raw_id = cs.raw_id[:def_len]
385 raw_id = cs.raw_id[:def_len]
386 if show_rev:
386 if show_rev:
387 return 'r%s:%s' % (cs.revision, raw_id)
387 return 'r%s:%s' % (cs.revision, raw_id)
388 else:
388 else:
389 return '%s' % (raw_id)
389 return '%s' % (raw_id)
390
390
391
391
392 def fmt_date(date):
392 def fmt_date(date):
393 if date:
393 if date:
394 _fmt = _(u"%a, %d %b %Y %H:%M:%S").encode('utf8')
394 _fmt = _(u"%a, %d %b %Y %H:%M:%S").encode('utf8')
395 return date.strftime(_fmt).decode('utf8')
395 return date.strftime(_fmt).decode('utf8')
396
396
397 return ""
397 return ""
398
398
399
399
400 def is_git(repository):
400 def is_git(repository):
401 if hasattr(repository, 'alias'):
401 if hasattr(repository, 'alias'):
402 _type = repository.alias
402 _type = repository.alias
403 elif hasattr(repository, 'repo_type'):
403 elif hasattr(repository, 'repo_type'):
404 _type = repository.repo_type
404 _type = repository.repo_type
405 else:
405 else:
406 _type = repository
406 _type = repository
407 return _type == 'git'
407 return _type == 'git'
408
408
409
409
410 def is_hg(repository):
410 def is_hg(repository):
411 if hasattr(repository, 'alias'):
411 if hasattr(repository, 'alias'):
412 _type = repository.alias
412 _type = repository.alias
413 elif hasattr(repository, 'repo_type'):
413 elif hasattr(repository, 'repo_type'):
414 _type = repository.repo_type
414 _type = repository.repo_type
415 else:
415 else:
416 _type = repository
416 _type = repository
417 return _type == 'hg'
417 return _type == 'hg'
418
418
419
419
420 def email_or_none(author):
420 def email_or_none(author):
421 # extract email from the commit string
421 # extract email from the commit string
422 _email = email(author)
422 _email = email(author)
423 if _email != '':
423 if _email != '':
424 # check it against RhodeCode database, and use the MAIN email for this
424 # check it against RhodeCode database, and use the MAIN email for this
425 # user
425 # user
426 user = User.get_by_email(_email, case_insensitive=True, cache=True)
426 user = User.get_by_email(_email, case_insensitive=True, cache=True)
427 if user is not None:
427 if user is not None:
428 return user.email
428 return user.email
429 return _email
429 return _email
430
430
431 # See if it contains a username we can get an email from
431 # See if it contains a username we can get an email from
432 user = User.get_by_username(author_name(author), case_insensitive=True,
432 user = User.get_by_username(author_name(author), case_insensitive=True,
433 cache=True)
433 cache=True)
434 if user is not None:
434 if user is not None:
435 return user.email
435 return user.email
436
436
437 # No valid email, not a valid user in the system, none!
437 # No valid email, not a valid user in the system, none!
438 return None
438 return None
439
439
440
440
441 def person(author, show_attr="username_and_name"):
441 def person(author, show_attr="username_and_name"):
442 # attr to return from fetched user
442 # attr to return from fetched user
443 person_getter = lambda usr: getattr(usr, show_attr)
443 person_getter = lambda usr: getattr(usr, show_attr)
444
444
445 # Valid email in the attribute passed, see if they're in the system
445 # Valid email in the attribute passed, see if they're in the system
446 _email = email(author)
446 _email = email(author)
447 if _email != '':
447 if _email != '':
448 user = User.get_by_email(_email, case_insensitive=True, cache=True)
448 user = User.get_by_email(_email, case_insensitive=True, cache=True)
449 if user is not None:
449 if user is not None:
450 return person_getter(user)
450 return person_getter(user)
451
451
452 # Maybe it's a username?
452 # Maybe it's a username?
453 _author = author_name(author)
453 _author = author_name(author)
454 user = User.get_by_username(_author, case_insensitive=True,
454 user = User.get_by_username(_author, case_insensitive=True,
455 cache=True)
455 cache=True)
456 if user is not None:
456 if user is not None:
457 return person_getter(user)
457 return person_getter(user)
458
458
459 # Still nothing? Just pass back the author name if any, else the email
459 # Still nothing? Just pass back the author name if any, else the email
460 return _author or _email
460 return _author or _email
461
461
462
462
463 def person_by_id(id_, show_attr="username_and_name"):
463 def person_by_id(id_, show_attr="username_and_name"):
464 # attr to return from fetched user
464 # attr to return from fetched user
465 person_getter = lambda usr: getattr(usr, show_attr)
465 person_getter = lambda usr: getattr(usr, show_attr)
466
466
467 #maybe it's an ID ?
467 #maybe it's an ID ?
468 if str(id_).isdigit() or isinstance(id_, int):
468 if str(id_).isdigit() or isinstance(id_, int):
469 id_ = int(id_)
469 id_ = int(id_)
470 user = User.get(id_)
470 user = User.get(id_)
471 if user is not None:
471 if user is not None:
472 return person_getter(user)
472 return person_getter(user)
473 return id_
473 return id_
474
474
475
475
476 def desc_stylize(value):
476 def desc_stylize(value):
477 """
477 """
478 converts tags from value into html equivalent
478 converts tags from value into html equivalent
479
479
480 :param value:
480 :param value:
481 """
481 """
482 value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
482 value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
483 '<div class="metatag" tag="see">see =&gt; \\1 </div>', value)
483 '<div class="metatag" tag="see">see =&gt; \\1 </div>', value)
484 value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
484 value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
485 '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', value)
485 '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', value)
486 value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]',
486 value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]',
487 '<div class="metatag" tag="\\1">\\1 =&gt; <a href="/\\2">\\2</a></div>', value)
487 '<div class="metatag" tag="\\1">\\1 =&gt; <a href="/\\2">\\2</a></div>', value)
488 value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+]*)\]',
488 value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+]*)\]',
489 '<div class="metatag" tag="lang">\\2</div>', value)
489 '<div class="metatag" tag="lang">\\2</div>', value)
490 value = re.sub(r'\[([a-z]+)\]',
490 value = re.sub(r'\[([a-z]+)\]',
491 '<div class="metatag" tag="\\1">\\1</div>', value)
491 '<div class="metatag" tag="\\1">\\1</div>', value)
492
492
493 return value
493 return value
494
494
495
495
496 def boolicon(value):
496 def boolicon(value):
497 """Returns boolean value of a value, represented as small html image of true/false
497 """Returns boolean value of a value, represented as small html image of true/false
498 icons
498 icons
499
499
500 :param value: value
500 :param value: value
501 """
501 """
502
502
503 if value:
503 if value:
504 return HTML.tag('img', src=url("/images/icons/accept.png"),
504 return HTML.tag('img', src=url("/images/icons/accept.png"),
505 alt=_('True'))
505 alt=_('True'))
506 else:
506 else:
507 return HTML.tag('img', src=url("/images/icons/cancel.png"),
507 return HTML.tag('img', src=url("/images/icons/cancel.png"),
508 alt=_('False'))
508 alt=_('False'))
509
509
510
510
511 def action_parser(user_log, feed=False, parse_cs=False):
511 def action_parser(user_log, feed=False, parse_cs=False):
512 """
512 """
513 This helper will action_map the specified string action into translated
513 This helper will action_map the specified string action into translated
514 fancy names with icons and links
514 fancy names with icons and links
515
515
516 :param user_log: user log instance
516 :param user_log: user log instance
517 :param feed: use output for feeds (no html and fancy icons)
517 :param feed: use output for feeds (no html and fancy icons)
518 :param parse_cs: parse Changesets into VCS instances
518 :param parse_cs: parse Changesets into VCS instances
519 """
519 """
520
520
521 action = user_log.action
521 action = user_log.action
522 action_params = ' '
522 action_params = ' '
523
523
524 x = action.split(':')
524 x = action.split(':')
525
525
526 if len(x) > 1:
526 if len(x) > 1:
527 action, action_params = x
527 action, action_params = x
528
528
529 def get_cs_links():
529 def get_cs_links():
530 revs_limit = 3 # display this amount always
530 revs_limit = 3 # display this amount always
531 revs_top_limit = 50 # show upto this amount of changesets hidden
531 revs_top_limit = 50 # show upto this amount of changesets hidden
532 revs_ids = action_params.split(',')
532 revs_ids = action_params.split(',')
533 deleted = user_log.repository is None
533 deleted = user_log.repository is None
534 if deleted:
534 if deleted:
535 return ','.join(revs_ids)
535 return ','.join(revs_ids)
536
536
537 repo_name = user_log.repository.repo_name
537 repo_name = user_log.repository.repo_name
538
538
539 def lnk(rev, repo_name):
539 def lnk(rev, repo_name):
540 if isinstance(rev, BaseChangeset) or isinstance(rev, AttributeDict):
540 if isinstance(rev, BaseChangeset) or isinstance(rev, AttributeDict):
541 lazy_cs = True
541 lazy_cs = True
542 if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
542 if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
543 lazy_cs = False
543 lazy_cs = False
544 lbl = '?'
544 lbl = '?'
545 if rev.op == 'delete_branch':
545 if rev.op == 'delete_branch':
546 lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
546 lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
547 title = ''
547 title = ''
548 elif rev.op == 'tag':
548 elif rev.op == 'tag':
549 lbl = '%s' % _('Created tag: %s') % rev.ref_name
549 lbl = '%s' % _('Created tag: %s') % rev.ref_name
550 title = ''
550 title = ''
551 _url = '#'
551 _url = '#'
552
552
553 else:
553 else:
554 lbl = '%s' % (rev.short_id[:8])
554 lbl = '%s' % (rev.short_id[:8])
555 _url = url('changeset_home', repo_name=repo_name,
555 _url = url('changeset_home', repo_name=repo_name,
556 revision=rev.raw_id)
556 revision=rev.raw_id)
557 title = tooltip(rev.message)
557 title = tooltip(rev.message)
558 else:
558 else:
559 ## changeset cannot be found/striped/removed etc.
559 ## changeset cannot be found/striped/removed etc.
560 lbl = ('%s' % rev)[:12]
560 lbl = ('%s' % rev)[:12]
561 _url = '#'
561 _url = '#'
562 title = _('Changeset not found')
562 title = _('Changeset not found')
563 if parse_cs:
563 if parse_cs:
564 return link_to(lbl, _url, title=title, class_='tooltip')
564 return link_to(lbl, _url, title=title, class_='tooltip')
565 return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
565 return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
566 class_='lazy-cs' if lazy_cs else '')
566 class_='lazy-cs' if lazy_cs else '')
567
567
568 def _get_op(rev_txt):
568 def _get_op(rev_txt):
569 _op = None
569 _op = None
570 _name = rev_txt
570 _name = rev_txt
571 if len(rev_txt.split('=>')) == 2:
571 if len(rev_txt.split('=>')) == 2:
572 _op, _name = rev_txt.split('=>')
572 _op, _name = rev_txt.split('=>')
573 return _op, _name
573 return _op, _name
574
574
575 revs = []
575 revs = []
576 if len(filter(lambda v: v != '', revs_ids)) > 0:
576 if len(filter(lambda v: v != '', revs_ids)) > 0:
577 repo = None
577 repo = None
578 for rev in revs_ids[:revs_top_limit]:
578 for rev in revs_ids[:revs_top_limit]:
579 _op, _name = _get_op(rev)
579 _op, _name = _get_op(rev)
580
580
581 # we want parsed changesets, or new log store format is bad
581 # we want parsed changesets, or new log store format is bad
582 if parse_cs:
582 if parse_cs:
583 try:
583 try:
584 if repo is None:
584 if repo is None:
585 repo = user_log.repository.scm_instance
585 repo = user_log.repository.scm_instance
586 _rev = repo.get_changeset(rev)
586 _rev = repo.get_changeset(rev)
587 revs.append(_rev)
587 revs.append(_rev)
588 except ChangesetDoesNotExistError:
588 except ChangesetDoesNotExistError:
589 log.error('cannot find revision %s in this repo' % rev)
589 log.error('cannot find revision %s in this repo' % rev)
590 revs.append(rev)
590 revs.append(rev)
591 continue
591 continue
592 else:
592 else:
593 _rev = AttributeDict({
593 _rev = AttributeDict({
594 'short_id': rev[:12],
594 'short_id': rev[:12],
595 'raw_id': rev,
595 'raw_id': rev,
596 'message': '',
596 'message': '',
597 'op': _op,
597 'op': _op,
598 'ref_name': _name
598 'ref_name': _name
599 })
599 })
600 revs.append(_rev)
600 revs.append(_rev)
601 cs_links = []
601 cs_links = []
602 cs_links.append(" " + ', '.join(
602 cs_links.append(" " + ', '.join(
603 [lnk(rev, repo_name) for rev in revs[:revs_limit]]
603 [lnk(rev, repo_name) for rev in revs[:revs_limit]]
604 )
604 )
605 )
605 )
606 _op1, _name1 = _get_op(revs_ids[0])
606 _op1, _name1 = _get_op(revs_ids[0])
607 _op2, _name2 = _get_op(revs_ids[-1])
607 _op2, _name2 = _get_op(revs_ids[-1])
608
608
609 _rev = '%s...%s' % (_name1, _name2)
609 _rev = '%s...%s' % (_name1, _name2)
610
610
611 compare_view = (
611 compare_view = (
612 ' <div class="compare_view tooltip" title="%s">'
612 ' <div class="compare_view tooltip" title="%s">'
613 '<a href="%s">%s</a> </div>' % (
613 '<a href="%s">%s</a> </div>' % (
614 _('Show all combined changesets %s->%s') % (
614 _('Show all combined changesets %s->%s') % (
615 revs_ids[0][:12], revs_ids[-1][:12]
615 revs_ids[0][:12], revs_ids[-1][:12]
616 ),
616 ),
617 url('changeset_home', repo_name=repo_name,
617 url('changeset_home', repo_name=repo_name,
618 revision=_rev
618 revision=_rev
619 ),
619 ),
620 _('compare view')
620 _('compare view')
621 )
621 )
622 )
622 )
623
623
624 # if we have exactly one more than normally displayed
624 # if we have exactly one more than normally displayed
625 # just display it, takes less space than displaying
625 # just display it, takes less space than displaying
626 # "and 1 more revisions"
626 # "and 1 more revisions"
627 if len(revs_ids) == revs_limit + 1:
627 if len(revs_ids) == revs_limit + 1:
628 rev = revs[revs_limit]
628 rev = revs[revs_limit]
629 cs_links.append(", " + lnk(rev, repo_name))
629 cs_links.append(", " + lnk(rev, repo_name))
630
630
631 # hidden-by-default ones
631 # hidden-by-default ones
632 if len(revs_ids) > revs_limit + 1:
632 if len(revs_ids) > revs_limit + 1:
633 uniq_id = revs_ids[0]
633 uniq_id = revs_ids[0]
634 html_tmpl = (
634 html_tmpl = (
635 '<span> %s <a class="show_more" id="_%s" '
635 '<span> %s <a class="show_more" id="_%s" '
636 'href="#more">%s</a> %s</span>'
636 'href="#more">%s</a> %s</span>'
637 )
637 )
638 if not feed:
638 if not feed:
639 cs_links.append(html_tmpl % (
639 cs_links.append(html_tmpl % (
640 _('and'),
640 _('and'),
641 uniq_id, _('%s more') % (len(revs_ids) - revs_limit),
641 uniq_id, _('%s more') % (len(revs_ids) - revs_limit),
642 _('revisions')
642 _('revisions')
643 )
643 )
644 )
644 )
645
645
646 if not feed:
646 if not feed:
647 html_tmpl = '<span id="%s" style="display:none">, %s </span>'
647 html_tmpl = '<span id="%s" style="display:none">, %s </span>'
648 else:
648 else:
649 html_tmpl = '<span id="%s"> %s </span>'
649 html_tmpl = '<span id="%s"> %s </span>'
650
650
651 morelinks = ', '.join(
651 morelinks = ', '.join(
652 [lnk(rev, repo_name) for rev in revs[revs_limit:]]
652 [lnk(rev, repo_name) for rev in revs[revs_limit:]]
653 )
653 )
654
654
655 if len(revs_ids) > revs_top_limit:
655 if len(revs_ids) > revs_top_limit:
656 morelinks += ', ...'
656 morelinks += ', ...'
657
657
658 cs_links.append(html_tmpl % (uniq_id, morelinks))
658 cs_links.append(html_tmpl % (uniq_id, morelinks))
659 if len(revs) > 1:
659 if len(revs) > 1:
660 cs_links.append(compare_view)
660 cs_links.append(compare_view)
661 return ''.join(cs_links)
661 return ''.join(cs_links)
662
662
663 def get_fork_name():
663 def get_fork_name():
664 repo_name = action_params
664 repo_name = action_params
665 _url = url('summary_home', repo_name=repo_name)
665 _url = url('summary_home', repo_name=repo_name)
666 return _('fork name %s') % link_to(action_params, _url)
666 return _('fork name %s') % link_to(action_params, _url)
667
667
668 def get_user_name():
668 def get_user_name():
669 user_name = action_params
669 user_name = action_params
670 return user_name
670 return user_name
671
671
672 def get_users_group():
672 def get_users_group():
673 group_name = action_params
673 group_name = action_params
674 return group_name
674 return group_name
675
675
676 def get_pull_request():
676 def get_pull_request():
677 pull_request_id = action_params
677 pull_request_id = action_params
678 deleted = user_log.repository is None
678 deleted = user_log.repository is None
679 if deleted:
679 if deleted:
680 repo_name = user_log.repository_name
680 repo_name = user_log.repository_name
681 else:
681 else:
682 repo_name = user_log.repository.repo_name
682 repo_name = user_log.repository.repo_name
683 return link_to(_('Pull request #%s') % pull_request_id,
683 return link_to(_('Pull request #%s') % pull_request_id,
684 url('pullrequest_show', repo_name=repo_name,
684 url('pullrequest_show', repo_name=repo_name,
685 pull_request_id=pull_request_id))
685 pull_request_id=pull_request_id))
686
686
687 # action : translated str, callback(extractor), icon
687 # action : translated str, callback(extractor), icon
688 action_map = {
688 action_map = {
689 'user_deleted_repo': (_('[deleted] repository'),
689 'user_deleted_repo': (_('[deleted] repository'),
690 None, 'database_delete.png'),
690 None, 'database_delete.png'),
691 'user_created_repo': (_('[created] repository'),
691 'user_created_repo': (_('[created] repository'),
692 None, 'database_add.png'),
692 None, 'database_add.png'),
693 'user_created_fork': (_('[created] repository as fork'),
693 'user_created_fork': (_('[created] repository as fork'),
694 None, 'arrow_divide.png'),
694 None, 'arrow_divide.png'),
695 'user_forked_repo': (_('[forked] repository'),
695 'user_forked_repo': (_('[forked] repository'),
696 get_fork_name, 'arrow_divide.png'),
696 get_fork_name, 'arrow_divide.png'),
697 'user_updated_repo': (_('[updated] repository'),
697 'user_updated_repo': (_('[updated] repository'),
698 None, 'database_edit.png'),
698 None, 'database_edit.png'),
699 'admin_deleted_repo': (_('[delete] repository'),
699 'admin_deleted_repo': (_('[delete] repository'),
700 None, 'database_delete.png'),
700 None, 'database_delete.png'),
701 'admin_created_repo': (_('[created] repository'),
701 'admin_created_repo': (_('[created] repository'),
702 None, 'database_add.png'),
702 None, 'database_add.png'),
703 'admin_forked_repo': (_('[forked] repository'),
703 'admin_forked_repo': (_('[forked] repository'),
704 None, 'arrow_divide.png'),
704 None, 'arrow_divide.png'),
705 'admin_updated_repo': (_('[updated] repository'),
705 'admin_updated_repo': (_('[updated] repository'),
706 None, 'database_edit.png'),
706 None, 'database_edit.png'),
707 'admin_created_user': (_('[created] user'),
707 'admin_created_user': (_('[created] user'),
708 get_user_name, 'user_add.png'),
708 get_user_name, 'user_add.png'),
709 'admin_updated_user': (_('[updated] user'),
709 'admin_updated_user': (_('[updated] user'),
710 get_user_name, 'user_edit.png'),
710 get_user_name, 'user_edit.png'),
711 'admin_created_users_group': (_('[created] user group'),
711 'admin_created_users_group': (_('[created] user group'),
712 get_users_group, 'group_add.png'),
712 get_users_group, 'group_add.png'),
713 'admin_updated_users_group': (_('[updated] user group'),
713 'admin_updated_users_group': (_('[updated] user group'),
714 get_users_group, 'group_edit.png'),
714 get_users_group, 'group_edit.png'),
715 'user_commented_revision': (_('[commented] on revision in repository'),
715 'user_commented_revision': (_('[commented] on revision in repository'),
716 get_cs_links, 'comment_add.png'),
716 get_cs_links, 'comment_add.png'),
717 'user_commented_pull_request': (_('[commented] on pull request for'),
717 'user_commented_pull_request': (_('[commented] on pull request for'),
718 get_pull_request, 'comment_add.png'),
718 get_pull_request, 'comment_add.png'),
719 'user_closed_pull_request': (_('[closed] pull request for'),
719 'user_closed_pull_request': (_('[closed] pull request for'),
720 get_pull_request, 'tick.png'),
720 get_pull_request, 'tick.png'),
721 'push': (_('[pushed] into'),
721 'push': (_('[pushed] into'),
722 get_cs_links, 'script_add.png'),
722 get_cs_links, 'script_add.png'),
723 'push_local': (_('[committed via RhodeCode] into repository'),
723 'push_local': (_('[committed via RhodeCode] into repository'),
724 get_cs_links, 'script_edit.png'),
724 get_cs_links, 'script_edit.png'),
725 'push_remote': (_('[pulled from remote] into repository'),
725 'push_remote': (_('[pulled from remote] into repository'),
726 get_cs_links, 'connect.png'),
726 get_cs_links, 'connect.png'),
727 'pull': (_('[pulled] from'),
727 'pull': (_('[pulled] from'),
728 None, 'down_16.png'),
728 None, 'down_16.png'),
729 'started_following_repo': (_('[started following] repository'),
729 'started_following_repo': (_('[started following] repository'),
730 None, 'heart_add.png'),
730 None, 'heart_add.png'),
731 'stopped_following_repo': (_('[stopped following] repository'),
731 'stopped_following_repo': (_('[stopped following] repository'),
732 None, 'heart_delete.png'),
732 None, 'heart_delete.png'),
733 }
733 }
734
734
735 action_str = action_map.get(action, action)
735 action_str = action_map.get(action, action)
736 if feed:
736 if feed:
737 action = action_str[0].replace('[', '').replace(']', '')
737 action = action_str[0].replace('[', '').replace(']', '')
738 else:
738 else:
739 action = action_str[0]\
739 action = action_str[0]\
740 .replace('[', '<span class="journal_highlight">')\
740 .replace('[', '<span class="journal_highlight">')\
741 .replace(']', '</span>')
741 .replace(']', '</span>')
742
742
743 action_params_func = lambda: ""
743 action_params_func = lambda: ""
744
744
745 if callable(action_str[1]):
745 if callable(action_str[1]):
746 action_params_func = action_str[1]
746 action_params_func = action_str[1]
747
747
748 def action_parser_icon():
748 def action_parser_icon():
749 action = user_log.action
749 action = user_log.action
750 action_params = None
750 action_params = None
751 x = action.split(':')
751 x = action.split(':')
752
752
753 if len(x) > 1:
753 if len(x) > 1:
754 action, action_params = x
754 action, action_params = x
755
755
756 tmpl = """<img src="%s%s" alt="%s"/>"""
756 tmpl = """<img src="%s%s" alt="%s"/>"""
757 ico = action_map.get(action, ['', '', ''])[2]
757 ico = action_map.get(action, ['', '', ''])[2]
758 return literal(tmpl % ((url('/images/icons/')), ico, action))
758 return literal(tmpl % ((url('/images/icons/')), ico, action))
759
759
760 # returned callbacks we need to call to get
760 # returned callbacks we need to call to get
761 return [lambda: literal(action), action_params_func, action_parser_icon]
761 return [lambda: literal(action), action_params_func, action_parser_icon]
762
762
763
763
764
764
765 #==============================================================================
765 #==============================================================================
766 # PERMS
766 # PERMS
767 #==============================================================================
767 #==============================================================================
768 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
768 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
769 HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \
769 HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \
770 HasReposGroupPermissionAny
770 HasReposGroupPermissionAny
771
771
772
772
773 #==============================================================================
773 #==============================================================================
774 # GRAVATAR URL
774 # GRAVATAR URL
775 #==============================================================================
775 #==============================================================================
776
776
777 def gravatar_url(email_address, size=30):
777 def gravatar_url(email_address, size=30):
778 from pylons import url # doh, we need to re-import url to mock it later
778 from pylons import url # doh, we need to re-import url to mock it later
779 _def = 'anonymous@rhodecode.org'
779 _def = 'anonymous@rhodecode.org'
780 use_gravatar = str2bool(config['app_conf'].get('use_gravatar'))
780 use_gravatar = str2bool(config['app_conf'].get('use_gravatar'))
781 email_address = email_address or _def
781 email_address = email_address or _def
782 if (not use_gravatar or not email_address or email_address == _def):
782 if (not use_gravatar or not email_address or email_address == _def):
783 f = lambda a, l: min(l, key=lambda x: abs(x - a))
783 f = lambda a, l: min(l, key=lambda x: abs(x - a))
784 return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30]))
784 return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30]))
785
785
786 if use_gravatar and config['app_conf'].get('alternative_gravatar_url'):
786 if use_gravatar and config['app_conf'].get('alternative_gravatar_url'):
787 tmpl = config['app_conf'].get('alternative_gravatar_url', '')
787 tmpl = config['app_conf'].get('alternative_gravatar_url', '')
788 parsed_url = urlparse.urlparse(url.current(qualified=True))
788 parsed_url = urlparse.urlparse(url.current(qualified=True))
789 tmpl = tmpl.replace('{email}', email_address)\
789 tmpl = tmpl.replace('{email}', email_address)\
790 .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \
790 .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \
791 .replace('{netloc}', parsed_url.netloc)\
791 .replace('{netloc}', parsed_url.netloc)\
792 .replace('{scheme}', parsed_url.scheme)\
792 .replace('{scheme}', parsed_url.scheme)\
793 .replace('{size}', str(size))
793 .replace('{size}', str(size))
794 return tmpl
794 return tmpl
795
795
796 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
796 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
797 default = 'identicon'
797 default = 'identicon'
798 baseurl_nossl = "http://www.gravatar.com/avatar/"
798 baseurl_nossl = "http://www.gravatar.com/avatar/"
799 baseurl_ssl = "https://secure.gravatar.com/avatar/"
799 baseurl_ssl = "https://secure.gravatar.com/avatar/"
800 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
800 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
801
801
802 if isinstance(email_address, unicode):
802 if isinstance(email_address, unicode):
803 #hashlib crashes on unicode items
803 #hashlib crashes on unicode items
804 email_address = safe_str(email_address)
804 email_address = safe_str(email_address)
805 # construct the url
805 # construct the url
806 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
806 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
807 gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
807 gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
808
808
809 return gravatar_url
809 return gravatar_url
810
810
811
811
812 class Page(_Page):
813 """
814 Custom pager to match rendering style with YUI paginator
815 """
816
817 def _get_pos(self, cur_page, max_page, items):
818 edge = (items / 2) + 1
819 if (cur_page <= edge):
820 radius = max(items / 2, items - cur_page)
821 elif (max_page - cur_page) < edge:
822 radius = (items - 1) - (max_page - cur_page)
823 else:
824 radius = items / 2
825
826 left = max(1, (cur_page - (radius)))
827 right = min(max_page, cur_page + (radius))
828 return left, cur_page, right
829
830 def _range(self, regexp_match):
831 """
832 Return range of linked pages (e.g. '1 2 [3] 4 5 6 7 8').
833
834 Arguments:
835
836 regexp_match
837 A "re" (regular expressions) match object containing the
838 radius of linked pages around the current page in
839 regexp_match.group(1) as a string
840
841 This function is supposed to be called as a callable in
842 re.sub.
843
844 """
845 radius = int(regexp_match.group(1))
846
847 # Compute the first and last page number within the radius
848 # e.g. '1 .. 5 6 [7] 8 9 .. 12'
849 # -> leftmost_page = 5
850 # -> rightmost_page = 9
851 leftmost_page, _cur, rightmost_page = self._get_pos(self.page,
852 self.last_page,
853 (radius * 2) + 1)
854 nav_items = []
855
856 # Create a link to the first page (unless we are on the first page
857 # or there would be no need to insert '..' spacers)
858 if self.page != self.first_page and self.first_page < leftmost_page:
859 nav_items.append(self._pagerlink(self.first_page, self.first_page))
860
861 # Insert dots if there are pages between the first page
862 # and the currently displayed page range
863 if leftmost_page - self.first_page > 1:
864 # Wrap in a SPAN tag if nolink_attr is set
865 text = '..'
866 if self.dotdot_attr:
867 text = HTML.span(c=text, **self.dotdot_attr)
868 nav_items.append(text)
869
870 for thispage in xrange(leftmost_page, rightmost_page + 1):
871 # Hilight the current page number and do not use a link
872 if thispage == self.page:
873 text = '%s' % (thispage,)
874 # Wrap in a SPAN tag if nolink_attr is set
875 if self.curpage_attr:
876 text = HTML.span(c=text, **self.curpage_attr)
877 nav_items.append(text)
878 # Otherwise create just a link to that page
879 else:
880 text = '%s' % (thispage,)
881 nav_items.append(self._pagerlink(thispage, text))
882
883 # Insert dots if there are pages between the displayed
884 # page numbers and the end of the page range
885 if self.last_page - rightmost_page > 1:
886 text = '..'
887 # Wrap in a SPAN tag if nolink_attr is set
888 if self.dotdot_attr:
889 text = HTML.span(c=text, **self.dotdot_attr)
890 nav_items.append(text)
891
892 # Create a link to the very last page (unless we are on the last
893 # page or there would be no need to insert '..' spacers)
894 if self.page != self.last_page and rightmost_page < self.last_page:
895 nav_items.append(self._pagerlink(self.last_page, self.last_page))
896
897 return self.separator.join(nav_items)
898
899 def pager(self, format='~2~', page_param='page', partial_param='partial',
900 show_if_single_page=False, separator=' ', onclick=None,
901 symbol_first='<<', symbol_last='>>',
902 symbol_previous='<', symbol_next='>',
903 link_attr={'class': 'pager_link'},
904 curpage_attr={'class': 'pager_curpage'},
905 dotdot_attr={'class': 'pager_dotdot'}, **kwargs):
906
907 self.curpage_attr = curpage_attr
908 self.separator = separator
909 self.pager_kwargs = kwargs
910 self.page_param = page_param
911 self.partial_param = partial_param
912 self.onclick = onclick
913 self.link_attr = link_attr
914 self.dotdot_attr = dotdot_attr
915
916 # Don't show navigator if there is no more than one page
917 if self.page_count == 0 or (self.page_count == 1 and not show_if_single_page):
918 return ''
919
920 from string import Template
921 # Replace ~...~ in token format by range of pages
922 result = re.sub(r'~(\d+)~', self._range, format)
923
924 # Interpolate '%' variables
925 result = Template(result).safe_substitute({
926 'first_page': self.first_page,
927 'last_page': self.last_page,
928 'page': self.page,
929 'page_count': self.page_count,
930 'items_per_page': self.items_per_page,
931 'first_item': self.first_item,
932 'last_item': self.last_item,
933 'item_count': self.item_count,
934 'link_first': self.page > self.first_page and \
935 self._pagerlink(self.first_page, symbol_first) or '',
936 'link_last': self.page < self.last_page and \
937 self._pagerlink(self.last_page, symbol_last) or '',
938 'link_previous': self.previous_page and \
939 self._pagerlink(self.previous_page, symbol_previous) \
940 or HTML.span(symbol_previous, class_="yui-pg-previous"),
941 'link_next': self.next_page and \
942 self._pagerlink(self.next_page, symbol_next) \
943 or HTML.span(symbol_next, class_="yui-pg-next")
944 })
945
946 return literal(result)
947
948
812 #==============================================================================
949 #==============================================================================
813 # REPO PAGER, PAGER FOR REPOSITORY
950 # REPO PAGER, PAGER FOR REPOSITORY
814 #==============================================================================
951 #==============================================================================
815 class RepoPage(Page):
952 class RepoPage(Page):
816
953
817 def __init__(self, collection, page=1, items_per_page=20,
954 def __init__(self, collection, page=1, items_per_page=20,
818 item_count=None, url=None, **kwargs):
955 item_count=None, url=None, **kwargs):
819
956
820 """Create a "RepoPage" instance. special pager for paging
957 """Create a "RepoPage" instance. special pager for paging
821 repository
958 repository
822 """
959 """
823 self._url_generator = url
960 self._url_generator = url
824
961
825 # Safe the kwargs class-wide so they can be used in the pager() method
962 # Safe the kwargs class-wide so they can be used in the pager() method
826 self.kwargs = kwargs
963 self.kwargs = kwargs
827
964
828 # Save a reference to the collection
965 # Save a reference to the collection
829 self.original_collection = collection
966 self.original_collection = collection
830
967
831 self.collection = collection
968 self.collection = collection
832
969
833 # The self.page is the number of the current page.
970 # The self.page is the number of the current page.
834 # The first page has the number 1!
971 # The first page has the number 1!
835 try:
972 try:
836 self.page = int(page) # make it int() if we get it as a string
973 self.page = int(page) # make it int() if we get it as a string
837 except (ValueError, TypeError):
974 except (ValueError, TypeError):
838 self.page = 1
975 self.page = 1
839
976
840 self.items_per_page = items_per_page
977 self.items_per_page = items_per_page
841
978
842 # Unless the user tells us how many items the collections has
979 # Unless the user tells us how many items the collections has
843 # we calculate that ourselves.
980 # we calculate that ourselves.
844 if item_count is not None:
981 if item_count is not None:
845 self.item_count = item_count
982 self.item_count = item_count
846 else:
983 else:
847 self.item_count = len(self.collection)
984 self.item_count = len(self.collection)
848
985
849 # Compute the number of the first and last available page
986 # Compute the number of the first and last available page
850 if self.item_count > 0:
987 if self.item_count > 0:
851 self.first_page = 1
988 self.first_page = 1
852 self.page_count = int(math.ceil(float(self.item_count) /
989 self.page_count = int(math.ceil(float(self.item_count) /
853 self.items_per_page))
990 self.items_per_page))
854 self.last_page = self.first_page + self.page_count - 1
991 self.last_page = self.first_page + self.page_count - 1
855
992
856 # Make sure that the requested page number is the range of
993 # Make sure that the requested page number is the range of
857 # valid pages
994 # valid pages
858 if self.page > self.last_page:
995 if self.page > self.last_page:
859 self.page = self.last_page
996 self.page = self.last_page
860 elif self.page < self.first_page:
997 elif self.page < self.first_page:
861 self.page = self.first_page
998 self.page = self.first_page
862
999
863 # Note: the number of items on this page can be less than
1000 # Note: the number of items on this page can be less than
864 # items_per_page if the last page is not full
1001 # items_per_page if the last page is not full
865 self.first_item = max(0, (self.item_count) - (self.page *
1002 self.first_item = max(0, (self.item_count) - (self.page *
866 items_per_page))
1003 items_per_page))
867 self.last_item = ((self.item_count - 1) - items_per_page *
1004 self.last_item = ((self.item_count - 1) - items_per_page *
868 (self.page - 1))
1005 (self.page - 1))
869
1006
870 self.items = list(self.collection[self.first_item:self.last_item + 1])
1007 self.items = list(self.collection[self.first_item:self.last_item + 1])
871
1008
872 # Links to previous and next page
1009 # Links to previous and next page
873 if self.page > self.first_page:
1010 if self.page > self.first_page:
874 self.previous_page = self.page - 1
1011 self.previous_page = self.page - 1
875 else:
1012 else:
876 self.previous_page = None
1013 self.previous_page = None
877
1014
878 if self.page < self.last_page:
1015 if self.page < self.last_page:
879 self.next_page = self.page + 1
1016 self.next_page = self.page + 1
880 else:
1017 else:
881 self.next_page = None
1018 self.next_page = None
882
1019
883 # No items available
1020 # No items available
884 else:
1021 else:
885 self.first_page = None
1022 self.first_page = None
886 self.page_count = 0
1023 self.page_count = 0
887 self.last_page = None
1024 self.last_page = None
888 self.first_item = None
1025 self.first_item = None
889 self.last_item = None
1026 self.last_item = None
890 self.previous_page = None
1027 self.previous_page = None
891 self.next_page = None
1028 self.next_page = None
892 self.items = []
1029 self.items = []
893
1030
894 # This is a subclass of the 'list' type. Initialise the list now.
1031 # This is a subclass of the 'list' type. Initialise the list now.
895 list.__init__(self, reversed(self.items))
1032 list.__init__(self, reversed(self.items))
896
1033
897
1034
898 def changed_tooltip(nodes):
1035 def changed_tooltip(nodes):
899 """
1036 """
900 Generates a html string for changed nodes in changeset page.
1037 Generates a html string for changed nodes in changeset page.
901 It limits the output to 30 entries
1038 It limits the output to 30 entries
902
1039
903 :param nodes: LazyNodesGenerator
1040 :param nodes: LazyNodesGenerator
904 """
1041 """
905 if nodes:
1042 if nodes:
906 pref = ': <br/> '
1043 pref = ': <br/> '
907 suf = ''
1044 suf = ''
908 if len(nodes) > 30:
1045 if len(nodes) > 30:
909 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
1046 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
910 return literal(pref + '<br/> '.join([safe_unicode(x.path)
1047 return literal(pref + '<br/> '.join([safe_unicode(x.path)
911 for x in nodes[:30]]) + suf)
1048 for x in nodes[:30]]) + suf)
912 else:
1049 else:
913 return ': ' + _('No Files')
1050 return ': ' + _('No Files')
914
1051
915
1052
916 def repo_link(groups_and_repos):
1053 def repo_link(groups_and_repos):
917 """
1054 """
918 Makes a breadcrumbs link to repo within a group
1055 Makes a breadcrumbs link to repo within a group
919 joins &raquo; on each group to create a fancy link
1056 joins &raquo; on each group to create a fancy link
920
1057
921 ex::
1058 ex::
922 group >> subgroup >> repo
1059 group >> subgroup >> repo
923
1060
924 :param groups_and_repos:
1061 :param groups_and_repos:
925 :param last_url:
1062 :param last_url:
926 """
1063 """
927 groups, just_name, repo_name = groups_and_repos
1064 groups, just_name, repo_name = groups_and_repos
928 last_url = url('summary_home', repo_name=repo_name)
1065 last_url = url('summary_home', repo_name=repo_name)
929 last_link = link_to(just_name, last_url)
1066 last_link = link_to(just_name, last_url)
930
1067
931 def make_link(group):
1068 def make_link(group):
932 return link_to(group.name,
1069 return link_to(group.name,
933 url('repos_group_home', group_name=group.group_name))
1070 url('repos_group_home', group_name=group.group_name))
934 return literal(' &raquo; '.join(map(make_link, groups) + ['<span>%s</span>' % last_link]))
1071 return literal(' &raquo; '.join(map(make_link, groups) + ['<span>%s</span>' % last_link]))
935
1072
936
1073
937 def fancy_file_stats(stats):
1074 def fancy_file_stats(stats):
938 """
1075 """
939 Displays a fancy two colored bar for number of added/deleted
1076 Displays a fancy two colored bar for number of added/deleted
940 lines of code on file
1077 lines of code on file
941
1078
942 :param stats: two element list of added/deleted lines of code
1079 :param stats: two element list of added/deleted lines of code
943 """
1080 """
944 def cgen(l_type, a_v, d_v):
1081 def cgen(l_type, a_v, d_v):
945 mapping = {'tr': 'top-right-rounded-corner-mid',
1082 mapping = {'tr': 'top-right-rounded-corner-mid',
946 'tl': 'top-left-rounded-corner-mid',
1083 'tl': 'top-left-rounded-corner-mid',
947 'br': 'bottom-right-rounded-corner-mid',
1084 'br': 'bottom-right-rounded-corner-mid',
948 'bl': 'bottom-left-rounded-corner-mid'}
1085 'bl': 'bottom-left-rounded-corner-mid'}
949 map_getter = lambda x: mapping[x]
1086 map_getter = lambda x: mapping[x]
950
1087
951 if l_type == 'a' and d_v:
1088 if l_type == 'a' and d_v:
952 #case when added and deleted are present
1089 #case when added and deleted are present
953 return ' '.join(map(map_getter, ['tl', 'bl']))
1090 return ' '.join(map(map_getter, ['tl', 'bl']))
954
1091
955 if l_type == 'a' and not d_v:
1092 if l_type == 'a' and not d_v:
956 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
1093 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
957
1094
958 if l_type == 'd' and a_v:
1095 if l_type == 'd' and a_v:
959 return ' '.join(map(map_getter, ['tr', 'br']))
1096 return ' '.join(map(map_getter, ['tr', 'br']))
960
1097
961 if l_type == 'd' and not a_v:
1098 if l_type == 'd' and not a_v:
962 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
1099 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
963
1100
964 a, d = stats[0], stats[1]
1101 a, d = stats[0], stats[1]
965 width = 100
1102 width = 100
966
1103
967 if a == 'b':
1104 if a == 'b':
968 #binary mode
1105 #binary mode
969 b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
1106 b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
970 b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
1107 b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
971 return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
1108 return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
972
1109
973 t = stats[0] + stats[1]
1110 t = stats[0] + stats[1]
974 unit = float(width) / (t or 1)
1111 unit = float(width) / (t or 1)
975
1112
976 # needs > 9% of width to be visible or 0 to be hidden
1113 # needs > 9% of width to be visible or 0 to be hidden
977 a_p = max(9, unit * a) if a > 0 else 0
1114 a_p = max(9, unit * a) if a > 0 else 0
978 d_p = max(9, unit * d) if d > 0 else 0
1115 d_p = max(9, unit * d) if d > 0 else 0
979 p_sum = a_p + d_p
1116 p_sum = a_p + d_p
980
1117
981 if p_sum > width:
1118 if p_sum > width:
982 #adjust the percentage to be == 100% since we adjusted to 9
1119 #adjust the percentage to be == 100% since we adjusted to 9
983 if a_p > d_p:
1120 if a_p > d_p:
984 a_p = a_p - (p_sum - width)
1121 a_p = a_p - (p_sum - width)
985 else:
1122 else:
986 d_p = d_p - (p_sum - width)
1123 d_p = d_p - (p_sum - width)
987
1124
988 a_v = a if a > 0 else ''
1125 a_v = a if a > 0 else ''
989 d_v = d if d > 0 else ''
1126 d_v = d if d > 0 else ''
990
1127
991 d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
1128 d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
992 cgen('a', a_v, d_v), a_p, a_v
1129 cgen('a', a_v, d_v), a_p, a_v
993 )
1130 )
994 d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
1131 d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
995 cgen('d', a_v, d_v), d_p, d_v
1132 cgen('d', a_v, d_v), d_p, d_v
996 )
1133 )
997 return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
1134 return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
998
1135
999
1136
1000 def urlify_text(text_, safe=True):
1137 def urlify_text(text_, safe=True):
1001 """
1138 """
1002 Extrac urls from text and make html links out of them
1139 Extrac urls from text and make html links out of them
1003
1140
1004 :param text_:
1141 :param text_:
1005 """
1142 """
1006
1143
1007 url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
1144 url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
1008 '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
1145 '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
1009
1146
1010 def url_func(match_obj):
1147 def url_func(match_obj):
1011 url_full = match_obj.groups()[0]
1148 url_full = match_obj.groups()[0]
1012 return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
1149 return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
1013 _newtext = url_pat.sub(url_func, text_)
1150 _newtext = url_pat.sub(url_func, text_)
1014 if safe:
1151 if safe:
1015 return literal(_newtext)
1152 return literal(_newtext)
1016 return _newtext
1153 return _newtext
1017
1154
1018
1155
1019 def urlify_changesets(text_, repository):
1156 def urlify_changesets(text_, repository):
1020 """
1157 """
1021 Extract revision ids from changeset and make link from them
1158 Extract revision ids from changeset and make link from them
1022
1159
1023 :param text_:
1160 :param text_:
1024 :param repository: repo name to build the URL with
1161 :param repository: repo name to build the URL with
1025 """
1162 """
1026 from pylons import url # doh, we need to re-import url to mock it later
1163 from pylons import url # doh, we need to re-import url to mock it later
1027 URL_PAT = re.compile(r'(^|\s)([0-9a-fA-F]{12,40})($|\s)')
1164 URL_PAT = re.compile(r'(^|\s)([0-9a-fA-F]{12,40})($|\s)')
1028
1165
1029 def url_func(match_obj):
1166 def url_func(match_obj):
1030 rev = match_obj.groups()[1]
1167 rev = match_obj.groups()[1]
1031 pref = match_obj.groups()[0]
1168 pref = match_obj.groups()[0]
1032 suf = match_obj.groups()[2]
1169 suf = match_obj.groups()[2]
1033
1170
1034 tmpl = (
1171 tmpl = (
1035 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1172 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1036 '%(rev)s</a>%(suf)s'
1173 '%(rev)s</a>%(suf)s'
1037 )
1174 )
1038 return tmpl % {
1175 return tmpl % {
1039 'pref': pref,
1176 'pref': pref,
1040 'cls': 'revision-link',
1177 'cls': 'revision-link',
1041 'url': url('changeset_home', repo_name=repository, revision=rev),
1178 'url': url('changeset_home', repo_name=repository, revision=rev),
1042 'rev': rev,
1179 'rev': rev,
1043 'suf': suf
1180 'suf': suf
1044 }
1181 }
1045
1182
1046 newtext = URL_PAT.sub(url_func, text_)
1183 newtext = URL_PAT.sub(url_func, text_)
1047
1184
1048 return newtext
1185 return newtext
1049
1186
1050
1187
1051 def urlify_commit(text_, repository=None, link_=None):
1188 def urlify_commit(text_, repository=None, link_=None):
1052 """
1189 """
1053 Parses given text message and makes proper links.
1190 Parses given text message and makes proper links.
1054 issues are linked to given issue-server, and rest is a changeset link
1191 issues are linked to given issue-server, and rest is a changeset link
1055 if link_ is given, in other case it's a plain text
1192 if link_ is given, in other case it's a plain text
1056
1193
1057 :param text_:
1194 :param text_:
1058 :param repository:
1195 :param repository:
1059 :param link_: changeset link
1196 :param link_: changeset link
1060 """
1197 """
1061 import traceback
1198 import traceback
1062 from pylons import url # doh, we need to re-import url to mock it later
1199 from pylons import url # doh, we need to re-import url to mock it later
1063
1200
1064 def escaper(string):
1201 def escaper(string):
1065 return string.replace('<', '&lt;').replace('>', '&gt;')
1202 return string.replace('<', '&lt;').replace('>', '&gt;')
1066
1203
1067 def linkify_others(t, l):
1204 def linkify_others(t, l):
1068 urls = re.compile(r'(\<a.*?\<\/a\>)',)
1205 urls = re.compile(r'(\<a.*?\<\/a\>)',)
1069 links = []
1206 links = []
1070 for e in urls.split(t):
1207 for e in urls.split(t):
1071 if not urls.match(e):
1208 if not urls.match(e):
1072 links.append('<a class="message-link" href="%s">%s</a>' % (l, e))
1209 links.append('<a class="message-link" href="%s">%s</a>' % (l, e))
1073 else:
1210 else:
1074 links.append(e)
1211 links.append(e)
1075
1212
1076 return ''.join(links)
1213 return ''.join(links)
1077
1214
1078 # urlify changesets - extrac revisions and make link out of them
1215 # urlify changesets - extrac revisions and make link out of them
1079 newtext = urlify_changesets(escaper(text_), repository)
1216 newtext = urlify_changesets(escaper(text_), repository)
1080
1217
1081 # extract http/https links and make them real urls
1218 # extract http/https links and make them real urls
1082 newtext = urlify_text(newtext, safe=False)
1219 newtext = urlify_text(newtext, safe=False)
1083
1220
1084 try:
1221 try:
1085 from rhodecode import CONFIG
1222 from rhodecode import CONFIG
1086 conf = CONFIG
1223 conf = CONFIG
1087
1224
1088 # allow multiple issue servers to be used
1225 # allow multiple issue servers to be used
1089 valid_indices = [
1226 valid_indices = [
1090 x.group(1)
1227 x.group(1)
1091 for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys())
1228 for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys())
1092 if x and 'issue_server_link%s' % x.group(1) in conf
1229 if x and 'issue_server_link%s' % x.group(1) in conf
1093 and 'issue_prefix%s' % x.group(1) in conf
1230 and 'issue_prefix%s' % x.group(1) in conf
1094 ]
1231 ]
1095
1232
1096 log.debug('found issue server suffixes `%s` during valuation of: %s'
1233 log.debug('found issue server suffixes `%s` during valuation of: %s'
1097 % (','.join(valid_indices), newtext))
1234 % (','.join(valid_indices), newtext))
1098
1235
1099 for pattern_index in valid_indices:
1236 for pattern_index in valid_indices:
1100 ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index)
1237 ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index)
1101 ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index)
1238 ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index)
1102 ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index)
1239 ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index)
1103
1240
1104 log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s'
1241 log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s'
1105 % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK,
1242 % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK,
1106 ISSUE_PREFIX))
1243 ISSUE_PREFIX))
1107
1244
1108 URL_PAT = re.compile(r'%s' % ISSUE_PATTERN)
1245 URL_PAT = re.compile(r'%s' % ISSUE_PATTERN)
1109
1246
1110 def url_func(match_obj):
1247 def url_func(match_obj):
1111 pref = ''
1248 pref = ''
1112 if match_obj.group().startswith(' '):
1249 if match_obj.group().startswith(' '):
1113 pref = ' '
1250 pref = ' '
1114
1251
1115 issue_id = ''.join(match_obj.groups())
1252 issue_id = ''.join(match_obj.groups())
1116 tmpl = (
1253 tmpl = (
1117 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1254 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1118 '%(issue-prefix)s%(id-repr)s'
1255 '%(issue-prefix)s%(id-repr)s'
1119 '</a>'
1256 '</a>'
1120 )
1257 )
1121 url = ISSUE_SERVER_LNK.replace('{id}', issue_id)
1258 url = ISSUE_SERVER_LNK.replace('{id}', issue_id)
1122 if repository:
1259 if repository:
1123 url = url.replace('{repo}', repository)
1260 url = url.replace('{repo}', repository)
1124 repo_name = repository.split(URL_SEP)[-1]
1261 repo_name = repository.split(URL_SEP)[-1]
1125 url = url.replace('{repo_name}', repo_name)
1262 url = url.replace('{repo_name}', repo_name)
1126
1263
1127 return tmpl % {
1264 return tmpl % {
1128 'pref': pref,
1265 'pref': pref,
1129 'cls': 'issue-tracker-link',
1266 'cls': 'issue-tracker-link',
1130 'url': url,
1267 'url': url,
1131 'id-repr': issue_id,
1268 'id-repr': issue_id,
1132 'issue-prefix': ISSUE_PREFIX,
1269 'issue-prefix': ISSUE_PREFIX,
1133 'serv': ISSUE_SERVER_LNK,
1270 'serv': ISSUE_SERVER_LNK,
1134 }
1271 }
1135 newtext = URL_PAT.sub(url_func, newtext)
1272 newtext = URL_PAT.sub(url_func, newtext)
1136 log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext))
1273 log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext))
1137
1274
1138 # if we actually did something above
1275 # if we actually did something above
1139 if link_:
1276 if link_:
1140 # wrap not links into final link => link_
1277 # wrap not links into final link => link_
1141 newtext = linkify_others(newtext, link_)
1278 newtext = linkify_others(newtext, link_)
1142 except Exception:
1279 except Exception:
1143 log.error(traceback.format_exc())
1280 log.error(traceback.format_exc())
1144 pass
1281 pass
1145
1282
1146 return literal(newtext)
1283 return literal(newtext)
1147
1284
1148
1285
1149 def rst(source):
1286 def rst(source):
1150 return literal('<div class="rst-block">%s</div>' %
1287 return literal('<div class="rst-block">%s</div>' %
1151 MarkupRenderer.rst(source))
1288 MarkupRenderer.rst(source))
1152
1289
1153
1290
1154 def rst_w_mentions(source):
1291 def rst_w_mentions(source):
1155 """
1292 """
1156 Wrapped rst renderer with @mention highlighting
1293 Wrapped rst renderer with @mention highlighting
1157
1294
1158 :param source:
1295 :param source:
1159 """
1296 """
1160 return literal('<div class="rst-block">%s</div>' %
1297 return literal('<div class="rst-block">%s</div>' %
1161 MarkupRenderer.rst_with_mentions(source))
1298 MarkupRenderer.rst_with_mentions(source))
1162
1299
1163
1300
1164 def changeset_status(repo, revision):
1301 def changeset_status(repo, revision):
1165 return ChangesetStatusModel().get_status(repo, revision)
1302 return ChangesetStatusModel().get_status(repo, revision)
1166
1303
1167
1304
1168 def changeset_status_lbl(changeset_status):
1305 def changeset_status_lbl(changeset_status):
1169 return dict(ChangesetStatus.STATUSES).get(changeset_status)
1306 return dict(ChangesetStatus.STATUSES).get(changeset_status)
1170
1307
1171
1308
1172 def get_permission_name(key):
1309 def get_permission_name(key):
1173 return dict(Permission.PERMS).get(key)
1310 return dict(Permission.PERMS).get(key)
1174
1311
1175
1312
1176 def journal_filter_help():
1313 def journal_filter_help():
1177 return _(textwrap.dedent('''
1314 return _(textwrap.dedent('''
1178 Example filter terms:
1315 Example filter terms:
1179 repository:vcs
1316 repository:vcs
1180 username:marcin
1317 username:marcin
1181 action:*push*
1318 action:*push*
1182 ip:127.0.0.1
1319 ip:127.0.0.1
1183 date:20120101
1320 date:20120101
1184 date:[20120101100000 TO 20120102]
1321 date:[20120101100000 TO 20120102]
1185
1322
1186 Generate wildcards using '*' character:
1323 Generate wildcards using '*' character:
1187 "repositroy:vcs*" - search everything starting with 'vcs'
1324 "repositroy:vcs*" - search everything starting with 'vcs'
1188 "repository:*vcs*" - search for repository containing 'vcs'
1325 "repository:*vcs*" - search for repository containing 'vcs'
1189
1326
1190 Optional AND / OR operators in queries
1327 Optional AND / OR operators in queries
1191 "repository:vcs OR repository:test"
1328 "repository:vcs OR repository:test"
1192 "username:test AND repository:test*"
1329 "username:test AND repository:test*"
1193 '''))
1330 '''))
1194
1331
1195
1332
1196 def not_mapped_error(repo_name):
1333 def not_mapped_error(repo_name):
1197 flash(_('%s repository is not mapped to db perhaps'
1334 flash(_('%s repository is not mapped to db perhaps'
1198 ' it was created or renamed from the filesystem'
1335 ' it was created or renamed from the filesystem'
1199 ' please run the application again'
1336 ' please run the application again'
1200 ' in order to rescan repositories') % repo_name, category='error')
1337 ' in order to rescan repositories') % repo_name, category='error')
1201
1338
1202
1339
1203 def ip_range(ip_addr):
1340 def ip_range(ip_addr):
1204 from rhodecode.model.db import UserIpMap
1341 from rhodecode.model.db import UserIpMap
1205 s, e = UserIpMap._get_ip_range(ip_addr)
1342 s, e = UserIpMap._get_ip_range(ip_addr)
1206 return '%s - %s' % (s, e)
1343 return '%s - %s' % (s, e)
@@ -1,4907 +1,4907 b''
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 {
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 border: 0;
2 border: 0;
3 outline: 0;
3 outline: 0;
4 font-size: 100%;
4 font-size: 100%;
5 vertical-align: baseline;
5 vertical-align: baseline;
6 background: transparent;
6 background: transparent;
7 margin: 0;
7 margin: 0;
8 padding: 0;
8 padding: 0;
9 }
9 }
10
10
11 body {
11 body {
12 line-height: 1;
12 line-height: 1;
13 height: 100%;
13 height: 100%;
14 background: url("../images/background.png") repeat scroll 0 0 #B0B0B0;
14 background: url("../images/background.png") repeat scroll 0 0 #B0B0B0;
15 font-family: Lucida Grande, Verdana, Lucida Sans Regular,
15 font-family: Lucida Grande, Verdana, Lucida Sans Regular,
16 Lucida Sans Unicode, Arial, sans-serif; font-size : 12px;
16 Lucida Sans Unicode, Arial, sans-serif; font-size : 12px;
17 color: #000;
17 color: #000;
18 margin: 0;
18 margin: 0;
19 padding: 0;
19 padding: 0;
20 font-size: 12px;
20 font-size: 12px;
21 }
21 }
22
22
23 ol, ul {
23 ol, ul {
24 list-style: none;
24 list-style: none;
25 }
25 }
26
26
27 blockquote, q {
27 blockquote, q {
28 quotes: none;
28 quotes: none;
29 }
29 }
30
30
31 blockquote:before, blockquote:after, q:before, q:after {
31 blockquote:before, blockquote:after, q:before, q:after {
32 content: none;
32 content: none;
33 }
33 }
34
34
35 :focus {
35 :focus {
36 outline: 0;
36 outline: 0;
37 }
37 }
38
38
39 del {
39 del {
40 text-decoration: line-through;
40 text-decoration: line-through;
41 }
41 }
42
42
43 table {
43 table {
44 border-collapse: collapse;
44 border-collapse: collapse;
45 border-spacing: 0;
45 border-spacing: 0;
46 }
46 }
47
47
48 html {
48 html {
49 height: 100%;
49 height: 100%;
50 }
50 }
51
51
52 a {
52 a {
53 color: #003367;
53 color: #003367;
54 text-decoration: none;
54 text-decoration: none;
55 cursor: pointer;
55 cursor: pointer;
56 }
56 }
57
57
58 a:hover {
58 a:hover {
59 color: #316293;
59 color: #316293;
60 text-decoration: underline;
60 text-decoration: underline;
61 }
61 }
62
62
63 h1, h2, h3, h4, h5, h6,
63 h1, h2, h3, h4, h5, h6,
64 div.h1, div.h2, div.h3, div.h4, div.h5, div.h6 {
64 div.h1, div.h2, div.h3, div.h4, div.h5, div.h6 {
65 color: #292929;
65 color: #292929;
66 font-weight: 700;
66 font-weight: 700;
67 }
67 }
68
68
69 h1, div.h1 {
69 h1, div.h1 {
70 font-size: 22px;
70 font-size: 22px;
71 }
71 }
72
72
73 h2, div.h2 {
73 h2, div.h2 {
74 font-size: 20px;
74 font-size: 20px;
75 }
75 }
76
76
77 h3, div.h3 {
77 h3, div.h3 {
78 font-size: 18px;
78 font-size: 18px;
79 }
79 }
80
80
81 h4, div.h4 {
81 h4, div.h4 {
82 font-size: 16px;
82 font-size: 16px;
83 }
83 }
84
84
85 h5, div.h5 {
85 h5, div.h5 {
86 font-size: 14px;
86 font-size: 14px;
87 }
87 }
88
88
89 h6, div.h6 {
89 h6, div.h6 {
90 font-size: 11px;
90 font-size: 11px;
91 }
91 }
92
92
93 ul.circle {
93 ul.circle {
94 list-style-type: circle;
94 list-style-type: circle;
95 }
95 }
96
96
97 ul.disc {
97 ul.disc {
98 list-style-type: disc;
98 list-style-type: disc;
99 }
99 }
100
100
101 ul.square {
101 ul.square {
102 list-style-type: square;
102 list-style-type: square;
103 }
103 }
104
104
105 ol.lower-roman {
105 ol.lower-roman {
106 list-style-type: lower-roman;
106 list-style-type: lower-roman;
107 }
107 }
108
108
109 ol.upper-roman {
109 ol.upper-roman {
110 list-style-type: upper-roman;
110 list-style-type: upper-roman;
111 }
111 }
112
112
113 ol.lower-alpha {
113 ol.lower-alpha {
114 list-style-type: lower-alpha;
114 list-style-type: lower-alpha;
115 }
115 }
116
116
117 ol.upper-alpha {
117 ol.upper-alpha {
118 list-style-type: upper-alpha;
118 list-style-type: upper-alpha;
119 }
119 }
120
120
121 ol.decimal {
121 ol.decimal {
122 list-style-type: decimal;
122 list-style-type: decimal;
123 }
123 }
124
124
125 div.color {
125 div.color {
126 clear: both;
126 clear: both;
127 overflow: hidden;
127 overflow: hidden;
128 position: absolute;
128 position: absolute;
129 background: #FFF;
129 background: #FFF;
130 margin: 7px 0 0 60px;
130 margin: 7px 0 0 60px;
131 padding: 1px 1px 1px 0;
131 padding: 1px 1px 1px 0;
132 }
132 }
133
133
134 div.color a {
134 div.color a {
135 width: 15px;
135 width: 15px;
136 height: 15px;
136 height: 15px;
137 display: block;
137 display: block;
138 float: left;
138 float: left;
139 margin: 0 0 0 1px;
139 margin: 0 0 0 1px;
140 padding: 0;
140 padding: 0;
141 }
141 }
142
142
143 div.options {
143 div.options {
144 clear: both;
144 clear: both;
145 overflow: hidden;
145 overflow: hidden;
146 position: absolute;
146 position: absolute;
147 background: #FFF;
147 background: #FFF;
148 margin: 7px 0 0 162px;
148 margin: 7px 0 0 162px;
149 padding: 0;
149 padding: 0;
150 }
150 }
151
151
152 div.options a {
152 div.options a {
153 height: 1%;
153 height: 1%;
154 display: block;
154 display: block;
155 text-decoration: none;
155 text-decoration: none;
156 margin: 0;
156 margin: 0;
157 padding: 3px 8px;
157 padding: 3px 8px;
158 }
158 }
159
159
160 .top-left-rounded-corner {
160 .top-left-rounded-corner {
161 -webkit-border-top-left-radius: 8px;
161 -webkit-border-top-left-radius: 8px;
162 -khtml-border-radius-topleft: 8px;
162 -khtml-border-radius-topleft: 8px;
163 border-top-left-radius: 8px;
163 border-top-left-radius: 8px;
164 }
164 }
165
165
166 .top-right-rounded-corner {
166 .top-right-rounded-corner {
167 -webkit-border-top-right-radius: 8px;
167 -webkit-border-top-right-radius: 8px;
168 -khtml-border-radius-topright: 8px;
168 -khtml-border-radius-topright: 8px;
169 border-top-right-radius: 8px;
169 border-top-right-radius: 8px;
170 }
170 }
171
171
172 .bottom-left-rounded-corner {
172 .bottom-left-rounded-corner {
173 -webkit-border-bottom-left-radius: 8px;
173 -webkit-border-bottom-left-radius: 8px;
174 -khtml-border-radius-bottomleft: 8px;
174 -khtml-border-radius-bottomleft: 8px;
175 border-bottom-left-radius: 8px;
175 border-bottom-left-radius: 8px;
176 }
176 }
177
177
178 .bottom-right-rounded-corner {
178 .bottom-right-rounded-corner {
179 -webkit-border-bottom-right-radius: 8px;
179 -webkit-border-bottom-right-radius: 8px;
180 -khtml-border-radius-bottomright: 8px;
180 -khtml-border-radius-bottomright: 8px;
181 border-bottom-right-radius: 8px;
181 border-bottom-right-radius: 8px;
182 }
182 }
183
183
184 .top-left-rounded-corner-mid {
184 .top-left-rounded-corner-mid {
185 -webkit-border-top-left-radius: 4px;
185 -webkit-border-top-left-radius: 4px;
186 -khtml-border-radius-topleft: 4px;
186 -khtml-border-radius-topleft: 4px;
187 border-top-left-radius: 4px;
187 border-top-left-radius: 4px;
188 }
188 }
189
189
190 .top-right-rounded-corner-mid {
190 .top-right-rounded-corner-mid {
191 -webkit-border-top-right-radius: 4px;
191 -webkit-border-top-right-radius: 4px;
192 -khtml-border-radius-topright: 4px;
192 -khtml-border-radius-topright: 4px;
193 border-top-right-radius: 4px;
193 border-top-right-radius: 4px;
194 }
194 }
195
195
196 .bottom-left-rounded-corner-mid {
196 .bottom-left-rounded-corner-mid {
197 -webkit-border-bottom-left-radius: 4px;
197 -webkit-border-bottom-left-radius: 4px;
198 -khtml-border-radius-bottomleft: 4px;
198 -khtml-border-radius-bottomleft: 4px;
199 border-bottom-left-radius: 4px;
199 border-bottom-left-radius: 4px;
200 }
200 }
201
201
202 .bottom-right-rounded-corner-mid {
202 .bottom-right-rounded-corner-mid {
203 -webkit-border-bottom-right-radius: 4px;
203 -webkit-border-bottom-right-radius: 4px;
204 -khtml-border-radius-bottomright: 4px;
204 -khtml-border-radius-bottomright: 4px;
205 border-bottom-right-radius: 4px;
205 border-bottom-right-radius: 4px;
206 }
206 }
207
207
208 .help-block {
208 .help-block {
209 color: #999999;
209 color: #999999;
210 display: block;
210 display: block;
211 margin-bottom: 0;
211 margin-bottom: 0;
212 margin-top: 5px;
212 margin-top: 5px;
213 }
213 }
214
214
215 .empty_data {
215 .empty_data {
216 color: #B9B9B9;
216 color: #B9B9B9;
217 }
217 }
218
218
219 a.permalink {
219 a.permalink {
220 visibility: hidden;
220 visibility: hidden;
221 position: absolute;
221 position: absolute;
222 margin: 3px 4px;
222 margin: 3px 4px;
223 }
223 }
224
224
225 a.permalink:hover {
225 a.permalink:hover {
226 text-decoration: none;
226 text-decoration: none;
227 }
227 }
228
228
229 h1:hover > a.permalink,
229 h1:hover > a.permalink,
230 h2:hover > a.permalink,
230 h2:hover > a.permalink,
231 h3:hover > a.permalink,
231 h3:hover > a.permalink,
232 h4:hover > a.permalink,
232 h4:hover > a.permalink,
233 h5:hover > a.permalink,
233 h5:hover > a.permalink,
234 h6:hover > a.permalink,
234 h6:hover > a.permalink,
235 div:hover > a.permalink {
235 div:hover > a.permalink {
236 visibility: visible;
236 visibility: visible;
237 }
237 }
238
238
239 #header {
239 #header {
240 }
240 }
241 #header ul#logged-user {
241 #header ul#logged-user {
242 margin-bottom: 5px !important;
242 margin-bottom: 5px !important;
243 -webkit-border-radius: 0px 0px 8px 8px;
243 -webkit-border-radius: 0px 0px 8px 8px;
244 -khtml-border-radius: 0px 0px 8px 8px;
244 -khtml-border-radius: 0px 0px 8px 8px;
245 border-radius: 0px 0px 8px 8px;
245 border-radius: 0px 0px 8px 8px;
246 height: 37px;
246 height: 37px;
247 background-color: #003B76;
247 background-color: #003B76;
248 background-repeat: repeat-x;
248 background-repeat: repeat-x;
249 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
249 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
250 background-image: -moz-linear-gradient(top, #003b76, #00376e);
250 background-image: -moz-linear-gradient(top, #003b76, #00376e);
251 background-image: -ms-linear-gradient(top, #003b76, #00376e);
251 background-image: -ms-linear-gradient(top, #003b76, #00376e);
252 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
252 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
253 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
253 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
254 background-image: -o-linear-gradient(top, #003b76, #00376e);
254 background-image: -o-linear-gradient(top, #003b76, #00376e);
255 background-image: linear-gradient(to bottom, #003b76, #00376e);
255 background-image: linear-gradient(to bottom, #003b76, #00376e);
256 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
256 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
257 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
257 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
258 }
258 }
259
259
260 #header ul#logged-user li {
260 #header ul#logged-user li {
261 list-style: none;
261 list-style: none;
262 float: left;
262 float: left;
263 margin: 8px 0 0;
263 margin: 8px 0 0;
264 padding: 4px 12px;
264 padding: 4px 12px;
265 border-left: 1px solid #316293;
265 border-left: 1px solid #316293;
266 }
266 }
267
267
268 #header ul#logged-user li.first {
268 #header ul#logged-user li.first {
269 border-left: none;
269 border-left: none;
270 margin: 4px;
270 margin: 4px;
271 }
271 }
272
272
273 #header ul#logged-user li.first div.gravatar {
273 #header ul#logged-user li.first div.gravatar {
274 margin-top: -2px;
274 margin-top: -2px;
275 }
275 }
276
276
277 #header ul#logged-user li.first div.account {
277 #header ul#logged-user li.first div.account {
278 padding-top: 4px;
278 padding-top: 4px;
279 float: left;
279 float: left;
280 }
280 }
281
281
282 #header ul#logged-user li.last {
282 #header ul#logged-user li.last {
283 border-right: none;
283 border-right: none;
284 }
284 }
285
285
286 #header ul#logged-user li a {
286 #header ul#logged-user li a {
287 color: #fff;
287 color: #fff;
288 font-weight: 700;
288 font-weight: 700;
289 text-decoration: none;
289 text-decoration: none;
290 }
290 }
291
291
292 #header ul#logged-user li a:hover {
292 #header ul#logged-user li a:hover {
293 text-decoration: underline;
293 text-decoration: underline;
294 }
294 }
295
295
296 #header ul#logged-user li.highlight a {
296 #header ul#logged-user li.highlight a {
297 color: #fff;
297 color: #fff;
298 }
298 }
299
299
300 #header ul#logged-user li.highlight a:hover {
300 #header ul#logged-user li.highlight a:hover {
301 color: #FFF;
301 color: #FFF;
302 }
302 }
303 #header-dd {
303 #header-dd {
304 clear: both;
304 clear: both;
305 position: fixed !important;
305 position: fixed !important;
306 background-color: #003B76;
306 background-color: #003B76;
307 opacity: 0.01;
307 opacity: 0.01;
308 cursor: pointer;
308 cursor: pointer;
309 min-height: 10px;
309 min-height: 10px;
310 width: 100% !important;
310 width: 100% !important;
311 -webkit-border-radius: 0px 0px 4px 4px;
311 -webkit-border-radius: 0px 0px 4px 4px;
312 -khtml-border-radius: 0px 0px 4px 4px;
312 -khtml-border-radius: 0px 0px 4px 4px;
313 border-radius: 0px 0px 4px 4px;
313 border-radius: 0px 0px 4px 4px;
314 }
314 }
315
315
316 #header-dd:hover {
316 #header-dd:hover {
317 opacity: 0.2;
317 opacity: 0.2;
318 -webkit-transition: opacity 0.5s ease-in-out;
318 -webkit-transition: opacity 0.5s ease-in-out;
319 -moz-transition: opacity 0.5s ease-in-out;
319 -moz-transition: opacity 0.5s ease-in-out;
320 transition: opacity 0.5s ease-in-out;
320 transition: opacity 0.5s ease-in-out;
321 }
321 }
322
322
323 #header #header-inner {
323 #header #header-inner {
324 min-height: 44px;
324 min-height: 44px;
325 clear: both;
325 clear: both;
326 position: relative;
326 position: relative;
327 background-color: #003B76;
327 background-color: #003B76;
328 background-repeat: repeat-x;
328 background-repeat: repeat-x;
329 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
329 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
330 background-image: -moz-linear-gradient(top, #003b76, #00376e);
330 background-image: -moz-linear-gradient(top, #003b76, #00376e);
331 background-image: -ms-linear-gradient(top, #003b76, #00376e);
331 background-image: -ms-linear-gradient(top, #003b76, #00376e);
332 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) );
332 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) );
333 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
333 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
334 background-image: -o-linear-gradient(top, #003b76, #00376e);
334 background-image: -o-linear-gradient(top, #003b76, #00376e);
335 background-image: linear-gradient(to bottom, #003b76, #00376e);
335 background-image: linear-gradient(to bottom, #003b76, #00376e);
336 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
336 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
337 margin: 0;
337 margin: 0;
338 padding: 0;
338 padding: 0;
339 display: block;
339 display: block;
340 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
340 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
341 -webkit-border-radius: 0px 0px 4px 4px;
341 -webkit-border-radius: 0px 0px 4px 4px;
342 -khtml-border-radius: 0px 0px 4px 4px;
342 -khtml-border-radius: 0px 0px 4px 4px;
343 border-radius: 0px 0px 4px 4px;
343 border-radius: 0px 0px 4px 4px;
344 }
344 }
345 #header #header-inner.hover {
345 #header #header-inner.hover {
346 width: 100% !important;
346 width: 100% !important;
347 -webkit-border-radius: 0px 0px 0px 0px;
347 -webkit-border-radius: 0px 0px 0px 0px;
348 -khtml-border-radius: 0px 0px 0px 0px;
348 -khtml-border-radius: 0px 0px 0px 0px;
349 border-radius: 0px 0px 0px 0px;
349 border-radius: 0px 0px 0px 0px;
350 position: fixed !important;
350 position: fixed !important;
351 z-index: 10000;
351 z-index: 10000;
352 }
352 }
353
353
354 .ie7 #header #header-inner.hover,
354 .ie7 #header #header-inner.hover,
355 .ie8 #header #header-inner.hover,
355 .ie8 #header #header-inner.hover,
356 .ie9 #header #header-inner.hover
356 .ie9 #header #header-inner.hover
357 {
357 {
358 z-index: auto !important;
358 z-index: auto !important;
359 }
359 }
360
360
361 .header-pos-fix, .anchor {
361 .header-pos-fix, .anchor {
362 margin-top: -46px;
362 margin-top: -46px;
363 padding-top: 46px;
363 padding-top: 46px;
364 }
364 }
365
365
366 #header #header-inner #home a {
366 #header #header-inner #home a {
367 height: 40px;
367 height: 40px;
368 width: 46px;
368 width: 46px;
369 display: block;
369 display: block;
370 background: url("../images/button_home.png");
370 background: url("../images/button_home.png");
371 background-position: 0 0;
371 background-position: 0 0;
372 margin: 0;
372 margin: 0;
373 padding: 0;
373 padding: 0;
374 }
374 }
375
375
376 #header #header-inner #home a:hover {
376 #header #header-inner #home a:hover {
377 background-position: 0 -40px;
377 background-position: 0 -40px;
378 }
378 }
379
379
380 #header #header-inner #logo {
380 #header #header-inner #logo {
381 float: left;
381 float: left;
382 position: absolute;
382 position: absolute;
383 }
383 }
384
384
385 #header #header-inner #logo h1 {
385 #header #header-inner #logo h1 {
386 color: #FFF;
386 color: #FFF;
387 font-size: 20px;
387 font-size: 20px;
388 margin: 12px 0 0 13px;
388 margin: 12px 0 0 13px;
389 padding: 0;
389 padding: 0;
390 }
390 }
391
391
392 #header #header-inner #logo a {
392 #header #header-inner #logo a {
393 color: #fff;
393 color: #fff;
394 text-decoration: none;
394 text-decoration: none;
395 }
395 }
396
396
397 #header #header-inner #logo a:hover {
397 #header #header-inner #logo a:hover {
398 color: #bfe3ff;
398 color: #bfe3ff;
399 }
399 }
400
400
401 #header #header-inner #quick {
401 #header #header-inner #quick {
402 position: relative;
402 position: relative;
403 float: right;
403 float: right;
404 list-style-type: none;
404 list-style-type: none;
405 list-style-position: outside;
405 list-style-position: outside;
406 margin: 4px 8px 0 0;
406 margin: 4px 8px 0 0;
407 padding: 0;
407 padding: 0;
408 border-radius: 4px;
408 border-radius: 4px;
409 }
409 }
410
410
411 #header #header-inner #quick li span.short {
411 #header #header-inner #quick li span.short {
412 padding: 9px 6px 8px 6px;
412 padding: 9px 6px 8px 6px;
413 }
413 }
414
414
415 #header #header-inner #quick li span {
415 #header #header-inner #quick li span {
416 display: inline;
416 display: inline;
417 margin: 0;
417 margin: 0;
418 }
418 }
419
419
420 #header #header-inner #quick li span.normal {
420 #header #header-inner #quick li span.normal {
421 border: none;
421 border: none;
422 padding: 10px 12px 8px;
422 padding: 10px 12px 8px;
423 }
423 }
424
424
425 #header #header-inner #quick li span.icon {
425 #header #header-inner #quick li span.icon {
426 border-left: none;
426 border-left: none;
427 padding-left: 10px;
427 padding-left: 10px;
428 }
428 }
429
429
430 #header #header-inner #quick li span.icon_short {
430 #header #header-inner #quick li span.icon_short {
431 top: 0;
431 top: 0;
432 left: 0;
432 left: 0;
433 border-left: none;
433 border-left: none;
434 border-right: 1px solid #2e5c89;
434 border-right: 1px solid #2e5c89;
435 padding: 8px 6px 4px;
435 padding: 8px 6px 4px;
436 }
436 }
437
437
438 #header #header-inner #quick li span.icon img, #header #header-inner #quick li span.icon_short img {
438 #header #header-inner #quick li span.icon img, #header #header-inner #quick li span.icon_short img {
439 vertical-align: middle;
439 vertical-align: middle;
440 margin-bottom: 2px;
440 margin-bottom: 2px;
441 }
441 }
442
442
443 #header #header-inner #quick ul.repo_switcher {
443 #header #header-inner #quick ul.repo_switcher {
444 max-height: 275px;
444 max-height: 275px;
445 overflow-x: hidden;
445 overflow-x: hidden;
446 overflow-y: auto;
446 overflow-y: auto;
447 }
447 }
448
448
449 #header #header-inner #quick ul.repo_switcher li.qfilter_rs {
449 #header #header-inner #quick ul.repo_switcher li.qfilter_rs {
450 padding: 2px 3px;
450 padding: 2px 3px;
451 padding-right: 17px;
451 padding-right: 17px;
452 }
452 }
453
453
454 #header #header-inner #quick ul.repo_switcher li.qfilter_rs input {
454 #header #header-inner #quick ul.repo_switcher li.qfilter_rs input {
455 width: 100%;
455 width: 100%;
456 border-radius: 10px;
456 border-radius: 10px;
457 padding: 2px 7px;
457 padding: 2px 7px;
458 }
458 }
459
459
460 #header #header-inner #quick .repo_switcher_type {
460 #header #header-inner #quick .repo_switcher_type {
461 position: absolute;
461 position: absolute;
462 left: 0;
462 left: 0;
463 top: 9px;
463 top: 9px;
464 margin: 0px 2px 0px 2px;
464 margin: 0px 2px 0px 2px;
465 }
465 }
466
466
467 #header #header-inner #quick li ul li a.journal, #header #header-inner #quick li ul li a.journal:hover {
467 #header #header-inner #quick li ul li a.journal, #header #header-inner #quick li ul li a.journal:hover {
468 background-image: url("../images/icons/book.png");
468 background-image: url("../images/icons/book.png");
469 }
469 }
470
470
471 #header #header-inner #quick li ul li a.private_repo, #header #header-inner #quick li ul li a.private_repo:hover {
471 #header #header-inner #quick li ul li a.private_repo, #header #header-inner #quick li ul li a.private_repo:hover {
472 background-image: url("../images/icons/lock.png")
472 background-image: url("../images/icons/lock.png")
473 }
473 }
474
474
475 #header #header-inner #quick li ul li a.public_repo, #header #header-inner #quick li ul li a.public_repo:hover {
475 #header #header-inner #quick li ul li a.public_repo, #header #header-inner #quick li ul li a.public_repo:hover {
476 background-image: url("../images/icons/lock_open.png");
476 background-image: url("../images/icons/lock_open.png");
477 }
477 }
478
478
479 #header #header-inner #quick li ul li a.hg, #header #header-inner #quick li ul li a.hg:hover {
479 #header #header-inner #quick li ul li a.hg, #header #header-inner #quick li ul li a.hg:hover {
480 background-image: url("../images/icons/hgicon.png");
480 background-image: url("../images/icons/hgicon.png");
481 padding-left: 42px;
481 padding-left: 42px;
482 background-position: 20px 9px;
482 background-position: 20px 9px;
483 }
483 }
484
484
485 #header #header-inner #quick li ul li a.git, #header #header-inner #quick li ul li a.git:hover {
485 #header #header-inner #quick li ul li a.git, #header #header-inner #quick li ul li a.git:hover {
486 background-image: url("../images/icons/giticon.png");
486 background-image: url("../images/icons/giticon.png");
487 padding-left: 42px;
487 padding-left: 42px;
488 background-position: 20px 9px;
488 background-position: 20px 9px;
489 }
489 }
490
490
491 #header #header-inner #quick li ul li a.repos, #header #header-inner #quick li ul li a.repos:hover {
491 #header #header-inner #quick li ul li a.repos, #header #header-inner #quick li ul li a.repos:hover {
492 background-image: url("../images/icons/database_edit.png");
492 background-image: url("../images/icons/database_edit.png");
493 }
493 }
494
494
495 #header #header-inner #quick li ul li a.repos_groups, #header #header-inner #quick li ul li a.repos_groups:hover {
495 #header #header-inner #quick li ul li a.repos_groups, #header #header-inner #quick li ul li a.repos_groups:hover {
496 background-image: url("../images/icons/database_link.png");
496 background-image: url("../images/icons/database_link.png");
497 }
497 }
498
498
499 #header #header-inner #quick li ul li a.users, #header #header-inner #quick li ul li a.users:hover {
499 #header #header-inner #quick li ul li a.users, #header #header-inner #quick li ul li a.users:hover {
500 background-image: url("../images/icons/user_edit.png");
500 background-image: url("../images/icons/user_edit.png");
501 }
501 }
502
502
503 #header #header-inner #quick li ul li a.groups, #header #header-inner #quick li ul li a.groups:hover {
503 #header #header-inner #quick li ul li a.groups, #header #header-inner #quick li ul li a.groups:hover {
504 background-image: url("../images/icons/group_edit.png");
504 background-image: url("../images/icons/group_edit.png");
505 }
505 }
506
506
507 #header #header-inner #quick li ul li a.defaults, #header #header-inner #quick li ul li a.defaults:hover {
507 #header #header-inner #quick li ul li a.defaults, #header #header-inner #quick li ul li a.defaults:hover {
508 background-image: url("../images/icons/wrench.png");
508 background-image: url("../images/icons/wrench.png");
509 }
509 }
510
510
511 #header #header-inner #quick li ul li a.settings, #header #header-inner #quick li ul li a.settings:hover {
511 #header #header-inner #quick li ul li a.settings, #header #header-inner #quick li ul li a.settings:hover {
512 background-image: url("../images/icons/cog.png");
512 background-image: url("../images/icons/cog.png");
513 }
513 }
514
514
515 #header #header-inner #quick li ul li a.permissions, #header #header-inner #quick li ul li a.permissions:hover {
515 #header #header-inner #quick li ul li a.permissions, #header #header-inner #quick li ul li a.permissions:hover {
516 background-image: url("../images/icons/key.png");
516 background-image: url("../images/icons/key.png");
517 }
517 }
518
518
519 #header #header-inner #quick li ul li a.ldap, #header #header-inner #quick li ul li a.ldap:hover {
519 #header #header-inner #quick li ul li a.ldap, #header #header-inner #quick li ul li a.ldap:hover {
520 background-image: url("../images/icons/server_key.png");
520 background-image: url("../images/icons/server_key.png");
521 }
521 }
522
522
523 #header #header-inner #quick li ul li a.fork, #header #header-inner #quick li ul li a.fork:hover {
523 #header #header-inner #quick li ul li a.fork, #header #header-inner #quick li ul li a.fork:hover {
524 background-image: url("../images/icons/arrow_divide.png");
524 background-image: url("../images/icons/arrow_divide.png");
525 }
525 }
526
526
527 #header #header-inner #quick li ul li a.locking_add, #header #header-inner #quick li ul li a.locking_add:hover {
527 #header #header-inner #quick li ul li a.locking_add, #header #header-inner #quick li ul li a.locking_add:hover {
528 background-image: url("../images/icons/lock_add.png");
528 background-image: url("../images/icons/lock_add.png");
529 }
529 }
530
530
531 #header #header-inner #quick li ul li a.locking_del, #header #header-inner #quick li ul li a.locking_del:hover {
531 #header #header-inner #quick li ul li a.locking_del, #header #header-inner #quick li ul li a.locking_del:hover {
532 background-image: url("../images/icons/lock_delete.png");
532 background-image: url("../images/icons/lock_delete.png");
533 }
533 }
534
534
535 #header #header-inner #quick li ul li a.pull_request, #header #header-inner #quick li ul li a.pull_request:hover {
535 #header #header-inner #quick li ul li a.pull_request, #header #header-inner #quick li ul li a.pull_request:hover {
536 background-image: url("../images/icons/arrow_join.png") ;
536 background-image: url("../images/icons/arrow_join.png") ;
537 }
537 }
538
538
539 #header #header-inner #quick li ul li a.compare_request, #header #header-inner #quick li ul li a.compare_request:hover {
539 #header #header-inner #quick li ul li a.compare_request, #header #header-inner #quick li ul li a.compare_request:hover {
540 background-image: url("../images/icons/arrow_inout.png");
540 background-image: url("../images/icons/arrow_inout.png");
541 }
541 }
542
542
543 #header #header-inner #quick li ul li a.search, #header #header-inner #quick li ul li a.search:hover {
543 #header #header-inner #quick li ul li a.search, #header #header-inner #quick li ul li a.search:hover {
544 background-image: url("../images/icons/search_16.png");
544 background-image: url("../images/icons/search_16.png");
545 }
545 }
546
546
547 #header #header-inner #quick li ul li a.delete, #header #header-inner #quick li ul li a.delete:hover {
547 #header #header-inner #quick li ul li a.delete, #header #header-inner #quick li ul li a.delete:hover {
548 background-image: url("../images/icons/delete.png");
548 background-image: url("../images/icons/delete.png");
549 }
549 }
550
550
551 #header #header-inner #quick li ul li a.branches, #header #header-inner #quick li ul li a.branches:hover {
551 #header #header-inner #quick li ul li a.branches, #header #header-inner #quick li ul li a.branches:hover {
552 background-image: url("../images/icons/arrow_branch.png");
552 background-image: url("../images/icons/arrow_branch.png");
553 }
553 }
554
554
555 #header #header-inner #quick li ul li a.tags,
555 #header #header-inner #quick li ul li a.tags,
556 #header #header-inner #quick li ul li a.tags:hover {
556 #header #header-inner #quick li ul li a.tags:hover {
557 background: #FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
557 background: #FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
558 width: 167px;
558 width: 167px;
559 margin: 0;
559 margin: 0;
560 padding: 12px 9px 7px 24px;
560 padding: 12px 9px 7px 24px;
561 }
561 }
562
562
563 #header #header-inner #quick li ul li a.bookmarks,
563 #header #header-inner #quick li ul li a.bookmarks,
564 #header #header-inner #quick li ul li a.bookmarks:hover {
564 #header #header-inner #quick li ul li a.bookmarks:hover {
565 background: #FFF url("../images/icons/tag_green.png") no-repeat 4px 9px;
565 background: #FFF url("../images/icons/tag_green.png") no-repeat 4px 9px;
566 width: 167px;
566 width: 167px;
567 margin: 0;
567 margin: 0;
568 padding: 12px 9px 7px 24px;
568 padding: 12px 9px 7px 24px;
569 }
569 }
570
570
571 #header #header-inner #quick li ul li a.admin,
571 #header #header-inner #quick li ul li a.admin,
572 #header #header-inner #quick li ul li a.admin:hover {
572 #header #header-inner #quick li ul li a.admin:hover {
573 background: #FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
573 background: #FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
574 width: 167px;
574 width: 167px;
575 margin: 0;
575 margin: 0;
576 padding: 12px 9px 7px 24px;
576 padding: 12px 9px 7px 24px;
577 }
577 }
578
578
579 .groups_breadcrumbs a {
579 .groups_breadcrumbs a {
580 color: #fff;
580 color: #fff;
581 }
581 }
582
582
583 .groups_breadcrumbs a:hover {
583 .groups_breadcrumbs a:hover {
584 color: #bfe3ff;
584 color: #bfe3ff;
585 text-decoration: none;
585 text-decoration: none;
586 }
586 }
587
587
588 td.quick_repo_menu {
588 td.quick_repo_menu {
589 background: #FFF url("../images/vertical-indicator.png") 8px 50% no-repeat !important;
589 background: #FFF url("../images/vertical-indicator.png") 8px 50% no-repeat !important;
590 cursor: pointer;
590 cursor: pointer;
591 width: 8px;
591 width: 8px;
592 border: 1px solid transparent;
592 border: 1px solid transparent;
593 }
593 }
594
594
595 td.quick_repo_menu.active {
595 td.quick_repo_menu.active {
596 background: url("../images/dt-arrow-dn.png") no-repeat scroll 5px 50% #FFFFFF !important;
596 background: url("../images/dt-arrow-dn.png") no-repeat scroll 5px 50% #FFFFFF !important;
597 border: 1px solid #003367;
597 border: 1px solid #003367;
598 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
598 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
599 cursor: pointer;
599 cursor: pointer;
600 }
600 }
601
601
602 td.quick_repo_menu .menu_items {
602 td.quick_repo_menu .menu_items {
603 margin-top: 10px;
603 margin-top: 10px;
604 margin-left: -6px;
604 margin-left: -6px;
605 width: 150px;
605 width: 150px;
606 position: absolute;
606 position: absolute;
607 background-color: #FFF;
607 background-color: #FFF;
608 background: none repeat scroll 0 0 #FFFFFF;
608 background: none repeat scroll 0 0 #FFFFFF;
609 border-color: #003367 #666666 #666666;
609 border-color: #003367 #666666 #666666;
610 border-right: 1px solid #666666;
610 border-right: 1px solid #666666;
611 border-style: solid;
611 border-style: solid;
612 border-width: 1px;
612 border-width: 1px;
613 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
613 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
614 border-top-style: none;
614 border-top-style: none;
615 }
615 }
616
616
617 td.quick_repo_menu .menu_items li {
617 td.quick_repo_menu .menu_items li {
618 padding: 0 !important;
618 padding: 0 !important;
619 }
619 }
620
620
621 td.quick_repo_menu .menu_items a {
621 td.quick_repo_menu .menu_items a {
622 display: block;
622 display: block;
623 padding: 4px 12px 4px 8px;
623 padding: 4px 12px 4px 8px;
624 }
624 }
625
625
626 td.quick_repo_menu .menu_items a:hover {
626 td.quick_repo_menu .menu_items a:hover {
627 background-color: #EEE;
627 background-color: #EEE;
628 text-decoration: none;
628 text-decoration: none;
629 }
629 }
630
630
631 td.quick_repo_menu .menu_items .icon img {
631 td.quick_repo_menu .menu_items .icon img {
632 margin-bottom: -2px;
632 margin-bottom: -2px;
633 }
633 }
634
634
635 td.quick_repo_menu .menu_items.hidden {
635 td.quick_repo_menu .menu_items.hidden {
636 display: none;
636 display: none;
637 }
637 }
638
638
639 .yui-dt-first th {
639 .yui-dt-first th {
640 text-align: left;
640 text-align: left;
641 }
641 }
642
642
643 /*
643 /*
644 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
644 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
645 Code licensed under the BSD License:
645 Code licensed under the BSD License:
646 http://developer.yahoo.com/yui/license.html
646 http://developer.yahoo.com/yui/license.html
647 version: 2.9.0
647 version: 2.9.0
648 */
648 */
649 .yui-skin-sam .yui-dt-mask {
649 .yui-skin-sam .yui-dt-mask {
650 position: absolute;
650 position: absolute;
651 z-index: 9500;
651 z-index: 9500;
652 }
652 }
653 .yui-dt-tmp {
653 .yui-dt-tmp {
654 position: absolute;
654 position: absolute;
655 left: -9000px;
655 left: -9000px;
656 }
656 }
657 .yui-dt-scrollable .yui-dt-bd { overflow: auto }
657 .yui-dt-scrollable .yui-dt-bd { overflow: auto }
658 .yui-dt-scrollable .yui-dt-hd {
658 .yui-dt-scrollable .yui-dt-hd {
659 overflow: hidden;
659 overflow: hidden;
660 position: relative;
660 position: relative;
661 }
661 }
662 .yui-dt-scrollable .yui-dt-bd thead tr,
662 .yui-dt-scrollable .yui-dt-bd thead tr,
663 .yui-dt-scrollable .yui-dt-bd thead th {
663 .yui-dt-scrollable .yui-dt-bd thead th {
664 position: absolute;
664 position: absolute;
665 left: -1500px;
665 left: -1500px;
666 }
666 }
667 .yui-dt-scrollable tbody { -moz-outline: 0 }
667 .yui-dt-scrollable tbody { -moz-outline: 0 }
668 .yui-skin-sam thead .yui-dt-sortable { cursor: pointer }
668 .yui-skin-sam thead .yui-dt-sortable { cursor: pointer }
669 .yui-skin-sam thead .yui-dt-draggable { cursor: move }
669 .yui-skin-sam thead .yui-dt-draggable { cursor: move }
670 .yui-dt-coltarget {
670 .yui-dt-coltarget {
671 position: absolute;
671 position: absolute;
672 z-index: 999;
672 z-index: 999;
673 }
673 }
674 .yui-dt-hd { zoom: 1 }
674 .yui-dt-hd { zoom: 1 }
675 th.yui-dt-resizeable .yui-dt-resizerliner { position: relative }
675 th.yui-dt-resizeable .yui-dt-resizerliner { position: relative }
676 .yui-dt-resizer {
676 .yui-dt-resizer {
677 position: absolute;
677 position: absolute;
678 right: 0;
678 right: 0;
679 bottom: 0;
679 bottom: 0;
680 height: 100%;
680 height: 100%;
681 cursor: e-resize;
681 cursor: e-resize;
682 cursor: col-resize;
682 cursor: col-resize;
683 background-color: #CCC;
683 background-color: #CCC;
684 opacity: 0;
684 opacity: 0;
685 filter: alpha(opacity=0);
685 filter: alpha(opacity=0);
686 }
686 }
687 .yui-dt-resizerproxy {
687 .yui-dt-resizerproxy {
688 visibility: hidden;
688 visibility: hidden;
689 position: absolute;
689 position: absolute;
690 z-index: 9000;
690 z-index: 9000;
691 background-color: #CCC;
691 background-color: #CCC;
692 opacity: 0;
692 opacity: 0;
693 filter: alpha(opacity=0);
693 filter: alpha(opacity=0);
694 }
694 }
695 th.yui-dt-hidden .yui-dt-liner,
695 th.yui-dt-hidden .yui-dt-liner,
696 td.yui-dt-hidden .yui-dt-liner,
696 td.yui-dt-hidden .yui-dt-liner,
697 th.yui-dt-hidden .yui-dt-resizer { display: none }
697 th.yui-dt-hidden .yui-dt-resizer { display: none }
698 .yui-dt-editor,
698 .yui-dt-editor,
699 .yui-dt-editor-shim {
699 .yui-dt-editor-shim {
700 position: absolute;
700 position: absolute;
701 z-index: 9000;
701 z-index: 9000;
702 }
702 }
703 .yui-skin-sam .yui-dt table {
703 .yui-skin-sam .yui-dt table {
704 margin: 0;
704 margin: 0;
705 padding: 0;
705 padding: 0;
706 font-family: arial;
706 font-family: arial;
707 font-size: inherit;
707 font-size: inherit;
708 border-collapse: separate;
708 border-collapse: separate;
709 *border-collapse: collapse;
709 *border-collapse: collapse;
710 border-spacing: 0;
710 border-spacing: 0;
711 border: 1px solid #7f7f7f;
711 border: 1px solid #7f7f7f;
712 }
712 }
713 .yui-skin-sam .yui-dt thead { border-spacing: 0 }
713 .yui-skin-sam .yui-dt thead { border-spacing: 0 }
714 .yui-skin-sam .yui-dt caption {
714 .yui-skin-sam .yui-dt caption {
715 color: #000;
715 color: #000;
716 font-size: 85%;
716 font-size: 85%;
717 font-weight: normal;
717 font-weight: normal;
718 font-style: italic;
718 font-style: italic;
719 line-height: 1;
719 line-height: 1;
720 padding: 1em 0;
720 padding: 1em 0;
721 text-align: center;
721 text-align: center;
722 }
722 }
723 .yui-skin-sam .yui-dt th { background: #d8d8da url(../images/sprite.png) repeat-x 0 0 }
723 .yui-skin-sam .yui-dt th { background: #d8d8da url(../images/sprite.png) repeat-x 0 0 }
724 .yui-skin-sam .yui-dt th,
724 .yui-skin-sam .yui-dt th,
725 .yui-skin-sam .yui-dt th a {
725 .yui-skin-sam .yui-dt th a {
726 font-weight: normal;
726 font-weight: normal;
727 text-decoration: none;
727 text-decoration: none;
728 color: #000;
728 color: #000;
729 vertical-align: bottom;
729 vertical-align: bottom;
730 }
730 }
731 .yui-skin-sam .yui-dt th {
731 .yui-skin-sam .yui-dt th {
732 margin: 0;
732 margin: 0;
733 padding: 0;
733 padding: 0;
734 border: 0;
734 border: 0;
735 border-right: 1px solid #cbcbcb;
735 border-right: 1px solid #cbcbcb;
736 }
736 }
737 .yui-skin-sam .yui-dt tr.yui-dt-first td { border-top: 1px solid #7f7f7f }
737 .yui-skin-sam .yui-dt tr.yui-dt-first td { border-top: 1px solid #7f7f7f }
738 .yui-skin-sam .yui-dt th .yui-dt-liner { white-space: nowrap }
738 .yui-skin-sam .yui-dt th .yui-dt-liner { white-space: nowrap }
739 .yui-skin-sam .yui-dt-liner {
739 .yui-skin-sam .yui-dt-liner {
740 margin: 0;
740 margin: 0;
741 padding: 0;
741 padding: 0;
742 }
742 }
743 .yui-skin-sam .yui-dt-coltarget {
743 .yui-skin-sam .yui-dt-coltarget {
744 width: 5px;
744 width: 5px;
745 background-color: red;
745 background-color: red;
746 }
746 }
747 .yui-skin-sam .yui-dt td {
747 .yui-skin-sam .yui-dt td {
748 margin: 0;
748 margin: 0;
749 padding: 0;
749 padding: 0;
750 border: 0;
750 border: 0;
751 border-right: 1px solid #cbcbcb;
751 border-right: 1px solid #cbcbcb;
752 text-align: left;
752 text-align: left;
753 }
753 }
754 .yui-skin-sam .yui-dt-list td { border-right: 0 }
754 .yui-skin-sam .yui-dt-list td { border-right: 0 }
755 .yui-skin-sam .yui-dt-resizer { width: 6px }
755 .yui-skin-sam .yui-dt-resizer { width: 6px }
756 .yui-skin-sam .yui-dt-mask {
756 .yui-skin-sam .yui-dt-mask {
757 background-color: #000;
757 background-color: #000;
758 opacity: .25;
758 opacity: .25;
759 filter: alpha(opacity=25);
759 filter: alpha(opacity=25);
760 }
760 }
761 .yui-skin-sam .yui-dt-message { background-color: #FFF }
761 .yui-skin-sam .yui-dt-message { background-color: #FFF }
762 .yui-skin-sam .yui-dt-scrollable table { border: 0 }
762 .yui-skin-sam .yui-dt-scrollable table { border: 0 }
763 .yui-skin-sam .yui-dt-scrollable .yui-dt-hd {
763 .yui-skin-sam .yui-dt-scrollable .yui-dt-hd {
764 border-left: 1px solid #7f7f7f;
764 border-left: 1px solid #7f7f7f;
765 border-top: 1px solid #7f7f7f;
765 border-top: 1px solid #7f7f7f;
766 border-right: 1px solid #7f7f7f;
766 border-right: 1px solid #7f7f7f;
767 }
767 }
768 .yui-skin-sam .yui-dt-scrollable .yui-dt-bd {
768 .yui-skin-sam .yui-dt-scrollable .yui-dt-bd {
769 border-left: 1px solid #7f7f7f;
769 border-left: 1px solid #7f7f7f;
770 border-bottom: 1px solid #7f7f7f;
770 border-bottom: 1px solid #7f7f7f;
771 border-right: 1px solid #7f7f7f;
771 border-right: 1px solid #7f7f7f;
772 background-color: #FFF;
772 background-color: #FFF;
773 }
773 }
774 .yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td { border-bottom: 1px solid #7f7f7f }
774 .yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td { border-bottom: 1px solid #7f7f7f }
775 .yui-skin-sam th.yui-dt-asc,
775 .yui-skin-sam th.yui-dt-asc,
776 .yui-skin-sam th.yui-dt-desc { background: url(../images/sprite.png) repeat-x 0 -100px }
776 .yui-skin-sam th.yui-dt-desc { background: url(../images/sprite.png) repeat-x 0 -100px }
777 .yui-skin-sam th.yui-dt-sortable .yui-dt-label { margin-right: 10px }
777 .yui-skin-sam th.yui-dt-sortable .yui-dt-label { margin-right: 10px }
778 .yui-skin-sam th.yui-dt-asc .yui-dt-liner { background: url(../images/dt-arrow-up.png) no-repeat right }
778 .yui-skin-sam th.yui-dt-asc .yui-dt-liner { background: url(../images/dt-arrow-up.png) no-repeat right }
779 .yui-skin-sam th.yui-dt-desc .yui-dt-liner { background: url(../images/dt-arrow-dn.png) no-repeat right }
779 .yui-skin-sam th.yui-dt-desc .yui-dt-liner { background: url(../images/dt-arrow-dn.png) no-repeat right }
780 tbody .yui-dt-editable { cursor: pointer }
780 tbody .yui-dt-editable { cursor: pointer }
781 .yui-dt-editor {
781 .yui-dt-editor {
782 text-align: left;
782 text-align: left;
783 background-color: #f2f2f2;
783 background-color: #f2f2f2;
784 border: 1px solid #808080;
784 border: 1px solid #808080;
785 padding: 6px;
785 padding: 6px;
786 }
786 }
787 .yui-dt-editor label {
787 .yui-dt-editor label {
788 padding-left: 4px;
788 padding-left: 4px;
789 padding-right: 6px;
789 padding-right: 6px;
790 }
790 }
791 .yui-dt-editor .yui-dt-button {
791 .yui-dt-editor .yui-dt-button {
792 padding-top: 6px;
792 padding-top: 6px;
793 text-align: right;
793 text-align: right;
794 }
794 }
795 .yui-dt-editor .yui-dt-button button {
795 .yui-dt-editor .yui-dt-button button {
796 background: url(../images/sprite.png) repeat-x 0 0;
796 background: url(../images/sprite.png) repeat-x 0 0;
797 border: 1px solid #999;
797 border: 1px solid #999;
798 width: 4em;
798 width: 4em;
799 height: 1.8em;
799 height: 1.8em;
800 margin-left: 6px;
800 margin-left: 6px;
801 }
801 }
802 .yui-dt-editor .yui-dt-button button.yui-dt-default {
802 .yui-dt-editor .yui-dt-button button.yui-dt-default {
803 background: url(../images/sprite.png) repeat-x 0 -1400px;
803 background: url(../images/sprite.png) repeat-x 0 -1400px;
804 background-color: #5584e0;
804 background-color: #5584e0;
805 border: 1px solid #304369;
805 border: 1px solid #304369;
806 color: #FFF;
806 color: #FFF;
807 }
807 }
808 .yui-dt-editor .yui-dt-button button:hover {
808 .yui-dt-editor .yui-dt-button button:hover {
809 background: url(../images/sprite.png) repeat-x 0 -1300px;
809 background: url(../images/sprite.png) repeat-x 0 -1300px;
810 color: #000;
810 color: #000;
811 }
811 }
812 .yui-dt-editor .yui-dt-button button:active {
812 .yui-dt-editor .yui-dt-button button:active {
813 background: url(../images/sprite.png) repeat-x 0 -1700px;
813 background: url(../images/sprite.png) repeat-x 0 -1700px;
814 color: #000;
814 color: #000;
815 }
815 }
816 .yui-skin-sam tr.yui-dt-even { background-color: #FFF }
816 .yui-skin-sam tr.yui-dt-even { background-color: #FFF }
817 .yui-skin-sam tr.yui-dt-odd { background-color: #edf5ff }
817 .yui-skin-sam tr.yui-dt-odd { background-color: #edf5ff }
818 .yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
818 .yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
819 .yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
819 .yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
820 .yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
820 .yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
821 .yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color: #dbeaff }
821 .yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color: #dbeaff }
822 .yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color: #FFF }
822 .yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color: #FFF }
823 .yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color: #FFF }
823 .yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color: #FFF }
824 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
824 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
825 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
825 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
826 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
826 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
827 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color: #edf5ff }
827 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color: #edf5ff }
828 .yui-skin-sam th.yui-dt-highlighted,
828 .yui-skin-sam th.yui-dt-highlighted,
829 .yui-skin-sam th.yui-dt-highlighted a { background-color: #b2d2ff }
829 .yui-skin-sam th.yui-dt-highlighted a { background-color: #b2d2ff }
830 .yui-skin-sam tr.yui-dt-highlighted,
830 .yui-skin-sam tr.yui-dt-highlighted,
831 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
831 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
832 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
832 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
833 .yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
833 .yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
834 .yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
834 .yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
835 cursor: pointer;
835 cursor: pointer;
836 background-color: #b2d2ff;
836 background-color: #b2d2ff;
837 }
837 }
838 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted,
838 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted,
839 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted a { background-color: #b2d2ff }
839 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted a { background-color: #b2d2ff }
840 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
840 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
841 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
841 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
842 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
842 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
843 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
843 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
844 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
844 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
845 cursor: pointer;
845 cursor: pointer;
846 background-color: #b2d2ff;
846 background-color: #b2d2ff;
847 }
847 }
848 .yui-skin-sam th.yui-dt-selected,
848 .yui-skin-sam th.yui-dt-selected,
849 .yui-skin-sam th.yui-dt-selected a { background-color: #446cd7 }
849 .yui-skin-sam th.yui-dt-selected a { background-color: #446cd7 }
850 .yui-skin-sam tr.yui-dt-selected td,
850 .yui-skin-sam tr.yui-dt-selected td,
851 .yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
851 .yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
852 .yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
852 .yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
853 background-color: #426fd9;
853 background-color: #426fd9;
854 color: #FFF;
854 color: #FFF;
855 }
855 }
856 .yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
856 .yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
857 .yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
857 .yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
858 background-color: #446cd7;
858 background-color: #446cd7;
859 color: #FFF;
859 color: #FFF;
860 }
860 }
861 .yui-skin-sam .yui-dt-list th.yui-dt-selected,
861 .yui-skin-sam .yui-dt-list th.yui-dt-selected,
862 .yui-skin-sam .yui-dt-list th.yui-dt-selected a { background-color: #446cd7 }
862 .yui-skin-sam .yui-dt-list th.yui-dt-selected a { background-color: #446cd7 }
863 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
863 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
864 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
864 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
865 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
865 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
866 background-color: #426fd9;
866 background-color: #426fd9;
867 color: #FFF;
867 color: #FFF;
868 }
868 }
869 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
869 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
870 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
870 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
871 background-color: #446cd7;
871 background-color: #446cd7;
872 color: #FFF;
872 color: #FFF;
873 }
873 }
874 .yui-skin-sam .yui-dt-paginator {
874 .yui-skin-sam .yui-dt-paginator {
875 display: block;
875 display: block;
876 margin: 6px 0;
876 margin: 6px 0;
877 white-space: nowrap;
877 white-space: nowrap;
878 }
878 }
879 .yui-skin-sam .yui-dt-paginator .yui-dt-first,
879 .yui-skin-sam .yui-dt-paginator .yui-dt-first,
880 .yui-skin-sam .yui-dt-paginator .yui-dt-last,
880 .yui-skin-sam .yui-dt-paginator .yui-dt-last,
881 .yui-skin-sam .yui-dt-paginator .yui-dt-selected { padding: 2px 6px }
881 .yui-skin-sam .yui-dt-paginator .yui-dt-selected { padding: 2px 6px }
882 .yui-skin-sam .yui-dt-paginator a.yui-dt-first,
882 .yui-skin-sam .yui-dt-paginator a.yui-dt-first,
883 .yui-skin-sam .yui-dt-paginator a.yui-dt-last { text-decoration: none }
883 .yui-skin-sam .yui-dt-paginator a.yui-dt-last { text-decoration: none }
884 .yui-skin-sam .yui-dt-paginator .yui-dt-previous,
884 .yui-skin-sam .yui-dt-paginator .yui-dt-previous,
885 .yui-skin-sam .yui-dt-paginator .yui-dt-next { display: none }
885 .yui-skin-sam .yui-dt-paginator .yui-dt-next { display: none }
886 .yui-skin-sam a.yui-dt-page {
886 .yui-skin-sam a.yui-dt-page {
887 border: 1px solid #cbcbcb;
887 border: 1px solid #cbcbcb;
888 padding: 2px 6px;
888 padding: 2px 6px;
889 text-decoration: none;
889 text-decoration: none;
890 background-color: #fff;
890 background-color: #fff;
891 }
891 }
892 .yui-skin-sam .yui-dt-selected {
892 .yui-skin-sam .yui-dt-selected {
893 border: 1px solid #fff;
893 border: 1px solid #fff;
894 background-color: #fff;
894 background-color: #fff;
895 }
895 }
896
896
897 #content #left {
897 #content #left {
898 left: 0;
898 left: 0;
899 width: 280px;
899 width: 280px;
900 position: absolute;
900 position: absolute;
901 }
901 }
902
902
903 #content #right {
903 #content #right {
904 margin: 0 60px 10px 290px;
904 margin: 0 60px 10px 290px;
905 }
905 }
906
906
907 #content div.box {
907 #content div.box {
908 clear: both;
908 clear: both;
909 background: #fff;
909 background: #fff;
910 margin: 0 0 10px;
910 margin: 0 0 10px;
911 padding: 0 0 10px;
911 padding: 0 0 10px;
912 -webkit-border-radius: 4px 4px 4px 4px;
912 -webkit-border-radius: 4px 4px 4px 4px;
913 -khtml-border-radius: 4px 4px 4px 4px;
913 -khtml-border-radius: 4px 4px 4px 4px;
914 border-radius: 4px 4px 4px 4px;
914 border-radius: 4px 4px 4px 4px;
915 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
915 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
916 }
916 }
917
917
918 #content div.box-left {
918 #content div.box-left {
919 width: 49%;
919 width: 49%;
920 clear: none;
920 clear: none;
921 float: left;
921 float: left;
922 margin: 0 0 10px;
922 margin: 0 0 10px;
923 }
923 }
924
924
925 #content div.box-right {
925 #content div.box-right {
926 width: 49%;
926 width: 49%;
927 clear: none;
927 clear: none;
928 float: right;
928 float: right;
929 margin: 0 0 10px;
929 margin: 0 0 10px;
930 }
930 }
931
931
932 #content div.box div.title {
932 #content div.box div.title {
933 clear: both;
933 clear: both;
934 overflow: hidden;
934 overflow: hidden;
935 background-color: #003B76;
935 background-color: #003B76;
936 background-repeat: repeat-x;
936 background-repeat: repeat-x;
937 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
937 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
938 background-image: -moz-linear-gradient(top, #003b76, #00376e);
938 background-image: -moz-linear-gradient(top, #003b76, #00376e);
939 background-image: -ms-linear-gradient(top, #003b76, #00376e);
939 background-image: -ms-linear-gradient(top, #003b76, #00376e);
940 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
940 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
941 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
941 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
942 background-image: -o-linear-gradient(top, #003b76, #00376e);
942 background-image: -o-linear-gradient(top, #003b76, #00376e);
943 background-image: linear-gradient(to bottom, #003b76, #00376e);
943 background-image: linear-gradient(to bottom, #003b76, #00376e);
944 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
944 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
945 margin: 0 0 20px;
945 margin: 0 0 20px;
946 padding: 0;
946 padding: 0;
947 border-radius: 4px 4px 0 0;
947 border-radius: 4px 4px 0 0;
948 }
948 }
949
949
950 #content div.box div.title h5 {
950 #content div.box div.title h5 {
951 float: left;
951 float: left;
952 border: none;
952 border: none;
953 color: #fff;
953 color: #fff;
954 margin: 0;
954 margin: 0;
955 padding: 11px 0 11px 10px;
955 padding: 11px 0 11px 10px;
956 }
956 }
957
957
958 #content div.box div.title .link-white {
958 #content div.box div.title .link-white {
959 color: #FFFFFF;
959 color: #FFFFFF;
960 }
960 }
961
961
962 #content div.box div.title .link-white.current {
962 #content div.box div.title .link-white.current {
963 color: #BFE3FF;
963 color: #BFE3FF;
964 }
964 }
965
965
966 #content div.box div.title ul.links li {
966 #content div.box div.title ul.links li {
967 list-style: none;
967 list-style: none;
968 float: left;
968 float: left;
969 margin: 0;
969 margin: 0;
970 padding: 0;
970 padding: 0;
971 }
971 }
972
972
973 #content div.box div.title ul.links li a {
973 #content div.box div.title ul.links li a {
974 border-left: 1px solid #316293;
974 border-left: 1px solid #316293;
975 color: #FFFFFF;
975 color: #FFFFFF;
976 display: block;
976 display: block;
977 float: left;
977 float: left;
978 font-size: 13px;
978 font-size: 13px;
979 font-weight: 700;
979 font-weight: 700;
980 height: 1%;
980 height: 1%;
981 margin: 0;
981 margin: 0;
982 padding: 11px 22px 12px;
982 padding: 11px 22px 12px;
983 text-decoration: none;
983 text-decoration: none;
984 }
984 }
985
985
986 #content div.box h1, #content div.box h2, #content div.box h3, #content div.box h4, #content div.box h5, #content div.box h6,
986 #content div.box h1, #content div.box h2, #content div.box h3, #content div.box h4, #content div.box h5, #content div.box h6,
987 #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 {
987 #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 {
988 clear: both;
988 clear: both;
989 overflow: hidden;
989 overflow: hidden;
990 border-bottom: 1px solid #DDD;
990 border-bottom: 1px solid #DDD;
991 margin: 10px 20px;
991 margin: 10px 20px;
992 padding: 0 0 15px;
992 padding: 0 0 15px;
993 }
993 }
994
994
995 #content div.box p {
995 #content div.box p {
996 color: #5f5f5f;
996 color: #5f5f5f;
997 font-size: 12px;
997 font-size: 12px;
998 line-height: 150%;
998 line-height: 150%;
999 margin: 0 24px 10px;
999 margin: 0 24px 10px;
1000 padding: 0;
1000 padding: 0;
1001 }
1001 }
1002
1002
1003 #content div.box blockquote {
1003 #content div.box blockquote {
1004 border-left: 4px solid #DDD;
1004 border-left: 4px solid #DDD;
1005 color: #5f5f5f;
1005 color: #5f5f5f;
1006 font-size: 11px;
1006 font-size: 11px;
1007 line-height: 150%;
1007 line-height: 150%;
1008 margin: 0 34px;
1008 margin: 0 34px;
1009 padding: 0 0 0 14px;
1009 padding: 0 0 0 14px;
1010 }
1010 }
1011
1011
1012 #content div.box blockquote p {
1012 #content div.box blockquote p {
1013 margin: 10px 0;
1013 margin: 10px 0;
1014 padding: 0;
1014 padding: 0;
1015 }
1015 }
1016
1016
1017 #content div.box dl {
1017 #content div.box dl {
1018 margin: 10px 0px;
1018 margin: 10px 0px;
1019 }
1019 }
1020
1020
1021 #content div.box dt {
1021 #content div.box dt {
1022 font-size: 12px;
1022 font-size: 12px;
1023 margin: 0;
1023 margin: 0;
1024 }
1024 }
1025
1025
1026 #content div.box dd {
1026 #content div.box dd {
1027 font-size: 12px;
1027 font-size: 12px;
1028 margin: 0;
1028 margin: 0;
1029 padding: 8px 0 8px 15px;
1029 padding: 8px 0 8px 15px;
1030 }
1030 }
1031
1031
1032 #content div.box li {
1032 #content div.box li {
1033 font-size: 12px;
1033 font-size: 12px;
1034 padding: 4px 0;
1034 padding: 4px 0;
1035 }
1035 }
1036
1036
1037 #content div.box ul.disc, #content div.box ul.circle {
1037 #content div.box ul.disc, #content div.box ul.circle {
1038 margin: 10px 24px 10px 38px;
1038 margin: 10px 24px 10px 38px;
1039 }
1039 }
1040
1040
1041 #content div.box ul.square {
1041 #content div.box ul.square {
1042 margin: 10px 24px 10px 40px;
1042 margin: 10px 24px 10px 40px;
1043 }
1043 }
1044
1044
1045 #content div.box img.left {
1045 #content div.box img.left {
1046 border: none;
1046 border: none;
1047 float: left;
1047 float: left;
1048 margin: 10px 10px 10px 0;
1048 margin: 10px 10px 10px 0;
1049 }
1049 }
1050
1050
1051 #content div.box img.right {
1051 #content div.box img.right {
1052 border: none;
1052 border: none;
1053 float: right;
1053 float: right;
1054 margin: 10px 0 10px 10px;
1054 margin: 10px 0 10px 10px;
1055 }
1055 }
1056
1056
1057 #content div.box div.messages {
1057 #content div.box div.messages {
1058 clear: both;
1058 clear: both;
1059 overflow: hidden;
1059 overflow: hidden;
1060 margin: 0 20px;
1060 margin: 0 20px;
1061 padding: 0;
1061 padding: 0;
1062 }
1062 }
1063
1063
1064 #content div.box div.message {
1064 #content div.box div.message {
1065 clear: both;
1065 clear: both;
1066 overflow: hidden;
1066 overflow: hidden;
1067 margin: 0;
1067 margin: 0;
1068 padding: 5px 0;
1068 padding: 5px 0;
1069 white-space: pre-wrap;
1069 white-space: pre-wrap;
1070 }
1070 }
1071 #content div.box div.expand {
1071 #content div.box div.expand {
1072 width: 110%;
1072 width: 110%;
1073 height: 14px;
1073 height: 14px;
1074 font-size: 10px;
1074 font-size: 10px;
1075 text-align: center;
1075 text-align: center;
1076 cursor: pointer;
1076 cursor: pointer;
1077 color: #666;
1077 color: #666;
1078
1078
1079 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)));
1079 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)));
1080 background: -webkit-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1080 background: -webkit-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1081 background: -moz-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1081 background: -moz-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1082 background: -o-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1082 background: -o-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1083 background: -ms-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1083 background: -ms-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1084 background: linear-gradient(to bottom,rgba(255,255,255,0),rgba(64,96,128,0.1));
1084 background: linear-gradient(to bottom,rgba(255,255,255,0),rgba(64,96,128,0.1));
1085
1085
1086 display: none;
1086 display: none;
1087 overflow: hidden;
1087 overflow: hidden;
1088 }
1088 }
1089 #content div.box div.expand .expandtext {
1089 #content div.box div.expand .expandtext {
1090 background-color: #ffffff;
1090 background-color: #ffffff;
1091 padding: 2px;
1091 padding: 2px;
1092 border-radius: 2px;
1092 border-radius: 2px;
1093 }
1093 }
1094
1094
1095 #content div.box div.message a {
1095 #content div.box div.message a {
1096 font-weight: 400 !important;
1096 font-weight: 400 !important;
1097 }
1097 }
1098
1098
1099 #content div.box div.message div.image {
1099 #content div.box div.message div.image {
1100 float: left;
1100 float: left;
1101 margin: 9px 0 0 5px;
1101 margin: 9px 0 0 5px;
1102 padding: 6px;
1102 padding: 6px;
1103 }
1103 }
1104
1104
1105 #content div.box div.message div.image img {
1105 #content div.box div.message div.image img {
1106 vertical-align: middle;
1106 vertical-align: middle;
1107 margin: 0;
1107 margin: 0;
1108 }
1108 }
1109
1109
1110 #content div.box div.message div.text {
1110 #content div.box div.message div.text {
1111 float: left;
1111 float: left;
1112 margin: 0;
1112 margin: 0;
1113 padding: 9px 6px;
1113 padding: 9px 6px;
1114 }
1114 }
1115
1115
1116 #content div.box div.message div.dismiss a {
1116 #content div.box div.message div.dismiss a {
1117 height: 16px;
1117 height: 16px;
1118 width: 16px;
1118 width: 16px;
1119 display: block;
1119 display: block;
1120 background: url("../images/icons/cross.png") no-repeat;
1120 background: url("../images/icons/cross.png") no-repeat;
1121 margin: 15px 14px 0 0;
1121 margin: 15px 14px 0 0;
1122 padding: 0;
1122 padding: 0;
1123 }
1123 }
1124
1124
1125 #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 {
1125 #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 {
1126 border: none;
1126 border: none;
1127 margin: 0;
1127 margin: 0;
1128 padding: 0;
1128 padding: 0;
1129 }
1129 }
1130
1130
1131 #content div.box div.message div.text span {
1131 #content div.box div.message div.text span {
1132 height: 1%;
1132 height: 1%;
1133 display: block;
1133 display: block;
1134 margin: 0;
1134 margin: 0;
1135 padding: 5px 0 0;
1135 padding: 5px 0 0;
1136 }
1136 }
1137
1137
1138 #content div.box div.message-error {
1138 #content div.box div.message-error {
1139 height: 1%;
1139 height: 1%;
1140 clear: both;
1140 clear: both;
1141 overflow: hidden;
1141 overflow: hidden;
1142 background: #FBE3E4;
1142 background: #FBE3E4;
1143 border: 1px solid #FBC2C4;
1143 border: 1px solid #FBC2C4;
1144 color: #860006;
1144 color: #860006;
1145 }
1145 }
1146
1146
1147 #content div.box div.message-error h6 {
1147 #content div.box div.message-error h6 {
1148 color: #860006;
1148 color: #860006;
1149 }
1149 }
1150
1150
1151 #content div.box div.message-warning {
1151 #content div.box div.message-warning {
1152 height: 1%;
1152 height: 1%;
1153 clear: both;
1153 clear: both;
1154 overflow: hidden;
1154 overflow: hidden;
1155 background: #FFF6BF;
1155 background: #FFF6BF;
1156 border: 1px solid #FFD324;
1156 border: 1px solid #FFD324;
1157 color: #5f5200;
1157 color: #5f5200;
1158 }
1158 }
1159
1159
1160 #content div.box div.message-warning h6 {
1160 #content div.box div.message-warning h6 {
1161 color: #5f5200;
1161 color: #5f5200;
1162 }
1162 }
1163
1163
1164 #content div.box div.message-notice {
1164 #content div.box div.message-notice {
1165 height: 1%;
1165 height: 1%;
1166 clear: both;
1166 clear: both;
1167 overflow: hidden;
1167 overflow: hidden;
1168 background: #8FBDE0;
1168 background: #8FBDE0;
1169 border: 1px solid #6BACDE;
1169 border: 1px solid #6BACDE;
1170 color: #003863;
1170 color: #003863;
1171 }
1171 }
1172
1172
1173 #content div.box div.message-notice h6 {
1173 #content div.box div.message-notice h6 {
1174 color: #003863;
1174 color: #003863;
1175 }
1175 }
1176
1176
1177 #content div.box div.message-success {
1177 #content div.box div.message-success {
1178 height: 1%;
1178 height: 1%;
1179 clear: both;
1179 clear: both;
1180 overflow: hidden;
1180 overflow: hidden;
1181 background: #E6EFC2;
1181 background: #E6EFC2;
1182 border: 1px solid #C6D880;
1182 border: 1px solid #C6D880;
1183 color: #4e6100;
1183 color: #4e6100;
1184 }
1184 }
1185
1185
1186 #content div.box div.message-success h6 {
1186 #content div.box div.message-success h6 {
1187 color: #4e6100;
1187 color: #4e6100;
1188 }
1188 }
1189
1189
1190 #content div.box div.form div.fields div.field {
1190 #content div.box div.form div.fields div.field {
1191 height: 1%;
1191 height: 1%;
1192 min-height: 12px;
1192 min-height: 12px;
1193 border-bottom: 1px solid #DDD;
1193 border-bottom: 1px solid #DDD;
1194 clear: both;
1194 clear: both;
1195 margin: 0;
1195 margin: 0;
1196 padding: 10px 0;
1196 padding: 10px 0;
1197 }
1197 }
1198
1198
1199 #content div.box div.form div.fields div.field-first {
1199 #content div.box div.form div.fields div.field-first {
1200 padding: 0 0 10px;
1200 padding: 0 0 10px;
1201 }
1201 }
1202
1202
1203 #content div.box div.form div.fields div.field-noborder {
1203 #content div.box div.form div.fields div.field-noborder {
1204 border-bottom: 0 !important;
1204 border-bottom: 0 !important;
1205 }
1205 }
1206
1206
1207 #content div.box div.form div.fields div.field span.error-message {
1207 #content div.box div.form div.fields div.field span.error-message {
1208 height: 1%;
1208 height: 1%;
1209 display: inline-block;
1209 display: inline-block;
1210 color: red;
1210 color: red;
1211 margin: 8px 0 0 4px;
1211 margin: 8px 0 0 4px;
1212 padding: 0;
1212 padding: 0;
1213 }
1213 }
1214
1214
1215 #content div.box div.form div.fields div.field span.success {
1215 #content div.box div.form div.fields div.field span.success {
1216 height: 1%;
1216 height: 1%;
1217 display: block;
1217 display: block;
1218 color: #316309;
1218 color: #316309;
1219 margin: 8px 0 0;
1219 margin: 8px 0 0;
1220 padding: 0;
1220 padding: 0;
1221 }
1221 }
1222
1222
1223 #content div.box div.form div.fields div.field div.label {
1223 #content div.box div.form div.fields div.field div.label {
1224 left: 70px;
1224 left: 70px;
1225 width: 155px;
1225 width: 155px;
1226 position: absolute;
1226 position: absolute;
1227 margin: 0;
1227 margin: 0;
1228 padding: 5px 0 0 0px;
1228 padding: 5px 0 0 0px;
1229 }
1229 }
1230
1230
1231 #content div.box div.form div.fields div.field div.label-summary {
1231 #content div.box div.form div.fields div.field div.label-summary {
1232 left: 30px;
1232 left: 30px;
1233 width: 155px;
1233 width: 155px;
1234 position: absolute;
1234 position: absolute;
1235 margin: 0;
1235 margin: 0;
1236 padding: 0px 0 0 0px;
1236 padding: 0px 0 0 0px;
1237 }
1237 }
1238
1238
1239 #content div.box-left div.form div.fields div.field div.label,
1239 #content div.box-left div.form div.fields div.field div.label,
1240 #content div.box-right div.form div.fields div.field div.label,
1240 #content div.box-right div.form div.fields div.field div.label,
1241 #content div.box-left div.form div.fields div.field div.label,
1241 #content div.box-left div.form div.fields div.field div.label,
1242 #content div.box-left div.form div.fields div.field div.label-summary,
1242 #content div.box-left div.form div.fields div.field div.label-summary,
1243 #content div.box-right div.form div.fields div.field div.label-summary,
1243 #content div.box-right div.form div.fields div.field div.label-summary,
1244 #content div.box-left div.form div.fields div.field div.label-summary {
1244 #content div.box-left div.form div.fields div.field div.label-summary {
1245 clear: both;
1245 clear: both;
1246 overflow: hidden;
1246 overflow: hidden;
1247 left: 0;
1247 left: 0;
1248 width: auto;
1248 width: auto;
1249 position: relative;
1249 position: relative;
1250 margin: 0;
1250 margin: 0;
1251 padding: 0 0 8px;
1251 padding: 0 0 8px;
1252 }
1252 }
1253
1253
1254 #content div.box div.form div.fields div.field div.label-select {
1254 #content div.box div.form div.fields div.field div.label-select {
1255 padding: 5px 0 0 5px;
1255 padding: 5px 0 0 5px;
1256 }
1256 }
1257
1257
1258 #content div.box-left div.form div.fields div.field div.label-select,
1258 #content div.box-left div.form div.fields div.field div.label-select,
1259 #content div.box-right div.form div.fields div.field div.label-select {
1259 #content div.box-right div.form div.fields div.field div.label-select {
1260 padding: 0 0 8px;
1260 padding: 0 0 8px;
1261 }
1261 }
1262
1262
1263 #content div.box-left div.form div.fields div.field div.label-textarea,
1263 #content div.box-left div.form div.fields div.field div.label-textarea,
1264 #content div.box-right div.form div.fields div.field div.label-textarea {
1264 #content div.box-right div.form div.fields div.field div.label-textarea {
1265 padding: 0 0 8px !important;
1265 padding: 0 0 8px !important;
1266 }
1266 }
1267
1267
1268 #content div.box div.form div.fields div.field div.label label, div.label label {
1268 #content div.box div.form div.fields div.field div.label label, div.label label {
1269 color: #393939;
1269 color: #393939;
1270 font-weight: 700;
1270 font-weight: 700;
1271 }
1271 }
1272 #content div.box div.form div.fields div.field div.label label, div.label-summary label {
1272 #content div.box div.form div.fields div.field div.label label, div.label-summary label {
1273 color: #393939;
1273 color: #393939;
1274 font-weight: 700;
1274 font-weight: 700;
1275 }
1275 }
1276 #content div.box div.form div.fields div.field div.input {
1276 #content div.box div.form div.fields div.field div.input {
1277 margin: 0 0 0 200px;
1277 margin: 0 0 0 200px;
1278 }
1278 }
1279
1279
1280 #content div.box div.form div.fields div.field div.input.summary {
1280 #content div.box div.form div.fields div.field div.input.summary {
1281 margin: 0 0 0 110px;
1281 margin: 0 0 0 110px;
1282 }
1282 }
1283 #content div.box div.form div.fields div.field div.input.summary-short {
1283 #content div.box div.form div.fields div.field div.input.summary-short {
1284 margin: 0 0 0 110px;
1284 margin: 0 0 0 110px;
1285 }
1285 }
1286 #content div.box div.form div.fields div.field div.file {
1286 #content div.box div.form div.fields div.field div.file {
1287 margin: 0 0 0 200px;
1287 margin: 0 0 0 200px;
1288 }
1288 }
1289
1289
1290 #content div.box-left div.form div.fields div.field div.input, #content div.box-right div.form div.fields div.field div.input {
1290 #content div.box-left div.form div.fields div.field div.input, #content div.box-right div.form div.fields div.field div.input {
1291 margin: 0 0 0 0px;
1291 margin: 0 0 0 0px;
1292 }
1292 }
1293
1293
1294 #content div.box div.form div.fields div.field div.input input,
1294 #content div.box div.form div.fields div.field div.input input,
1295 .reviewer_ac input {
1295 .reviewer_ac input {
1296 background: #FFF;
1296 background: #FFF;
1297 border-top: 1px solid #b3b3b3;
1297 border-top: 1px solid #b3b3b3;
1298 border-left: 1px solid #b3b3b3;
1298 border-left: 1px solid #b3b3b3;
1299 border-right: 1px solid #eaeaea;
1299 border-right: 1px solid #eaeaea;
1300 border-bottom: 1px solid #eaeaea;
1300 border-bottom: 1px solid #eaeaea;
1301 color: #000;
1301 color: #000;
1302 font-size: 11px;
1302 font-size: 11px;
1303 margin: 0;
1303 margin: 0;
1304 padding: 7px 7px 6px;
1304 padding: 7px 7px 6px;
1305 }
1305 }
1306
1306
1307 #content div.box div.form div.fields div.field div.input input#clone_url,
1307 #content div.box div.form div.fields div.field div.input input#clone_url,
1308 #content div.box div.form div.fields div.field div.input input#clone_url_id
1308 #content div.box div.form div.fields div.field div.input input#clone_url_id
1309 {
1309 {
1310 font-size: 16px;
1310 font-size: 16px;
1311 padding: 2px;
1311 padding: 2px;
1312 }
1312 }
1313
1313
1314 #content div.box div.form div.fields div.field div.file input {
1314 #content div.box div.form div.fields div.field div.file input {
1315 background: none repeat scroll 0 0 #FFFFFF;
1315 background: none repeat scroll 0 0 #FFFFFF;
1316 border-color: #B3B3B3 #EAEAEA #EAEAEA #B3B3B3;
1316 border-color: #B3B3B3 #EAEAEA #EAEAEA #B3B3B3;
1317 border-style: solid;
1317 border-style: solid;
1318 border-width: 1px;
1318 border-width: 1px;
1319 color: #000000;
1319 color: #000000;
1320 font-size: 11px;
1320 font-size: 11px;
1321 margin: 0;
1321 margin: 0;
1322 padding: 7px 7px 6px;
1322 padding: 7px 7px 6px;
1323 }
1323 }
1324
1324
1325 input.disabled {
1325 input.disabled {
1326 background-color: #F5F5F5 !important;
1326 background-color: #F5F5F5 !important;
1327 }
1327 }
1328 #content div.box div.form div.fields div.field div.input input.small {
1328 #content div.box div.form div.fields div.field div.input input.small {
1329 width: 30%;
1329 width: 30%;
1330 }
1330 }
1331
1331
1332 #content div.box div.form div.fields div.field div.input input.medium {
1332 #content div.box div.form div.fields div.field div.input input.medium {
1333 width: 55%;
1333 width: 55%;
1334 }
1334 }
1335
1335
1336 #content div.box div.form div.fields div.field div.input input.large {
1336 #content div.box div.form div.fields div.field div.input input.large {
1337 width: 85%;
1337 width: 85%;
1338 }
1338 }
1339
1339
1340 #content div.box div.form div.fields div.field div.input input.date {
1340 #content div.box div.form div.fields div.field div.input input.date {
1341 width: 177px;
1341 width: 177px;
1342 }
1342 }
1343
1343
1344 #content div.box div.form div.fields div.field div.input input.button {
1344 #content div.box div.form div.fields div.field div.input input.button {
1345 background: #D4D0C8;
1345 background: #D4D0C8;
1346 border-top: 1px solid #FFF;
1346 border-top: 1px solid #FFF;
1347 border-left: 1px solid #FFF;
1347 border-left: 1px solid #FFF;
1348 border-right: 1px solid #404040;
1348 border-right: 1px solid #404040;
1349 border-bottom: 1px solid #404040;
1349 border-bottom: 1px solid #404040;
1350 color: #000;
1350 color: #000;
1351 margin: 0;
1351 margin: 0;
1352 padding: 4px 8px;
1352 padding: 4px 8px;
1353 }
1353 }
1354
1354
1355 #content div.box div.form div.fields div.field div.textarea {
1355 #content div.box div.form div.fields div.field div.textarea {
1356 border-top: 1px solid #b3b3b3;
1356 border-top: 1px solid #b3b3b3;
1357 border-left: 1px solid #b3b3b3;
1357 border-left: 1px solid #b3b3b3;
1358 border-right: 1px solid #eaeaea;
1358 border-right: 1px solid #eaeaea;
1359 border-bottom: 1px solid #eaeaea;
1359 border-bottom: 1px solid #eaeaea;
1360 margin: 0 0 0 200px;
1360 margin: 0 0 0 200px;
1361 padding: 10px;
1361 padding: 10px;
1362 }
1362 }
1363
1363
1364 #content div.box div.form div.fields div.field div.textarea-editor {
1364 #content div.box div.form div.fields div.field div.textarea-editor {
1365 border: 1px solid #ddd;
1365 border: 1px solid #ddd;
1366 padding: 0;
1366 padding: 0;
1367 }
1367 }
1368
1368
1369 #content div.box div.form div.fields div.field div.textarea textarea {
1369 #content div.box div.form div.fields div.field div.textarea textarea {
1370 width: 100%;
1370 width: 100%;
1371 height: 220px;
1371 height: 220px;
1372 overflow: hidden;
1372 overflow: hidden;
1373 background: #FFF;
1373 background: #FFF;
1374 color: #000;
1374 color: #000;
1375 font-size: 11px;
1375 font-size: 11px;
1376 outline: none;
1376 outline: none;
1377 border-width: 0;
1377 border-width: 0;
1378 margin: 0;
1378 margin: 0;
1379 padding: 0;
1379 padding: 0;
1380 }
1380 }
1381
1381
1382 #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 {
1382 #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 {
1383 width: 100%;
1383 width: 100%;
1384 height: 100px;
1384 height: 100px;
1385 }
1385 }
1386
1386
1387 #content div.box div.form div.fields div.field div.textarea table {
1387 #content div.box div.form div.fields div.field div.textarea table {
1388 width: 100%;
1388 width: 100%;
1389 border: none;
1389 border: none;
1390 margin: 0;
1390 margin: 0;
1391 padding: 0;
1391 padding: 0;
1392 }
1392 }
1393
1393
1394 #content div.box div.form div.fields div.field div.textarea table td {
1394 #content div.box div.form div.fields div.field div.textarea table td {
1395 background: #DDD;
1395 background: #DDD;
1396 border: none;
1396 border: none;
1397 padding: 0;
1397 padding: 0;
1398 }
1398 }
1399
1399
1400 #content div.box div.form div.fields div.field div.textarea table td table {
1400 #content div.box div.form div.fields div.field div.textarea table td table {
1401 width: auto;
1401 width: auto;
1402 border: none;
1402 border: none;
1403 margin: 0;
1403 margin: 0;
1404 padding: 0;
1404 padding: 0;
1405 }
1405 }
1406
1406
1407 #content div.box div.form div.fields div.field div.textarea table td table td {
1407 #content div.box div.form div.fields div.field div.textarea table td table td {
1408 font-size: 11px;
1408 font-size: 11px;
1409 padding: 5px 5px 5px 0;
1409 padding: 5px 5px 5px 0;
1410 }
1410 }
1411
1411
1412 #content div.box div.form div.fields div.field input[type=text]:focus,
1412 #content div.box div.form div.fields div.field input[type=text]:focus,
1413 #content div.box div.form div.fields div.field input[type=password]:focus,
1413 #content div.box div.form div.fields div.field input[type=password]:focus,
1414 #content div.box div.form div.fields div.field input[type=file]:focus,
1414 #content div.box div.form div.fields div.field input[type=file]:focus,
1415 #content div.box div.form div.fields div.field textarea:focus,
1415 #content div.box div.form div.fields div.field textarea:focus,
1416 #content div.box div.form div.fields div.field select:focus,
1416 #content div.box div.form div.fields div.field select:focus,
1417 .reviewer_ac input:focus {
1417 .reviewer_ac input:focus {
1418 background: #f6f6f6;
1418 background: #f6f6f6;
1419 border-color: #666;
1419 border-color: #666;
1420 }
1420 }
1421
1421
1422 .reviewer_ac {
1422 .reviewer_ac {
1423 padding: 10px
1423 padding: 10px
1424 }
1424 }
1425
1425
1426 div.form div.fields div.field div.button {
1426 div.form div.fields div.field div.button {
1427 margin: 0;
1427 margin: 0;
1428 padding: 0 0 0 8px;
1428 padding: 0 0 0 8px;
1429 }
1429 }
1430 #content div.box table.noborder {
1430 #content div.box table.noborder {
1431 border: 1px solid transparent;
1431 border: 1px solid transparent;
1432 }
1432 }
1433
1433
1434 #content div.box table {
1434 #content div.box table {
1435 width: 100%;
1435 width: 100%;
1436 border-collapse: separate;
1436 border-collapse: separate;
1437 margin: 0;
1437 margin: 0;
1438 padding: 0;
1438 padding: 0;
1439 border: 1px solid #eee;
1439 border: 1px solid #eee;
1440 -webkit-border-radius: 4px;
1440 -webkit-border-radius: 4px;
1441 border-radius: 4px;
1441 border-radius: 4px;
1442 }
1442 }
1443
1443
1444 #content div.box table th {
1444 #content div.box table th {
1445 background: #eee;
1445 background: #eee;
1446 border-bottom: 1px solid #ddd;
1446 border-bottom: 1px solid #ddd;
1447 padding: 5px 0px 5px 5px;
1447 padding: 5px 0px 5px 5px;
1448 text-align: left;
1448 text-align: left;
1449 }
1449 }
1450
1450
1451 #content div.box table th.left {
1451 #content div.box table th.left {
1452 text-align: left;
1452 text-align: left;
1453 }
1453 }
1454
1454
1455 #content div.box table th.right {
1455 #content div.box table th.right {
1456 text-align: right;
1456 text-align: right;
1457 }
1457 }
1458
1458
1459 #content div.box table th.center {
1459 #content div.box table th.center {
1460 text-align: center;
1460 text-align: center;
1461 }
1461 }
1462
1462
1463 #content div.box table th.selected {
1463 #content div.box table th.selected {
1464 vertical-align: middle;
1464 vertical-align: middle;
1465 padding: 0;
1465 padding: 0;
1466 }
1466 }
1467
1467
1468 #content div.box table td {
1468 #content div.box table td {
1469 background: #fff;
1469 background: #fff;
1470 border-bottom: 1px solid #cdcdcd;
1470 border-bottom: 1px solid #cdcdcd;
1471 vertical-align: middle;
1471 vertical-align: middle;
1472 padding: 5px;
1472 padding: 5px;
1473 }
1473 }
1474
1474
1475 #content div.box table tr.selected td {
1475 #content div.box table tr.selected td {
1476 background: #FFC;
1476 background: #FFC;
1477 }
1477 }
1478
1478
1479 #content div.box table td.selected {
1479 #content div.box table td.selected {
1480 width: 3%;
1480 width: 3%;
1481 text-align: center;
1481 text-align: center;
1482 vertical-align: middle;
1482 vertical-align: middle;
1483 padding: 0;
1483 padding: 0;
1484 }
1484 }
1485
1485
1486 #content div.box table td.action {
1486 #content div.box table td.action {
1487 width: 45%;
1487 width: 45%;
1488 text-align: left;
1488 text-align: left;
1489 }
1489 }
1490
1490
1491 #content div.box table td.date {
1491 #content div.box table td.date {
1492 width: 33%;
1492 width: 33%;
1493 text-align: center;
1493 text-align: center;
1494 }
1494 }
1495
1495
1496 #content div.box div.action {
1496 #content div.box div.action {
1497 float: right;
1497 float: right;
1498 background: #FFF;
1498 background: #FFF;
1499 text-align: right;
1499 text-align: right;
1500 margin: 10px 0 0;
1500 margin: 10px 0 0;
1501 padding: 0;
1501 padding: 0;
1502 }
1502 }
1503
1503
1504 #content div.box div.action select {
1504 #content div.box div.action select {
1505 font-size: 11px;
1505 font-size: 11px;
1506 margin: 0;
1506 margin: 0;
1507 }
1507 }
1508
1508
1509 #content div.box div.action .ui-selectmenu {
1509 #content div.box div.action .ui-selectmenu {
1510 margin: 0;
1510 margin: 0;
1511 padding: 0;
1511 padding: 0;
1512 }
1512 }
1513
1513
1514 #content div.box div.pagination {
1514 #content div.box div.pagination {
1515 height: 1%;
1515 height: 1%;
1516 clear: both;
1516 clear: both;
1517 overflow: hidden;
1517 overflow: hidden;
1518 margin: 10px 0 0;
1518 margin: 10px 0 0;
1519 padding: 0;
1519 padding: 0;
1520 }
1520 }
1521
1521
1522 #content div.box div.pagination ul.pager {
1522 #content div.box div.pagination ul.pager {
1523 float: right;
1523 float: right;
1524 text-align: right;
1524 text-align: right;
1525 margin: 0;
1525 margin: 0;
1526 padding: 0;
1526 padding: 0;
1527 }
1527 }
1528
1528
1529 #content div.box div.pagination ul.pager li {
1529 #content div.box div.pagination ul.pager li {
1530 height: 1%;
1530 height: 1%;
1531 float: left;
1531 float: left;
1532 list-style: none;
1532 list-style: none;
1533 background: #ebebeb url("../images/pager.png") repeat-x;
1533 background: #ebebeb url("../images/pager.png") repeat-x;
1534 border-top: 1px solid #dedede;
1534 border-top: 1px solid #dedede;
1535 border-left: 1px solid #cfcfcf;
1535 border-left: 1px solid #cfcfcf;
1536 border-right: 1px solid #c4c4c4;
1536 border-right: 1px solid #c4c4c4;
1537 border-bottom: 1px solid #c4c4c4;
1537 border-bottom: 1px solid #c4c4c4;
1538 color: #4A4A4A;
1538 color: #4A4A4A;
1539 font-weight: 700;
1539 font-weight: 700;
1540 margin: 0 0 0 4px;
1540 margin: 0 0 0 4px;
1541 padding: 0;
1541 padding: 0;
1542 }
1542 }
1543
1543
1544 #content div.box div.pagination ul.pager li.separator {
1544 #content div.box div.pagination ul.pager li.separator {
1545 padding: 6px;
1545 padding: 6px;
1546 }
1546 }
1547
1547
1548 #content div.box div.pagination ul.pager li.current {
1548 #content div.box div.pagination ul.pager li.current {
1549 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1549 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1550 border-top: 1px solid #ccc;
1550 border-top: 1px solid #ccc;
1551 border-left: 1px solid #bebebe;
1551 border-left: 1px solid #bebebe;
1552 border-right: 1px solid #b1b1b1;
1552 border-right: 1px solid #b1b1b1;
1553 border-bottom: 1px solid #afafaf;
1553 border-bottom: 1px solid #afafaf;
1554 color: #515151;
1554 color: #515151;
1555 padding: 6px;
1555 padding: 6px;
1556 }
1556 }
1557
1557
1558 #content div.box div.pagination ul.pager li a {
1558 #content div.box div.pagination ul.pager li a {
1559 height: 1%;
1559 height: 1%;
1560 display: block;
1560 display: block;
1561 float: left;
1561 float: left;
1562 color: #515151;
1562 color: #515151;
1563 text-decoration: none;
1563 text-decoration: none;
1564 margin: 0;
1564 margin: 0;
1565 padding: 6px;
1565 padding: 6px;
1566 }
1566 }
1567
1567
1568 #content div.box div.pagination ul.pager li a:hover,
1568 #content div.box div.pagination ul.pager li a:hover,
1569 #content div.box div.pagination ul.pager li a:active {
1569 #content div.box div.pagination ul.pager li a:active {
1570 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1570 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1571 border-top: 1px solid #ccc;
1571 border-top: 1px solid #ccc;
1572 border-left: 1px solid #bebebe;
1572 border-left: 1px solid #bebebe;
1573 border-right: 1px solid #b1b1b1;
1573 border-right: 1px solid #b1b1b1;
1574 border-bottom: 1px solid #afafaf;
1574 border-bottom: 1px solid #afafaf;
1575 margin: -1px;
1575 margin: -1px;
1576 }
1576 }
1577
1577
1578 #content div.box div.pagination-right {
1578 #content div.box div.pagination-right {
1579 float: right;
1579 float: right;
1580 }
1580 }
1581
1581
1582 #content div.box div.pagination-wh {
1582 #content div.box div.pagination-wh {
1583 height: 1%;
1583 height: 1%;
1584 overflow: hidden;
1584 overflow: hidden;
1585 text-align: right;
1585 text-align: right;
1586 margin: 10px 0 0;
1586 margin: 10px 0 0;
1587 padding: 0;
1587 padding: 0;
1588 }
1588 }
1589
1589
1590 #content div.box div.pagination-wh > :first-child {
1590 #content div.box div.pagination-wh > :first-child {
1591 border-radius: 4px 0px 0px 4px;
1591 border-radius: 4px 0px 0px 4px;
1592 }
1592 }
1593
1593
1594 #content div.box div.pagination-wh > :last-child{
1594 #content div.box div.pagination-wh > :last-child {
1595 border-radius: 0px 4px 4px 0px;
1595 border-radius: 0px 4px 4px 0px;
1596 border-right: 1px solid #cfcfcf;
1596 border-right: 1px solid #cfcfcf;
1597 }
1597 }
1598
1598
1599 #content div.box div.pagination-wh a,
1599 #content div.box div.pagination-wh a,
1600 #content div.box div.pagination-wh span.pager_dotdot,
1600 #content div.box div.pagination-wh span.pager_dotdot,
1601 #content div.box div.pagination-wh span.yui-pg-previous,
1601 #content div.box div.pagination-wh span.yui-pg-previous,
1602 #content div.box div.pagination-wh span.yui-pg-last,
1602 #content div.box div.pagination-wh span.yui-pg-last,
1603 #content div.box div.pagination-wh span.yui-pg-next,
1603 #content div.box div.pagination-wh span.yui-pg-next,
1604 #content div.box div.pagination-wh span.yui-pg-first {
1604 #content div.box div.pagination-wh span.yui-pg-first {
1605 height: 1%;
1605 height: 1%;
1606 float: left;
1606 float: left;
1607 background: #ebebeb url("../images/pager.png") repeat-x;
1607 background: #ebebeb url("../images/pager.png") repeat-x;
1608 border-top: 1px solid #dedede;
1608 border-top: 1px solid #dedede;
1609 border-left: 1px solid #cfcfcf;
1609 border-left: 1px solid #cfcfcf;
1610 border-bottom: 1px solid #c4c4c4;
1610 border-bottom: 1px solid #c4c4c4;
1611 color: #4A4A4A;
1611 color: #4A4A4A;
1612 font-weight: 700;
1612 font-weight: 700;
1613 padding: 6px;
1613 padding: 6px;
1614 }
1614 }
1615
1615
1616 #content div.box div.pagination-wh span.pager_curpage {
1616 #content div.box div.pagination-wh span.pager_curpage {
1617 height: 1%;
1617 height: 1%;
1618 float: left;
1618 float: left;
1619 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1619 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1620 border-top: 1px solid #ccc;
1620 border-top: 1px solid #ccc;
1621 border-left: 1px solid #bebebe;
1621 border-left: 1px solid #bebebe;
1622 border-bottom: 1px solid #afafaf;
1622 border-bottom: 1px solid #afafaf;
1623 color: #515151;
1623 color: #515151;
1624 font-weight: 700;
1624 font-weight: 700;
1625 padding: 6px;
1625 padding: 6px;
1626 }
1626 }
1627
1627
1628 #content div.box div.pagination-wh a:hover, #content div.box div.pagination-wh a:active {
1628 #content div.box div.pagination-wh a:hover, #content div.box div.pagination-wh a:active {
1629 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1629 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1630 border-top: 1px solid #ccc;
1630 border-top: 1px solid #ccc;
1631 border-left: 1px solid #bebebe;
1631 border-left: 1px solid #bebebe;
1632 border-bottom: 1px solid #afafaf;
1632 border-bottom: 1px solid #afafaf;
1633 text-decoration: none;
1633 text-decoration: none;
1634 }
1634 }
1635
1635
1636 #content div.box div.traffic div.legend {
1636 #content div.box div.traffic div.legend {
1637 clear: both;
1637 clear: both;
1638 overflow: hidden;
1638 overflow: hidden;
1639 border-bottom: 1px solid #ddd;
1639 border-bottom: 1px solid #ddd;
1640 margin: 0 0 10px;
1640 margin: 0 0 10px;
1641 padding: 0 0 10px;
1641 padding: 0 0 10px;
1642 }
1642 }
1643
1643
1644 #content div.box div.traffic div.legend h6 {
1644 #content div.box div.traffic div.legend h6 {
1645 float: left;
1645 float: left;
1646 border: none;
1646 border: none;
1647 margin: 0;
1647 margin: 0;
1648 padding: 0;
1648 padding: 0;
1649 }
1649 }
1650
1650
1651 #content div.box div.traffic div.legend li {
1651 #content div.box div.traffic div.legend li {
1652 list-style: none;
1652 list-style: none;
1653 float: left;
1653 float: left;
1654 font-size: 11px;
1654 font-size: 11px;
1655 margin: 0;
1655 margin: 0;
1656 padding: 0 8px 0 4px;
1656 padding: 0 8px 0 4px;
1657 }
1657 }
1658
1658
1659 #content div.box div.traffic div.legend li.visits {
1659 #content div.box div.traffic div.legend li.visits {
1660 border-left: 12px solid #edc240;
1660 border-left: 12px solid #edc240;
1661 }
1661 }
1662
1662
1663 #content div.box div.traffic div.legend li.pageviews {
1663 #content div.box div.traffic div.legend li.pageviews {
1664 border-left: 12px solid #afd8f8;
1664 border-left: 12px solid #afd8f8;
1665 }
1665 }
1666
1666
1667 #content div.box div.traffic table {
1667 #content div.box div.traffic table {
1668 width: auto;
1668 width: auto;
1669 }
1669 }
1670
1670
1671 #content div.box div.traffic table td {
1671 #content div.box div.traffic table td {
1672 background: transparent;
1672 background: transparent;
1673 border: none;
1673 border: none;
1674 padding: 2px 3px 3px;
1674 padding: 2px 3px 3px;
1675 }
1675 }
1676
1676
1677 #content div.box div.traffic table td.legendLabel {
1677 #content div.box div.traffic table td.legendLabel {
1678 padding: 0 3px 2px;
1678 padding: 0 3px 2px;
1679 }
1679 }
1680
1680
1681 #content div.box #summary {
1681 #content div.box #summary {
1682 margin-right: 200px;
1682 margin-right: 200px;
1683 }
1683 }
1684
1684
1685 #summary-menu-stats {
1685 #summary-menu-stats {
1686 float: left;
1686 float: left;
1687 width: 180px;
1687 width: 180px;
1688 position: absolute;
1688 position: absolute;
1689 top: 0;
1689 top: 0;
1690 right: 0;
1690 right: 0;
1691 }
1691 }
1692
1692
1693 #summary-menu-stats ul {
1693 #summary-menu-stats ul {
1694 margin: 0 10px;
1694 margin: 0 10px;
1695 display: block;
1695 display: block;
1696 background-color: #f9f9f9;
1696 background-color: #f9f9f9;
1697 border: 1px solid #d1d1d1;
1697 border: 1px solid #d1d1d1;
1698 border-radius: 4px;
1698 border-radius: 4px;
1699 }
1699 }
1700
1700
1701 #content #summary-menu-stats li {
1701 #content #summary-menu-stats li {
1702 border-top: 1px solid #d1d1d1;
1702 border-top: 1px solid #d1d1d1;
1703 padding: 0;
1703 padding: 0;
1704 }
1704 }
1705
1705
1706 #content #summary-menu-stats li:hover {
1706 #content #summary-menu-stats li:hover {
1707 background: #f0f0f0;
1707 background: #f0f0f0;
1708 }
1708 }
1709
1709
1710 #content #summary-menu-stats li:first-child {
1710 #content #summary-menu-stats li:first-child {
1711 border-top: none;
1711 border-top: none;
1712 }
1712 }
1713
1713
1714 #summary-menu-stats a.followers { background-image: url('../images/icons/heart.png')}
1714 #summary-menu-stats a.followers { background-image: url('../images/icons/heart.png')}
1715 #summary-menu-stats a.forks { background-image: url('../images/icons/arrow_divide.png')}
1715 #summary-menu-stats a.forks { background-image: url('../images/icons/arrow_divide.png')}
1716 #summary-menu-stats a.settings { background-image: url('../images/icons/cog_edit.png')}
1716 #summary-menu-stats a.settings { background-image: url('../images/icons/cog_edit.png')}
1717 #summary-menu-stats a.feed { background-image: url('../images/icons/rss_16.png')}
1717 #summary-menu-stats a.feed { background-image: url('../images/icons/rss_16.png')}
1718 #summary-menu-stats a.repo-size { background-image: url('../images/icons/server.png')}
1718 #summary-menu-stats a.repo-size { background-image: url('../images/icons/server.png')}
1719
1719
1720 #summary-menu-stats a {
1720 #summary-menu-stats a {
1721 display: block;
1721 display: block;
1722 padding: 12px 30px;
1722 padding: 12px 30px;
1723 background-repeat: no-repeat;
1723 background-repeat: no-repeat;
1724 background-position: 10px 50%;
1724 background-position: 10px 50%;
1725 padding-right: 10px;
1725 padding-right: 10px;
1726 }
1726 }
1727
1727
1728 #repo_size_2.loaded {
1728 #repo_size_2.loaded {
1729 margin-left: 30px;
1729 margin-left: 30px;
1730 display: block;
1730 display: block;
1731 padding-right: 10px;
1731 padding-right: 10px;
1732 padding-bottom: 7px;
1732 padding-bottom: 7px;
1733 }
1733 }
1734
1734
1735 #summary-menu-stats a:hover {
1735 #summary-menu-stats a:hover {
1736 text-decoration: none;
1736 text-decoration: none;
1737 }
1737 }
1738
1738
1739 #summary-menu-stats a span {
1739 #summary-menu-stats a span {
1740 background-color: #DEDEDE;
1740 background-color: #DEDEDE;
1741 color: 888 !important;
1741 color: 888 !important;
1742 border-radius: 4px;
1742 border-radius: 4px;
1743 padding: 2px 4px;
1743 padding: 2px 4px;
1744 font-size: 10px;
1744 font-size: 10px;
1745 }
1745 }
1746
1746
1747 #summary .metatag {
1747 #summary .metatag {
1748 display: inline-block;
1748 display: inline-block;
1749 padding: 3px 5px;
1749 padding: 3px 5px;
1750 margin-bottom: 3px;
1750 margin-bottom: 3px;
1751 margin-right: 1px;
1751 margin-right: 1px;
1752 border-radius: 5px;
1752 border-radius: 5px;
1753 }
1753 }
1754
1754
1755 #content div.box #summary p {
1755 #content div.box #summary p {
1756 margin-bottom: -5px;
1756 margin-bottom: -5px;
1757 width: 600px;
1757 width: 600px;
1758 white-space: pre-wrap;
1758 white-space: pre-wrap;
1759 }
1759 }
1760
1760
1761 #content div.box #summary p:last-child {
1761 #content div.box #summary p:last-child {
1762 margin-bottom: 9px;
1762 margin-bottom: 9px;
1763 }
1763 }
1764
1764
1765 #content div.box #summary p:first-of-type {
1765 #content div.box #summary p:first-of-type {
1766 margin-top: 9px;
1766 margin-top: 9px;
1767 }
1767 }
1768
1768
1769 .metatag {
1769 .metatag {
1770 display: inline-block;
1770 display: inline-block;
1771 margin-right: 1px;
1771 margin-right: 1px;
1772 -webkit-border-radius: 4px 4px 4px 4px;
1772 -webkit-border-radius: 4px 4px 4px 4px;
1773 -khtml-border-radius: 4px 4px 4px 4px;
1773 -khtml-border-radius: 4px 4px 4px 4px;
1774 border-radius: 4px 4px 4px 4px;
1774 border-radius: 4px 4px 4px 4px;
1775
1775
1776 border: solid 1px #9CF;
1776 border: solid 1px #9CF;
1777 padding: 2px 3px 2px 3px !important;
1777 padding: 2px 3px 2px 3px !important;
1778 background-color: #DEF;
1778 background-color: #DEF;
1779 }
1779 }
1780
1780
1781 .metatag[tag="dead"] {
1781 .metatag[tag="dead"] {
1782 background-color: #E44;
1782 background-color: #E44;
1783 }
1783 }
1784
1784
1785 .metatag[tag="stale"] {
1785 .metatag[tag="stale"] {
1786 background-color: #EA4;
1786 background-color: #EA4;
1787 }
1787 }
1788
1788
1789 .metatag[tag="featured"] {
1789 .metatag[tag="featured"] {
1790 background-color: #AEA;
1790 background-color: #AEA;
1791 }
1791 }
1792
1792
1793 .metatag[tag="requires"] {
1793 .metatag[tag="requires"] {
1794 background-color: #9CF;
1794 background-color: #9CF;
1795 }
1795 }
1796
1796
1797 .metatag[tag="recommends"] {
1797 .metatag[tag="recommends"] {
1798 background-color: #BDF;
1798 background-color: #BDF;
1799 }
1799 }
1800
1800
1801 .metatag[tag="lang"] {
1801 .metatag[tag="lang"] {
1802 background-color: #FAF474;
1802 background-color: #FAF474;
1803 }
1803 }
1804
1804
1805 .metatag[tag="license"] {
1805 .metatag[tag="license"] {
1806 border: solid 1px #9CF;
1806 border: solid 1px #9CF;
1807 background-color: #DEF;
1807 background-color: #DEF;
1808 target-new: tab !important;
1808 target-new: tab !important;
1809 }
1809 }
1810 .metatag[tag="see"] {
1810 .metatag[tag="see"] {
1811 border: solid 1px #CBD;
1811 border: solid 1px #CBD;
1812 background-color: #EDF;
1812 background-color: #EDF;
1813 }
1813 }
1814
1814
1815 a.metatag[tag="license"]:hover {
1815 a.metatag[tag="license"]:hover {
1816 background-color: #003367;
1816 background-color: #003367;
1817 color: #FFF;
1817 color: #FFF;
1818 text-decoration: none;
1818 text-decoration: none;
1819 }
1819 }
1820
1820
1821 #summary .desc {
1821 #summary .desc {
1822 white-space: pre;
1822 white-space: pre;
1823 width: 100%;
1823 width: 100%;
1824 }
1824 }
1825
1825
1826 #summary .repo_name {
1826 #summary .repo_name {
1827 font-size: 1.6em;
1827 font-size: 1.6em;
1828 font-weight: bold;
1828 font-weight: bold;
1829 vertical-align: baseline;
1829 vertical-align: baseline;
1830 clear: right
1830 clear: right
1831 }
1831 }
1832
1832
1833 #footer {
1833 #footer {
1834 clear: both;
1834 clear: both;
1835 overflow: hidden;
1835 overflow: hidden;
1836 text-align: right;
1836 text-align: right;
1837 margin: 0;
1837 margin: 0;
1838 padding: 0 10px 4px;
1838 padding: 0 10px 4px;
1839 margin: -10px 0 0;
1839 margin: -10px 0 0;
1840 }
1840 }
1841
1841
1842 #footer div#footer-inner {
1842 #footer div#footer-inner {
1843 background-color: #003B76;
1843 background-color: #003B76;
1844 background-repeat: repeat-x;
1844 background-repeat: repeat-x;
1845 background-image: -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
1845 background-image: -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
1846 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1846 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1847 background-image: -ms-linear-gradient( top, #003b76, #00376e);
1847 background-image: -ms-linear-gradient( top, #003b76, #00376e);
1848 background-image: -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1848 background-image: -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1849 background-image: -webkit-linear-gradient( top, #003b76, #00376e));
1849 background-image: -webkit-linear-gradient( top, #003b76, #00376e));
1850 background-image: -o-linear-gradient( top, #003b76, #00376e));
1850 background-image: -o-linear-gradient( top, #003b76, #00376e));
1851 background-image: linear-gradient(to bottom, #003b76, #00376e);
1851 background-image: linear-gradient(to bottom, #003b76, #00376e);
1852 filter: progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
1852 filter: progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
1853 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1853 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1854 -webkit-border-radius: 4px 4px 4px 4px;
1854 -webkit-border-radius: 4px 4px 4px 4px;
1855 -khtml-border-radius: 4px 4px 4px 4px;
1855 -khtml-border-radius: 4px 4px 4px 4px;
1856 border-radius: 4px 4px 4px 4px;
1856 border-radius: 4px 4px 4px 4px;
1857 }
1857 }
1858
1858
1859 #footer div#footer-inner p {
1859 #footer div#footer-inner p {
1860 padding: 15px 25px 15px 0;
1860 padding: 15px 25px 15px 0;
1861 color: #FFF;
1861 color: #FFF;
1862 font-weight: 700;
1862 font-weight: 700;
1863 }
1863 }
1864
1864
1865 #footer div#footer-inner .footer-link {
1865 #footer div#footer-inner .footer-link {
1866 float: left;
1866 float: left;
1867 padding-left: 10px;
1867 padding-left: 10px;
1868 }
1868 }
1869
1869
1870 #footer div#footer-inner .footer-link a, #footer div#footer-inner .footer-link-right a {
1870 #footer div#footer-inner .footer-link a, #footer div#footer-inner .footer-link-right a {
1871 color: #FFF;
1871 color: #FFF;
1872 }
1872 }
1873
1873
1874 #login div.title {
1874 #login div.title {
1875 clear: both;
1875 clear: both;
1876 overflow: hidden;
1876 overflow: hidden;
1877 position: relative;
1877 position: relative;
1878 background-color: #003B76;
1878 background-color: #003B76;
1879 background-repeat: repeat-x;
1879 background-repeat: repeat-x;
1880 background-image: -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
1880 background-image: -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
1881 background-image: -moz-linear-gradient( top, #003b76, #00376e);
1881 background-image: -moz-linear-gradient( top, #003b76, #00376e);
1882 background-image: -ms-linear-gradient( top, #003b76, #00376e);
1882 background-image: -ms-linear-gradient( top, #003b76, #00376e);
1883 background-image: -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1883 background-image: -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1884 background-image: -webkit-linear-gradient( top, #003b76, #00376e));
1884 background-image: -webkit-linear-gradient( top, #003b76, #00376e));
1885 background-image: -o-linear-gradient( top, #003b76, #00376e));
1885 background-image: -o-linear-gradient( top, #003b76, #00376e));
1886 background-image: linear-gradient(to bottom, #003b76, #00376e);
1886 background-image: linear-gradient(to bottom, #003b76, #00376e);
1887 filter: progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
1887 filter: progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
1888 margin: 0 auto;
1888 margin: 0 auto;
1889 padding: 0;
1889 padding: 0;
1890 }
1890 }
1891
1891
1892 #login div.inner {
1892 #login div.inner {
1893 background: #FFF url("../images/login.png") no-repeat top left;
1893 background: #FFF url("../images/login.png") no-repeat top left;
1894 border-top: none;
1894 border-top: none;
1895 border-bottom: none;
1895 border-bottom: none;
1896 margin: 0 auto;
1896 margin: 0 auto;
1897 padding: 20px;
1897 padding: 20px;
1898 }
1898 }
1899
1899
1900 #login div.form div.fields div.field div.label {
1900 #login div.form div.fields div.field div.label {
1901 width: 173px;
1901 width: 173px;
1902 float: left;
1902 float: left;
1903 text-align: right;
1903 text-align: right;
1904 margin: 2px 10px 0 0;
1904 margin: 2px 10px 0 0;
1905 padding: 5px 0 0 5px;
1905 padding: 5px 0 0 5px;
1906 }
1906 }
1907
1907
1908 #login div.form div.fields div.field div.input input {
1908 #login div.form div.fields div.field div.input input {
1909 background: #FFF;
1909 background: #FFF;
1910 border-top: 1px solid #b3b3b3;
1910 border-top: 1px solid #b3b3b3;
1911 border-left: 1px solid #b3b3b3;
1911 border-left: 1px solid #b3b3b3;
1912 border-right: 1px solid #eaeaea;
1912 border-right: 1px solid #eaeaea;
1913 border-bottom: 1px solid #eaeaea;
1913 border-bottom: 1px solid #eaeaea;
1914 color: #000;
1914 color: #000;
1915 font-size: 11px;
1915 font-size: 11px;
1916 margin: 0;
1916 margin: 0;
1917 padding: 7px 7px 6px;
1917 padding: 7px 7px 6px;
1918 }
1918 }
1919
1919
1920 #login div.form div.fields div.buttons {
1920 #login div.form div.fields div.buttons {
1921 clear: both;
1921 clear: both;
1922 overflow: hidden;
1922 overflow: hidden;
1923 border-top: 1px solid #DDD;
1923 border-top: 1px solid #DDD;
1924 text-align: right;
1924 text-align: right;
1925 margin: 0;
1925 margin: 0;
1926 padding: 10px 0 0;
1926 padding: 10px 0 0;
1927 }
1927 }
1928
1928
1929 #login div.form div.links {
1929 #login div.form div.links {
1930 clear: both;
1930 clear: both;
1931 overflow: hidden;
1931 overflow: hidden;
1932 margin: 10px 0 0;
1932 margin: 10px 0 0;
1933 padding: 0 0 2px;
1933 padding: 0 0 2px;
1934 }
1934 }
1935
1935
1936 .user-menu {
1936 .user-menu {
1937 margin: 0px !important;
1937 margin: 0px !important;
1938 float: left;
1938 float: left;
1939 }
1939 }
1940
1940
1941 .user-menu .container {
1941 .user-menu .container {
1942 padding: 0px 4px 0px 4px;
1942 padding: 0px 4px 0px 4px;
1943 margin: 0px 0px 0px 0px;
1943 margin: 0px 0px 0px 0px;
1944 }
1944 }
1945
1945
1946 .user-menu .gravatar {
1946 .user-menu .gravatar {
1947 margin: 0px 0px 0px 0px;
1947 margin: 0px 0px 0px 0px;
1948 cursor: pointer;
1948 cursor: pointer;
1949 }
1949 }
1950 .user-menu .gravatar.enabled {
1950 .user-menu .gravatar.enabled {
1951 background-color: #FDF784 !important;
1951 background-color: #FDF784 !important;
1952 }
1952 }
1953 .user-menu .gravatar:hover {
1953 .user-menu .gravatar:hover {
1954 background-color: #FDF784 !important;
1954 background-color: #FDF784 !important;
1955 }
1955 }
1956 #quick_login {
1956 #quick_login {
1957 min-height: 110px;
1957 min-height: 110px;
1958 padding: 4px;
1958 padding: 4px;
1959 position: absolute;
1959 position: absolute;
1960 right: 0;
1960 right: 0;
1961 background-color: #003B76;
1961 background-color: #003B76;
1962 background-repeat: repeat-x;
1962 background-repeat: repeat-x;
1963 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
1963 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
1964 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1964 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1965 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1965 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1966 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
1966 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
1967 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
1967 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
1968 background-image: -o-linear-gradient(top, #003b76, #00376e);
1968 background-image: -o-linear-gradient(top, #003b76, #00376e);
1969 background-image: linear-gradient(to bottom, #003b76, #00376e);
1969 background-image: linear-gradient(to bottom, #003b76, #00376e);
1970 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
1970 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
1971
1971
1972 z-index: 999;
1972 z-index: 999;
1973 -webkit-border-radius: 0px 0px 4px 4px;
1973 -webkit-border-radius: 0px 0px 4px 4px;
1974 -khtml-border-radius: 0px 0px 4px 4px;
1974 -khtml-border-radius: 0px 0px 4px 4px;
1975 border-radius: 0px 0px 4px 4px;
1975 border-radius: 0px 0px 4px 4px;
1976 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1976 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1977
1977
1978 overflow: hidden;
1978 overflow: hidden;
1979 }
1979 }
1980 #quick_login h4 {
1980 #quick_login h4 {
1981 color: #fff;
1981 color: #fff;
1982 padding: 5px 0px 5px 14px;
1982 padding: 5px 0px 5px 14px;
1983 }
1983 }
1984
1984
1985 #quick_login .password_forgoten {
1985 #quick_login .password_forgoten {
1986 padding-right: 0px;
1986 padding-right: 0px;
1987 padding-top: 0px;
1987 padding-top: 0px;
1988 text-align: left;
1988 text-align: left;
1989 }
1989 }
1990
1990
1991 #quick_login .password_forgoten a {
1991 #quick_login .password_forgoten a {
1992 font-size: 10px;
1992 font-size: 10px;
1993 color: #fff;
1993 color: #fff;
1994 padding: 0px !important;
1994 padding: 0px !important;
1995 line-height: 20px !important;
1995 line-height: 20px !important;
1996 }
1996 }
1997
1997
1998 #quick_login .register {
1998 #quick_login .register {
1999 padding-right: 10px;
1999 padding-right: 10px;
2000 padding-top: 5px;
2000 padding-top: 5px;
2001 text-align: left;
2001 text-align: left;
2002 }
2002 }
2003
2003
2004 #quick_login .register a {
2004 #quick_login .register a {
2005 font-size: 10px;
2005 font-size: 10px;
2006 color: #fff;
2006 color: #fff;
2007 padding: 0px !important;
2007 padding: 0px !important;
2008 line-height: 20px !important;
2008 line-height: 20px !important;
2009 }
2009 }
2010
2010
2011 #quick_login .submit {
2011 #quick_login .submit {
2012 margin: -20px 0 0 0px;
2012 margin: -20px 0 0 0px;
2013 position: absolute;
2013 position: absolute;
2014 right: 15px;
2014 right: 15px;
2015 }
2015 }
2016
2016
2017 #quick_login .links_left {
2017 #quick_login .links_left {
2018 float: left;
2018 float: left;
2019 margin-right: 130px;
2019 margin-right: 130px;
2020 width: 170px;
2020 width: 170px;
2021 }
2021 }
2022 #quick_login .links_right {
2022 #quick_login .links_right {
2023
2023
2024 position: absolute;
2024 position: absolute;
2025 right: 0;
2025 right: 0;
2026 }
2026 }
2027 #quick_login .full_name {
2027 #quick_login .full_name {
2028 color: #FFFFFF;
2028 color: #FFFFFF;
2029 font-weight: bold;
2029 font-weight: bold;
2030 padding: 3px 3px 3px 6px;
2030 padding: 3px 3px 3px 6px;
2031 }
2031 }
2032 #quick_login .big_gravatar {
2032 #quick_login .big_gravatar {
2033 padding: 4px 0px 0px 6px;
2033 padding: 4px 0px 0px 6px;
2034 }
2034 }
2035 #quick_login .notifications {
2035 #quick_login .notifications {
2036 padding: 2px 0px 0px 6px;
2036 padding: 2px 0px 0px 6px;
2037 color: #FFFFFF;
2037 color: #FFFFFF;
2038 font-weight: bold;
2038 font-weight: bold;
2039 line-height: 10px !important;
2039 line-height: 10px !important;
2040 }
2040 }
2041 #quick_login .notifications a,
2041 #quick_login .notifications a,
2042 #quick_login .unread a {
2042 #quick_login .unread a {
2043 color: #FFFFFF;
2043 color: #FFFFFF;
2044 display: block;
2044 display: block;
2045 padding: 0px !important;
2045 padding: 0px !important;
2046 }
2046 }
2047 #quick_login .notifications a:hover,
2047 #quick_login .notifications a:hover,
2048 #quick_login .unread a:hover {
2048 #quick_login .unread a:hover {
2049 background-color: inherit !important;
2049 background-color: inherit !important;
2050 }
2050 }
2051 #quick_login .email, #quick_login .unread {
2051 #quick_login .email, #quick_login .unread {
2052 color: #FFFFFF;
2052 color: #FFFFFF;
2053 padding: 3px 3px 3px 6px;
2053 padding: 3px 3px 3px 6px;
2054 }
2054 }
2055 #quick_login .links .logout {
2055 #quick_login .links .logout {
2056 }
2056 }
2057
2057
2058 #quick_login div.form div.fields {
2058 #quick_login div.form div.fields {
2059 padding-top: 2px;
2059 padding-top: 2px;
2060 padding-left: 10px;
2060 padding-left: 10px;
2061 }
2061 }
2062
2062
2063 #quick_login div.form div.fields div.field {
2063 #quick_login div.form div.fields div.field {
2064 padding: 5px;
2064 padding: 5px;
2065 }
2065 }
2066
2066
2067 #quick_login div.form div.fields div.field div.label label {
2067 #quick_login div.form div.fields div.field div.label label {
2068 color: #fff;
2068 color: #fff;
2069 padding-bottom: 3px;
2069 padding-bottom: 3px;
2070 }
2070 }
2071
2071
2072 #quick_login div.form div.fields div.field div.input input {
2072 #quick_login div.form div.fields div.field div.input input {
2073 width: 236px;
2073 width: 236px;
2074 background: #FFF;
2074 background: #FFF;
2075 border-top: 1px solid #b3b3b3;
2075 border-top: 1px solid #b3b3b3;
2076 border-left: 1px solid #b3b3b3;
2076 border-left: 1px solid #b3b3b3;
2077 border-right: 1px solid #eaeaea;
2077 border-right: 1px solid #eaeaea;
2078 border-bottom: 1px solid #eaeaea;
2078 border-bottom: 1px solid #eaeaea;
2079 color: #000;
2079 color: #000;
2080 font-size: 11px;
2080 font-size: 11px;
2081 margin: 0;
2081 margin: 0;
2082 padding: 5px 7px 4px;
2082 padding: 5px 7px 4px;
2083 }
2083 }
2084
2084
2085 #quick_login div.form div.fields div.buttons {
2085 #quick_login div.form div.fields div.buttons {
2086 clear: both;
2086 clear: both;
2087 overflow: hidden;
2087 overflow: hidden;
2088 text-align: right;
2088 text-align: right;
2089 margin: 0;
2089 margin: 0;
2090 padding: 5px 14px 0px 5px;
2090 padding: 5px 14px 0px 5px;
2091 }
2091 }
2092
2092
2093 #quick_login div.form div.links {
2093 #quick_login div.form div.links {
2094 clear: both;
2094 clear: both;
2095 overflow: hidden;
2095 overflow: hidden;
2096 margin: 10px 0 0;
2096 margin: 10px 0 0;
2097 padding: 0 0 2px;
2097 padding: 0 0 2px;
2098 }
2098 }
2099
2099
2100 #quick_login ol.links {
2100 #quick_login ol.links {
2101 display: block;
2101 display: block;
2102 font-weight: bold;
2102 font-weight: bold;
2103 list-style: none outside none;
2103 list-style: none outside none;
2104 text-align: right;
2104 text-align: right;
2105 }
2105 }
2106 #quick_login ol.links li {
2106 #quick_login ol.links li {
2107 line-height: 27px;
2107 line-height: 27px;
2108 margin: 0;
2108 margin: 0;
2109 padding: 0;
2109 padding: 0;
2110 color: #fff;
2110 color: #fff;
2111 display: block;
2111 display: block;
2112 float: none !important;
2112 float: none !important;
2113 }
2113 }
2114
2114
2115 #quick_login ol.links li a {
2115 #quick_login ol.links li a {
2116 color: #fff;
2116 color: #fff;
2117 display: block;
2117 display: block;
2118 padding: 2px;
2118 padding: 2px;
2119 }
2119 }
2120 #quick_login ol.links li a:HOVER {
2120 #quick_login ol.links li a:HOVER {
2121 background-color: inherit !important;
2121 background-color: inherit !important;
2122 }
2122 }
2123
2123
2124 #register div.title {
2124 #register div.title {
2125 clear: both;
2125 clear: both;
2126 overflow: hidden;
2126 overflow: hidden;
2127 position: relative;
2127 position: relative;
2128 background-color: #003B76;
2128 background-color: #003B76;
2129 background-repeat: repeat-x;
2129 background-repeat: repeat-x;
2130 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2130 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2131 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2131 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2132 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2132 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2133 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2133 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2134 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2134 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2135 background-image: -o-linear-gradient(top, #003b76, #00376e);
2135 background-image: -o-linear-gradient(top, #003b76, #00376e);
2136 background-image: linear-gradient(to bottom, #003b76, #00376e);
2136 background-image: linear-gradient(to bottom, #003b76, #00376e);
2137 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
2137 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
2138 endColorstr='#00376e', GradientType=0 );
2138 endColorstr='#00376e', GradientType=0 );
2139 margin: 0 auto;
2139 margin: 0 auto;
2140 padding: 0;
2140 padding: 0;
2141 }
2141 }
2142
2142
2143 #register div.inner {
2143 #register div.inner {
2144 background: #FFF;
2144 background: #FFF;
2145 border-top: none;
2145 border-top: none;
2146 border-bottom: none;
2146 border-bottom: none;
2147 margin: 0 auto;
2147 margin: 0 auto;
2148 padding: 20px;
2148 padding: 20px;
2149 }
2149 }
2150
2150
2151 #register div.form div.fields div.field div.label {
2151 #register div.form div.fields div.field div.label {
2152 width: 135px;
2152 width: 135px;
2153 float: left;
2153 float: left;
2154 text-align: right;
2154 text-align: right;
2155 margin: 2px 10px 0 0;
2155 margin: 2px 10px 0 0;
2156 padding: 5px 0 0 5px;
2156 padding: 5px 0 0 5px;
2157 }
2157 }
2158
2158
2159 #register div.form div.fields div.field div.input input {
2159 #register div.form div.fields div.field div.input input {
2160 width: 300px;
2160 width: 300px;
2161 background: #FFF;
2161 background: #FFF;
2162 border-top: 1px solid #b3b3b3;
2162 border-top: 1px solid #b3b3b3;
2163 border-left: 1px solid #b3b3b3;
2163 border-left: 1px solid #b3b3b3;
2164 border-right: 1px solid #eaeaea;
2164 border-right: 1px solid #eaeaea;
2165 border-bottom: 1px solid #eaeaea;
2165 border-bottom: 1px solid #eaeaea;
2166 color: #000;
2166 color: #000;
2167 font-size: 11px;
2167 font-size: 11px;
2168 margin: 0;
2168 margin: 0;
2169 padding: 7px 7px 6px;
2169 padding: 7px 7px 6px;
2170 }
2170 }
2171
2171
2172 #register div.form div.fields div.buttons {
2172 #register div.form div.fields div.buttons {
2173 clear: both;
2173 clear: both;
2174 overflow: hidden;
2174 overflow: hidden;
2175 border-top: 1px solid #DDD;
2175 border-top: 1px solid #DDD;
2176 text-align: left;
2176 text-align: left;
2177 margin: 0;
2177 margin: 0;
2178 padding: 10px 0 0 150px;
2178 padding: 10px 0 0 150px;
2179 }
2179 }
2180
2180
2181 #register div.form div.activation_msg {
2181 #register div.form div.activation_msg {
2182 padding-top: 4px;
2182 padding-top: 4px;
2183 padding-bottom: 4px;
2183 padding-bottom: 4px;
2184 }
2184 }
2185
2185
2186 #journal .journal_day {
2186 #journal .journal_day {
2187 font-size: 20px;
2187 font-size: 20px;
2188 padding: 10px 0px;
2188 padding: 10px 0px;
2189 border-bottom: 2px solid #DDD;
2189 border-bottom: 2px solid #DDD;
2190 margin-left: 10px;
2190 margin-left: 10px;
2191 margin-right: 10px;
2191 margin-right: 10px;
2192 }
2192 }
2193
2193
2194 #journal .journal_container {
2194 #journal .journal_container {
2195 padding: 5px;
2195 padding: 5px;
2196 clear: both;
2196 clear: both;
2197 margin: 0px 5px 0px 10px;
2197 margin: 0px 5px 0px 10px;
2198 }
2198 }
2199
2199
2200 #journal .journal_action_container {
2200 #journal .journal_action_container {
2201 padding-left: 38px;
2201 padding-left: 38px;
2202 }
2202 }
2203
2203
2204 #journal .journal_user {
2204 #journal .journal_user {
2205 color: #747474;
2205 color: #747474;
2206 font-size: 14px;
2206 font-size: 14px;
2207 font-weight: bold;
2207 font-weight: bold;
2208 height: 30px;
2208 height: 30px;
2209 }
2209 }
2210
2210
2211 #journal .journal_user.deleted {
2211 #journal .journal_user.deleted {
2212 color: #747474;
2212 color: #747474;
2213 font-size: 14px;
2213 font-size: 14px;
2214 font-weight: normal;
2214 font-weight: normal;
2215 height: 30px;
2215 height: 30px;
2216 font-style: italic;
2216 font-style: italic;
2217 }
2217 }
2218
2218
2219
2219
2220 #journal .journal_icon {
2220 #journal .journal_icon {
2221 clear: both;
2221 clear: both;
2222 float: left;
2222 float: left;
2223 padding-right: 4px;
2223 padding-right: 4px;
2224 padding-top: 3px;
2224 padding-top: 3px;
2225 }
2225 }
2226
2226
2227 #journal .journal_action {
2227 #journal .journal_action {
2228 padding-top: 4px;
2228 padding-top: 4px;
2229 min-height: 2px;
2229 min-height: 2px;
2230 float: left
2230 float: left
2231 }
2231 }
2232
2232
2233 #journal .journal_action_params {
2233 #journal .journal_action_params {
2234 clear: left;
2234 clear: left;
2235 padding-left: 22px;
2235 padding-left: 22px;
2236 }
2236 }
2237
2237
2238 #journal .journal_repo {
2238 #journal .journal_repo {
2239 float: left;
2239 float: left;
2240 margin-left: 6px;
2240 margin-left: 6px;
2241 padding-top: 3px;
2241 padding-top: 3px;
2242 }
2242 }
2243
2243
2244 #journal .date {
2244 #journal .date {
2245 clear: both;
2245 clear: both;
2246 color: #777777;
2246 color: #777777;
2247 font-size: 11px;
2247 font-size: 11px;
2248 padding-left: 22px;
2248 padding-left: 22px;
2249 }
2249 }
2250
2250
2251 #journal .journal_repo .journal_repo_name {
2251 #journal .journal_repo .journal_repo_name {
2252 font-weight: bold;
2252 font-weight: bold;
2253 font-size: 1.1em;
2253 font-size: 1.1em;
2254 }
2254 }
2255
2255
2256 #journal .compare_view {
2256 #journal .compare_view {
2257 padding: 5px 0px 5px 0px;
2257 padding: 5px 0px 5px 0px;
2258 width: 95px;
2258 width: 95px;
2259 }
2259 }
2260
2260
2261 .journal_highlight {
2261 .journal_highlight {
2262 font-weight: bold;
2262 font-weight: bold;
2263 padding: 0 2px;
2263 padding: 0 2px;
2264 vertical-align: bottom;
2264 vertical-align: bottom;
2265 }
2265 }
2266
2266
2267 .trending_language_tbl, .trending_language_tbl td {
2267 .trending_language_tbl, .trending_language_tbl td {
2268 border: 0 !important;
2268 border: 0 !important;
2269 margin: 0 !important;
2269 margin: 0 !important;
2270 padding: 0 !important;
2270 padding: 0 !important;
2271 }
2271 }
2272
2272
2273 .trending_language_tbl, .trending_language_tbl tr {
2273 .trending_language_tbl, .trending_language_tbl tr {
2274 border-spacing: 1px;
2274 border-spacing: 1px;
2275 }
2275 }
2276
2276
2277 .trending_language {
2277 .trending_language {
2278 background-color: #003367;
2278 background-color: #003367;
2279 color: #FFF;
2279 color: #FFF;
2280 display: block;
2280 display: block;
2281 min-width: 20px;
2281 min-width: 20px;
2282 text-decoration: none;
2282 text-decoration: none;
2283 height: 12px;
2283 height: 12px;
2284 margin-bottom: 0px;
2284 margin-bottom: 0px;
2285 margin-left: 5px;
2285 margin-left: 5px;
2286 white-space: pre;
2286 white-space: pre;
2287 padding: 3px;
2287 padding: 3px;
2288 }
2288 }
2289
2289
2290 h3.files_location {
2290 h3.files_location {
2291 font-size: 1.8em;
2291 font-size: 1.8em;
2292 font-weight: 700;
2292 font-weight: 700;
2293 border-bottom: none !important;
2293 border-bottom: none !important;
2294 margin: 10px 0 !important;
2294 margin: 10px 0 !important;
2295 }
2295 }
2296
2296
2297 #files_data dl dt {
2297 #files_data dl dt {
2298 float: left;
2298 float: left;
2299 width: 60px;
2299 width: 60px;
2300 margin: 0 !important;
2300 margin: 0 !important;
2301 padding: 5px;
2301 padding: 5px;
2302 }
2302 }
2303
2303
2304 #files_data dl dd {
2304 #files_data dl dd {
2305 margin: 0 !important;
2305 margin: 0 !important;
2306 padding: 5px !important;
2306 padding: 5px !important;
2307 }
2307 }
2308
2308
2309 .file_history {
2309 .file_history {
2310 padding-top: 10px;
2310 padding-top: 10px;
2311 font-size: 16px;
2311 font-size: 16px;
2312 }
2312 }
2313 .file_author {
2313 .file_author {
2314 float: left;
2314 float: left;
2315 }
2315 }
2316
2316
2317 .file_author .item {
2317 .file_author .item {
2318 float: left;
2318 float: left;
2319 padding: 5px;
2319 padding: 5px;
2320 color: #888;
2320 color: #888;
2321 }
2321 }
2322
2322
2323 .tablerow0 {
2323 .tablerow0 {
2324 background-color: #F8F8F8;
2324 background-color: #F8F8F8;
2325 }
2325 }
2326
2326
2327 .tablerow1 {
2327 .tablerow1 {
2328 background-color: #FFFFFF;
2328 background-color: #FFFFFF;
2329 }
2329 }
2330
2330
2331 .changeset_id {
2331 .changeset_id {
2332 color: #666666;
2332 color: #666666;
2333 margin-right: -3px;
2333 margin-right: -3px;
2334 }
2334 }
2335
2335
2336 .changeset_hash {
2336 .changeset_hash {
2337 color: #000000;
2337 color: #000000;
2338 }
2338 }
2339
2339
2340 #changeset_content {
2340 #changeset_content {
2341 border-left: 1px solid #CCC;
2341 border-left: 1px solid #CCC;
2342 border-right: 1px solid #CCC;
2342 border-right: 1px solid #CCC;
2343 border-bottom: 1px solid #CCC;
2343 border-bottom: 1px solid #CCC;
2344 padding: 5px;
2344 padding: 5px;
2345 }
2345 }
2346
2346
2347 #changeset_compare_view_content {
2347 #changeset_compare_view_content {
2348 border: 1px solid #CCC;
2348 border: 1px solid #CCC;
2349 padding: 5px;
2349 padding: 5px;
2350 }
2350 }
2351
2351
2352 #changeset_content .container {
2352 #changeset_content .container {
2353 min-height: 100px;
2353 min-height: 100px;
2354 font-size: 1.2em;
2354 font-size: 1.2em;
2355 overflow: hidden;
2355 overflow: hidden;
2356 }
2356 }
2357
2357
2358 #changeset_compare_view_content .compare_view_commits {
2358 #changeset_compare_view_content .compare_view_commits {
2359 width: auto !important;
2359 width: auto !important;
2360 }
2360 }
2361
2361
2362 #changeset_compare_view_content .compare_view_commits td {
2362 #changeset_compare_view_content .compare_view_commits td {
2363 padding: 0px 0px 0px 12px !important;
2363 padding: 0px 0px 0px 12px !important;
2364 }
2364 }
2365
2365
2366 #changeset_content .container .right {
2366 #changeset_content .container .right {
2367 float: right;
2367 float: right;
2368 width: 20%;
2368 width: 20%;
2369 text-align: right;
2369 text-align: right;
2370 }
2370 }
2371
2371
2372 #changeset_content .container .message {
2372 #changeset_content .container .message {
2373 white-space: pre-wrap;
2373 white-space: pre-wrap;
2374 }
2374 }
2375 #changeset_content .container .message a:hover {
2375 #changeset_content .container .message a:hover {
2376 text-decoration: none;
2376 text-decoration: none;
2377 }
2377 }
2378 .cs_files .cur_cs {
2378 .cs_files .cur_cs {
2379 margin: 10px 2px;
2379 margin: 10px 2px;
2380 font-weight: bold;
2380 font-weight: bold;
2381 }
2381 }
2382
2382
2383 .cs_files .node {
2383 .cs_files .node {
2384 float: left;
2384 float: left;
2385 }
2385 }
2386
2386
2387 .cs_files .changes {
2387 .cs_files .changes {
2388 float: right;
2388 float: right;
2389 color: #003367;
2389 color: #003367;
2390 }
2390 }
2391
2391
2392 .cs_files .changes .added {
2392 .cs_files .changes .added {
2393 background-color: #BBFFBB;
2393 background-color: #BBFFBB;
2394 float: left;
2394 float: left;
2395 text-align: center;
2395 text-align: center;
2396 font-size: 9px;
2396 font-size: 9px;
2397 padding: 2px 0px 2px 0px;
2397 padding: 2px 0px 2px 0px;
2398 }
2398 }
2399
2399
2400 .cs_files .changes .deleted {
2400 .cs_files .changes .deleted {
2401 background-color: #FF8888;
2401 background-color: #FF8888;
2402 float: left;
2402 float: left;
2403 text-align: center;
2403 text-align: center;
2404 font-size: 9px;
2404 font-size: 9px;
2405 padding: 2px 0px 2px 0px;
2405 padding: 2px 0px 2px 0px;
2406 }
2406 }
2407 /*new binary*/
2407 /*new binary*/
2408 .cs_files .changes .bin1 {
2408 .cs_files .changes .bin1 {
2409 background-color: #BBFFBB;
2409 background-color: #BBFFBB;
2410 float: left;
2410 float: left;
2411 text-align: center;
2411 text-align: center;
2412 font-size: 9px;
2412 font-size: 9px;
2413 padding: 2px 0px 2px 0px;
2413 padding: 2px 0px 2px 0px;
2414 }
2414 }
2415
2415
2416 /*deleted binary*/
2416 /*deleted binary*/
2417 .cs_files .changes .bin2 {
2417 .cs_files .changes .bin2 {
2418 background-color: #FF8888;
2418 background-color: #FF8888;
2419 float: left;
2419 float: left;
2420 text-align: center;
2420 text-align: center;
2421 font-size: 9px;
2421 font-size: 9px;
2422 padding: 2px 0px 2px 0px;
2422 padding: 2px 0px 2px 0px;
2423 }
2423 }
2424
2424
2425 /*mod binary*/
2425 /*mod binary*/
2426 .cs_files .changes .bin3 {
2426 .cs_files .changes .bin3 {
2427 background-color: #DDDDDD;
2427 background-color: #DDDDDD;
2428 float: left;
2428 float: left;
2429 text-align: center;
2429 text-align: center;
2430 font-size: 9px;
2430 font-size: 9px;
2431 padding: 2px 0px 2px 0px;
2431 padding: 2px 0px 2px 0px;
2432 }
2432 }
2433
2433
2434 /*rename file*/
2434 /*rename file*/
2435 .cs_files .changes .bin4 {
2435 .cs_files .changes .bin4 {
2436 background-color: #6D99FF;
2436 background-color: #6D99FF;
2437 float: left;
2437 float: left;
2438 text-align: center;
2438 text-align: center;
2439 font-size: 9px;
2439 font-size: 9px;
2440 padding: 2px 0px 2px 0px;
2440 padding: 2px 0px 2px 0px;
2441 }
2441 }
2442
2442
2443
2443
2444 .cs_files .cs_added, .cs_files .cs_A {
2444 .cs_files .cs_added, .cs_files .cs_A {
2445 background: url("../images/icons/page_white_add.png") no-repeat scroll
2445 background: url("../images/icons/page_white_add.png") no-repeat scroll
2446 3px;
2446 3px;
2447 height: 16px;
2447 height: 16px;
2448 padding-left: 20px;
2448 padding-left: 20px;
2449 margin-top: 7px;
2449 margin-top: 7px;
2450 text-align: left;
2450 text-align: left;
2451 }
2451 }
2452
2452
2453 .cs_files .cs_changed, .cs_files .cs_M {
2453 .cs_files .cs_changed, .cs_files .cs_M {
2454 background: url("../images/icons/page_white_edit.png") no-repeat scroll
2454 background: url("../images/icons/page_white_edit.png") no-repeat scroll
2455 3px;
2455 3px;
2456 height: 16px;
2456 height: 16px;
2457 padding-left: 20px;
2457 padding-left: 20px;
2458 margin-top: 7px;
2458 margin-top: 7px;
2459 text-align: left;
2459 text-align: left;
2460 }
2460 }
2461
2461
2462 .cs_files .cs_removed, .cs_files .cs_D {
2462 .cs_files .cs_removed, .cs_files .cs_D {
2463 background: url("../images/icons/page_white_delete.png") no-repeat
2463 background: url("../images/icons/page_white_delete.png") no-repeat
2464 scroll 3px;
2464 scroll 3px;
2465 height: 16px;
2465 height: 16px;
2466 padding-left: 20px;
2466 padding-left: 20px;
2467 margin-top: 7px;
2467 margin-top: 7px;
2468 text-align: left;
2468 text-align: left;
2469 }
2469 }
2470
2470
2471 .table {
2471 .table {
2472 position: relative;
2472 position: relative;
2473 }
2473 }
2474
2474
2475 #graph {
2475 #graph {
2476 position: relative;
2476 position: relative;
2477 overflow: hidden;
2477 overflow: hidden;
2478 }
2478 }
2479
2479
2480 #graph_nodes {
2480 #graph_nodes {
2481 position: absolute;
2481 position: absolute;
2482 }
2482 }
2483
2483
2484 #graph_content,
2484 #graph_content,
2485 #graph .info_box,
2485 #graph .info_box,
2486 #graph .container_header {
2486 #graph .container_header {
2487 margin-left: 100px;
2487 margin-left: 100px;
2488 }
2488 }
2489
2489
2490 #graph_content {
2490 #graph_content {
2491 position: relative;
2491 position: relative;
2492 }
2492 }
2493
2493
2494 #graph .container_header {
2494 #graph .container_header {
2495 padding: 10px;
2495 padding: 10px;
2496 height: 25px;
2496 height: 25px;
2497 }
2497 }
2498
2498
2499 #graph_content #rev_range_container {
2499 #graph_content #rev_range_container {
2500 float: left;
2500 float: left;
2501 margin: 0px 0px 0px 3px;
2501 margin: 0px 0px 0px 3px;
2502 }
2502 }
2503
2503
2504 #graph_content #rev_range_clear {
2504 #graph_content #rev_range_clear {
2505 float: left;
2505 float: left;
2506 margin: 0px 0px 0px 3px;
2506 margin: 0px 0px 0px 3px;
2507 }
2507 }
2508
2508
2509 #graph_content #changesets {
2509 #graph_content #changesets {
2510 table-layout: fixed;
2510 table-layout: fixed;
2511 border-collapse: collapse;
2511 border-collapse: collapse;
2512 border-left: none;
2512 border-left: none;
2513 border-right: none;
2513 border-right: none;
2514 border-color: #cdcdcd;
2514 border-color: #cdcdcd;
2515 }
2515 }
2516
2516
2517 #graph_content #changesets td {
2517 #graph_content #changesets td {
2518 overflow: hidden;
2518 overflow: hidden;
2519 text-overflow: ellipsis;
2519 text-overflow: ellipsis;
2520 white-space: nowrap;
2520 white-space: nowrap;
2521 height: 31px;
2521 height: 31px;
2522 border-color: #cdcdcd;
2522 border-color: #cdcdcd;
2523 text-align: left;
2523 text-align: left;
2524 }
2524 }
2525
2525
2526 #graph_content .container .checkbox {
2526 #graph_content .container .checkbox {
2527 width: 12px;
2527 width: 12px;
2528 font-size: 0.85em;
2528 font-size: 0.85em;
2529 }
2529 }
2530
2530
2531 #graph_content .container .status {
2531 #graph_content .container .status {
2532 width: 14px;
2532 width: 14px;
2533 font-size: 0.85em;
2533 font-size: 0.85em;
2534 }
2534 }
2535
2535
2536 #graph_content .container .author {
2536 #graph_content .container .author {
2537 width: 105px;
2537 width: 105px;
2538 }
2538 }
2539
2539
2540 #graph_content .container .hash {
2540 #graph_content .container .hash {
2541 width: 100px;
2541 width: 100px;
2542 font-size: 0.85em;
2542 font-size: 0.85em;
2543 }
2543 }
2544
2544
2545 #graph_content #changesets .container .date {
2545 #graph_content #changesets .container .date {
2546 width: 76px;
2546 width: 76px;
2547 color: #666;
2547 color: #666;
2548 font-size: 10px;
2548 font-size: 10px;
2549 }
2549 }
2550
2550
2551 #graph_content #changesets .container .right {
2551 #graph_content #changesets .container .right {
2552 width: 120px;
2552 width: 120px;
2553 padding-right: 0px;
2553 padding-right: 0px;
2554 overflow: visible;
2554 overflow: visible;
2555 position: relative;
2555 position: relative;
2556 }
2556 }
2557
2557
2558 #graph_content .container .mid {
2558 #graph_content .container .mid {
2559 padding: 0;
2559 padding: 0;
2560 }
2560 }
2561
2561
2562 #graph_content .log-container {
2562 #graph_content .log-container {
2563 position: relative;
2563 position: relative;
2564 }
2564 }
2565
2565
2566 #graph_content .container .changeset_range {
2566 #graph_content .container .changeset_range {
2567 float: left;
2567 float: left;
2568 margin: 6px 3px;
2568 margin: 6px 3px;
2569 }
2569 }
2570
2570
2571 #graph_content .container .author img {
2571 #graph_content .container .author img {
2572 vertical-align: middle;
2572 vertical-align: middle;
2573 }
2573 }
2574
2574
2575 #graph_content .container .author .user {
2575 #graph_content .container .author .user {
2576 color: #444444;
2576 color: #444444;
2577 }
2577 }
2578
2578
2579 #graph_content .container .mid .message {
2579 #graph_content .container .mid .message {
2580 white-space: pre-wrap;
2580 white-space: pre-wrap;
2581 padding: 0;
2581 padding: 0;
2582 overflow: hidden;
2582 overflow: hidden;
2583 height: 1.1em;
2583 height: 1.1em;
2584 }
2584 }
2585
2585
2586 #graph_content .container .extra-container {
2586 #graph_content .container .extra-container {
2587 display: block;
2587 display: block;
2588 position: absolute;
2588 position: absolute;
2589 top: -15px;
2589 top: -15px;
2590 right: 0;
2590 right: 0;
2591 padding-left: 5px;
2591 padding-left: 5px;
2592 background: #FFFFFF;
2592 background: #FFFFFF;
2593 height: 41px;
2593 height: 41px;
2594 }
2594 }
2595
2595
2596 #graph_content .comments-container,
2596 #graph_content .comments-container,
2597 #shortlog_data .comments-container,
2597 #shortlog_data .comments-container,
2598 #graph_content .logtags {
2598 #graph_content .logtags {
2599 display: block;
2599 display: block;
2600 float: left;
2600 float: left;
2601 overflow: hidden;
2601 overflow: hidden;
2602 padding: 0;
2602 padding: 0;
2603 margin: 0;
2603 margin: 0;
2604 }
2604 }
2605
2605
2606 #graph_content .comments-container {
2606 #graph_content .comments-container {
2607 margin: 0.8em 0;
2607 margin: 0.8em 0;
2608 margin-right: 0.5em;
2608 margin-right: 0.5em;
2609 }
2609 }
2610
2610
2611 #graph_content .tagcontainer {
2611 #graph_content .tagcontainer {
2612 width: 80px;
2612 width: 80px;
2613 position: relative;
2613 position: relative;
2614 float: right;
2614 float: right;
2615 height: 100%;
2615 height: 100%;
2616 top: 7px;
2616 top: 7px;
2617 margin-left: 0.5em;
2617 margin-left: 0.5em;
2618 }
2618 }
2619
2619
2620 #graph_content .logtags {
2620 #graph_content .logtags {
2621 min-width: 80px;
2621 min-width: 80px;
2622 height: 1.1em;
2622 height: 1.1em;
2623 position: absolute;
2623 position: absolute;
2624 left: 0px;
2624 left: 0px;
2625 width: auto;
2625 width: auto;
2626 top: 0px;
2626 top: 0px;
2627 }
2627 }
2628
2628
2629 #graph_content .logtags.tags {
2629 #graph_content .logtags.tags {
2630 top: 14px;
2630 top: 14px;
2631 }
2631 }
2632
2632
2633 #graph_content .logtags:hover {
2633 #graph_content .logtags:hover {
2634 overflow: visible;
2634 overflow: visible;
2635 position: absolute;
2635 position: absolute;
2636 width: auto;
2636 width: auto;
2637 right: 0;
2637 right: 0;
2638 left: initial;
2638 left: initial;
2639 }
2639 }
2640
2640
2641 #graph_content .logtags .booktag,
2641 #graph_content .logtags .booktag,
2642 #graph_content .logtags .tagtag {
2642 #graph_content .logtags .tagtag {
2643 float: left;
2643 float: left;
2644 line-height: 1em;
2644 line-height: 1em;
2645 margin-bottom: 1px;
2645 margin-bottom: 1px;
2646 margin-right: 1px;
2646 margin-right: 1px;
2647 padding: 1px 3px;
2647 padding: 1px 3px;
2648 font-size: 10px;
2648 font-size: 10px;
2649 }
2649 }
2650
2650
2651 #graph_content .container .mid .message a:hover {
2651 #graph_content .container .mid .message a:hover {
2652 text-decoration: none;
2652 text-decoration: none;
2653 }
2653 }
2654
2654
2655 .revision-link {
2655 .revision-link {
2656 color: #3F6F9F;
2656 color: #3F6F9F;
2657 font-weight: bold !important;
2657 font-weight: bold !important;
2658 }
2658 }
2659
2659
2660 .issue-tracker-link {
2660 .issue-tracker-link {
2661 color: #3F6F9F;
2661 color: #3F6F9F;
2662 font-weight: bold !important;
2662 font-weight: bold !important;
2663 }
2663 }
2664
2664
2665 .changeset-status-container {
2665 .changeset-status-container {
2666 padding-right: 5px;
2666 padding-right: 5px;
2667 margin-top: 1px;
2667 margin-top: 1px;
2668 float: right;
2668 float: right;
2669 height: 14px;
2669 height: 14px;
2670 }
2670 }
2671 .code-header .changeset-status-container {
2671 .code-header .changeset-status-container {
2672 float: left;
2672 float: left;
2673 padding: 2px 0px 0px 2px;
2673 padding: 2px 0px 0px 2px;
2674 }
2674 }
2675 .changeset-status-container .changeset-status-lbl {
2675 .changeset-status-container .changeset-status-lbl {
2676 color: rgb(136, 136, 136);
2676 color: rgb(136, 136, 136);
2677 float: left;
2677 float: left;
2678 padding: 3px 4px 0px 0px
2678 padding: 3px 4px 0px 0px
2679 }
2679 }
2680 .code-header .changeset-status-container .changeset-status-lbl {
2680 .code-header .changeset-status-container .changeset-status-lbl {
2681 float: left;
2681 float: left;
2682 padding: 0px 4px 0px 0px;
2682 padding: 0px 4px 0px 0px;
2683 }
2683 }
2684 .changeset-status-container .changeset-status-ico {
2684 .changeset-status-container .changeset-status-ico {
2685 float: left;
2685 float: left;
2686 }
2686 }
2687 .code-header .changeset-status-container .changeset-status-ico, .container .changeset-status-ico {
2687 .code-header .changeset-status-container .changeset-status-ico, .container .changeset-status-ico {
2688 float: left;
2688 float: left;
2689 }
2689 }
2690
2690
2691 #graph_content .comments-cnt {
2691 #graph_content .comments-cnt {
2692 color: rgb(136, 136, 136);
2692 color: rgb(136, 136, 136);
2693 padding: 5px 0;
2693 padding: 5px 0;
2694 }
2694 }
2695
2695
2696 #shortlog_data .comments-cnt {
2696 #shortlog_data .comments-cnt {
2697 color: rgb(136, 136, 136);
2697 color: rgb(136, 136, 136);
2698 padding: 3px 0;
2698 padding: 3px 0;
2699 }
2699 }
2700
2700
2701 #graph_content .comments-cnt a,
2701 #graph_content .comments-cnt a,
2702 #shortlog_data .comments-cnt a {
2702 #shortlog_data .comments-cnt a {
2703 background-image: url('../images/icons/comments.png');
2703 background-image: url('../images/icons/comments.png');
2704 background-repeat: no-repeat;
2704 background-repeat: no-repeat;
2705 background-position: 100% 50%;
2705 background-position: 100% 50%;
2706 padding: 5px 0;
2706 padding: 5px 0;
2707 padding-right: 20px;
2707 padding-right: 20px;
2708 }
2708 }
2709
2709
2710 .right .changes {
2710 .right .changes {
2711 clear: both;
2711 clear: both;
2712 }
2712 }
2713
2713
2714 .right .changes .changed_total {
2714 .right .changes .changed_total {
2715 display: block;
2715 display: block;
2716 float: right;
2716 float: right;
2717 text-align: center;
2717 text-align: center;
2718 min-width: 45px;
2718 min-width: 45px;
2719 cursor: pointer;
2719 cursor: pointer;
2720 color: #444444;
2720 color: #444444;
2721 background: #FEA;
2721 background: #FEA;
2722 -webkit-border-radius: 0px 0px 0px 6px;
2722 -webkit-border-radius: 0px 0px 0px 6px;
2723 border-radius: 0px 0px 0px 6px;
2723 border-radius: 0px 0px 0px 6px;
2724 padding: 1px;
2724 padding: 1px;
2725 }
2725 }
2726
2726
2727 .right .changes .added, .changed, .removed {
2727 .right .changes .added, .changed, .removed {
2728 display: block;
2728 display: block;
2729 padding: 1px;
2729 padding: 1px;
2730 color: #444444;
2730 color: #444444;
2731 float: right;
2731 float: right;
2732 text-align: center;
2732 text-align: center;
2733 min-width: 15px;
2733 min-width: 15px;
2734 }
2734 }
2735
2735
2736 .right .changes .added {
2736 .right .changes .added {
2737 background: #CFC;
2737 background: #CFC;
2738 }
2738 }
2739
2739
2740 .right .changes .changed {
2740 .right .changes .changed {
2741 background: #FEA;
2741 background: #FEA;
2742 }
2742 }
2743
2743
2744 .right .changes .removed {
2744 .right .changes .removed {
2745 background: #FAA;
2745 background: #FAA;
2746 }
2746 }
2747
2747
2748 .right .merge {
2748 .right .merge {
2749 padding: 1px 3px 1px 3px;
2749 padding: 1px 3px 1px 3px;
2750 background-color: #fca062;
2750 background-color: #fca062;
2751 font-size: 10px;
2751 font-size: 10px;
2752 color: #ffffff;
2752 color: #ffffff;
2753 text-transform: uppercase;
2753 text-transform: uppercase;
2754 white-space: nowrap;
2754 white-space: nowrap;
2755 -webkit-border-radius: 3px;
2755 -webkit-border-radius: 3px;
2756 border-radius: 3px;
2756 border-radius: 3px;
2757 margin-right: 2px;
2757 margin-right: 2px;
2758 }
2758 }
2759
2759
2760 .right .parent {
2760 .right .parent {
2761 color: #666666;
2761 color: #666666;
2762 clear: both;
2762 clear: both;
2763 }
2763 }
2764 .right .logtags {
2764 .right .logtags {
2765 line-height: 2.2em;
2765 line-height: 2.2em;
2766 }
2766 }
2767 .branchtag, .logtags .tagtag, .logtags .booktag {
2767 .branchtag, .logtags .tagtag, .logtags .booktag {
2768 margin: 0px 2px;
2768 margin: 0px 2px;
2769 }
2769 }
2770
2770
2771 .branchtag,
2771 .branchtag,
2772 .tagtag,
2772 .tagtag,
2773 .booktag,
2773 .booktag,
2774 .spantag {
2774 .spantag {
2775 padding: 1px 3px 1px 3px;
2775 padding: 1px 3px 1px 3px;
2776 font-size: 10px;
2776 font-size: 10px;
2777 color: #336699;
2777 color: #336699;
2778 white-space: nowrap;
2778 white-space: nowrap;
2779 -webkit-border-radius: 4px;
2779 -webkit-border-radius: 4px;
2780 border-radius: 4px;
2780 border-radius: 4px;
2781 border: 1px solid #d9e8f8;
2781 border: 1px solid #d9e8f8;
2782 line-height: 1.5em;
2782 line-height: 1.5em;
2783 }
2783 }
2784
2784
2785 #graph_content .branchtag,
2785 #graph_content .branchtag,
2786 #graph_content .tagtag,
2786 #graph_content .tagtag,
2787 #graph_content .booktag {
2787 #graph_content .booktag {
2788 margin: 1.1em 0;
2788 margin: 1.1em 0;
2789 margin-right: 0.5em;
2789 margin-right: 0.5em;
2790 }
2790 }
2791
2791
2792 .branchtag,
2792 .branchtag,
2793 .tagtag,
2793 .tagtag,
2794 .booktag {
2794 .booktag {
2795 float: left;
2795 float: left;
2796 }
2796 }
2797
2797
2798 .right .logtags .branchtag,
2798 .right .logtags .branchtag,
2799 .right .logtags .tagtag,
2799 .right .logtags .tagtag,
2800 .right .logtags .booktag,
2800 .right .logtags .booktag,
2801 .right .merge {
2801 .right .merge {
2802 float: right;
2802 float: right;
2803 line-height: 1em;
2803 line-height: 1em;
2804 margin: 1px 1px !important;
2804 margin: 1px 1px !important;
2805 display: block;
2805 display: block;
2806 }
2806 }
2807
2807
2808 .booktag {
2808 .booktag {
2809 border-color: #46A546;
2809 border-color: #46A546;
2810 color: #46A546;
2810 color: #46A546;
2811 }
2811 }
2812
2812
2813 .tagtag {
2813 .tagtag {
2814 border-color: #62cffc;
2814 border-color: #62cffc;
2815 color: #62cffc;
2815 color: #62cffc;
2816 }
2816 }
2817
2817
2818 .logtags .branchtag a:hover,
2818 .logtags .branchtag a:hover,
2819 .logtags .branchtag a,
2819 .logtags .branchtag a,
2820 .branchtag a,
2820 .branchtag a,
2821 .branchtag a:hover {
2821 .branchtag a:hover {
2822 text-decoration: none;
2822 text-decoration: none;
2823 color: inherit;
2823 color: inherit;
2824 }
2824 }
2825 .logtags .tagtag {
2825 .logtags .tagtag {
2826 padding: 1px 3px 1px 3px;
2826 padding: 1px 3px 1px 3px;
2827 background-color: #62cffc;
2827 background-color: #62cffc;
2828 font-size: 10px;
2828 font-size: 10px;
2829 color: #ffffff;
2829 color: #ffffff;
2830 white-space: nowrap;
2830 white-space: nowrap;
2831 -webkit-border-radius: 3px;
2831 -webkit-border-radius: 3px;
2832 border-radius: 3px;
2832 border-radius: 3px;
2833 }
2833 }
2834
2834
2835 .tagtag a,
2835 .tagtag a,
2836 .tagtag a:hover,
2836 .tagtag a:hover,
2837 .logtags .tagtag a,
2837 .logtags .tagtag a,
2838 .logtags .tagtag a:hover {
2838 .logtags .tagtag a:hover {
2839 text-decoration: none;
2839 text-decoration: none;
2840 color: inherit;
2840 color: inherit;
2841 }
2841 }
2842 .logbooks .booktag, .logbooks .booktag, .logtags .booktag, .logtags .booktag {
2842 .logbooks .booktag, .logbooks .booktag, .logtags .booktag, .logtags .booktag {
2843 padding: 1px 3px 1px 3px;
2843 padding: 1px 3px 1px 3px;
2844 background-color: #46A546;
2844 background-color: #46A546;
2845 font-size: 10px;
2845 font-size: 10px;
2846 color: #ffffff;
2846 color: #ffffff;
2847 white-space: nowrap;
2847 white-space: nowrap;
2848 -webkit-border-radius: 3px;
2848 -webkit-border-radius: 3px;
2849 border-radius: 3px;
2849 border-radius: 3px;
2850 }
2850 }
2851 .logbooks .booktag, .logbooks .booktag a, .right .logtags .booktag, .logtags .booktag a {
2851 .logbooks .booktag, .logbooks .booktag a, .right .logtags .booktag, .logtags .booktag a {
2852 color: #ffffff;
2852 color: #ffffff;
2853 }
2853 }
2854
2854
2855 .logbooks .booktag, .logbooks .booktag a:hover,
2855 .logbooks .booktag, .logbooks .booktag a:hover,
2856 .logtags .booktag, .logtags .booktag a:hover,
2856 .logtags .booktag, .logtags .booktag a:hover,
2857 .booktag a,
2857 .booktag a,
2858 .booktag a:hover {
2858 .booktag a:hover {
2859 text-decoration: none;
2859 text-decoration: none;
2860 color: inherit;
2860 color: inherit;
2861 }
2861 }
2862 div.browserblock {
2862 div.browserblock {
2863 overflow: hidden;
2863 overflow: hidden;
2864 border: 1px solid #ccc;
2864 border: 1px solid #ccc;
2865 background: #f8f8f8;
2865 background: #f8f8f8;
2866 font-size: 100%;
2866 font-size: 100%;
2867 line-height: 125%;
2867 line-height: 125%;
2868 padding: 0;
2868 padding: 0;
2869 -webkit-border-radius: 6px 6px 0px 0px;
2869 -webkit-border-radius: 6px 6px 0px 0px;
2870 border-radius: 6px 6px 0px 0px;
2870 border-radius: 6px 6px 0px 0px;
2871 }
2871 }
2872
2872
2873 div.browserblock .browser-header {
2873 div.browserblock .browser-header {
2874 background: #FFF;
2874 background: #FFF;
2875 padding: 10px 0px 15px 0px;
2875 padding: 10px 0px 15px 0px;
2876 width: 100%;
2876 width: 100%;
2877 }
2877 }
2878
2878
2879 div.browserblock .browser-nav {
2879 div.browserblock .browser-nav {
2880 float: left
2880 float: left
2881 }
2881 }
2882
2882
2883 div.browserblock .browser-branch {
2883 div.browserblock .browser-branch {
2884 float: left;
2884 float: left;
2885 }
2885 }
2886
2886
2887 div.browserblock .browser-branch label {
2887 div.browserblock .browser-branch label {
2888 color: #4A4A4A;
2888 color: #4A4A4A;
2889 vertical-align: text-top;
2889 vertical-align: text-top;
2890 }
2890 }
2891
2891
2892 div.browserblock .browser-header span {
2892 div.browserblock .browser-header span {
2893 margin-left: 5px;
2893 margin-left: 5px;
2894 font-weight: 700;
2894 font-weight: 700;
2895 }
2895 }
2896
2896
2897 div.browserblock .browser-search {
2897 div.browserblock .browser-search {
2898 clear: both;
2898 clear: both;
2899 padding: 8px 8px 0px 5px;
2899 padding: 8px 8px 0px 5px;
2900 height: 20px;
2900 height: 20px;
2901 }
2901 }
2902
2902
2903 div.browserblock #node_filter_box {
2903 div.browserblock #node_filter_box {
2904 }
2904 }
2905
2905
2906 div.browserblock .search_activate {
2906 div.browserblock .search_activate {
2907 float: left
2907 float: left
2908 }
2908 }
2909
2909
2910 div.browserblock .add_node {
2910 div.browserblock .add_node {
2911 float: left;
2911 float: left;
2912 padding-left: 5px;
2912 padding-left: 5px;
2913 }
2913 }
2914
2914
2915 div.browserblock .search_activate a:hover, div.browserblock .add_node a:hover {
2915 div.browserblock .search_activate a:hover, div.browserblock .add_node a:hover {
2916 text-decoration: none !important;
2916 text-decoration: none !important;
2917 }
2917 }
2918
2918
2919 div.browserblock .browser-body {
2919 div.browserblock .browser-body {
2920 background: #EEE;
2920 background: #EEE;
2921 border-top: 1px solid #CCC;
2921 border-top: 1px solid #CCC;
2922 }
2922 }
2923
2923
2924 table.code-browser {
2924 table.code-browser {
2925 border-collapse: collapse;
2925 border-collapse: collapse;
2926 width: 100%;
2926 width: 100%;
2927 }
2927 }
2928
2928
2929 table.code-browser tr {
2929 table.code-browser tr {
2930 margin: 3px;
2930 margin: 3px;
2931 }
2931 }
2932
2932
2933 table.code-browser thead th {
2933 table.code-browser thead th {
2934 background-color: #EEE;
2934 background-color: #EEE;
2935 height: 20px;
2935 height: 20px;
2936 font-size: 1.1em;
2936 font-size: 1.1em;
2937 font-weight: 700;
2937 font-weight: 700;
2938 text-align: left;
2938 text-align: left;
2939 padding-left: 10px;
2939 padding-left: 10px;
2940 }
2940 }
2941
2941
2942 table.code-browser tbody td {
2942 table.code-browser tbody td {
2943 padding-left: 10px;
2943 padding-left: 10px;
2944 height: 20px;
2944 height: 20px;
2945 }
2945 }
2946
2946
2947 table.code-browser .browser-file {
2947 table.code-browser .browser-file {
2948 background: url("../images/icons/document_16.png") no-repeat scroll 3px;
2948 background: url("../images/icons/document_16.png") no-repeat scroll 3px;
2949 height: 16px;
2949 height: 16px;
2950 padding-left: 20px;
2950 padding-left: 20px;
2951 text-align: left;
2951 text-align: left;
2952 }
2952 }
2953 .diffblock .changeset_header {
2953 .diffblock .changeset_header {
2954 height: 16px;
2954 height: 16px;
2955 }
2955 }
2956 .diffblock .changeset_file {
2956 .diffblock .changeset_file {
2957 background: url("../images/icons/file.png") no-repeat scroll 3px;
2957 background: url("../images/icons/file.png") no-repeat scroll 3px;
2958 text-align: left;
2958 text-align: left;
2959 float: left;
2959 float: left;
2960 padding: 2px 0px 2px 22px;
2960 padding: 2px 0px 2px 22px;
2961 }
2961 }
2962 .diffblock .diff-menu-wrapper {
2962 .diffblock .diff-menu-wrapper {
2963 float: left;
2963 float: left;
2964 }
2964 }
2965
2965
2966 .diffblock .diff-menu {
2966 .diffblock .diff-menu {
2967 position: absolute;
2967 position: absolute;
2968 background: none repeat scroll 0 0 #FFFFFF;
2968 background: none repeat scroll 0 0 #FFFFFF;
2969 border-color: #003367 #666666 #666666;
2969 border-color: #003367 #666666 #666666;
2970 border-right: 1px solid #666666;
2970 border-right: 1px solid #666666;
2971 border-style: solid solid solid;
2971 border-style: solid solid solid;
2972 border-width: 1px;
2972 border-width: 1px;
2973 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
2973 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
2974 margin-top: 5px;
2974 margin-top: 5px;
2975 margin-left: 1px;
2975 margin-left: 1px;
2976
2976
2977 }
2977 }
2978 .diffblock .diff-actions {
2978 .diffblock .diff-actions {
2979 padding: 2px 0px 0px 2px;
2979 padding: 2px 0px 0px 2px;
2980 float: left;
2980 float: left;
2981 }
2981 }
2982 .diffblock .diff-menu ul li {
2982 .diffblock .diff-menu ul li {
2983 padding: 0px 0px 0px 0px !important;
2983 padding: 0px 0px 0px 0px !important;
2984 }
2984 }
2985 .diffblock .diff-menu ul li a {
2985 .diffblock .diff-menu ul li a {
2986 display: block;
2986 display: block;
2987 padding: 3px 8px 3px 8px !important;
2987 padding: 3px 8px 3px 8px !important;
2988 }
2988 }
2989 .diffblock .diff-menu ul li a:hover {
2989 .diffblock .diff-menu ul li a:hover {
2990 text-decoration: none;
2990 text-decoration: none;
2991 background-color: #EEEEEE;
2991 background-color: #EEEEEE;
2992 }
2992 }
2993 table.code-browser .browser-dir {
2993 table.code-browser .browser-dir {
2994 background: url("../images/icons/folder_16.png") no-repeat scroll 3px;
2994 background: url("../images/icons/folder_16.png") no-repeat scroll 3px;
2995 height: 16px;
2995 height: 16px;
2996 padding-left: 20px;
2996 padding-left: 20px;
2997 text-align: left;
2997 text-align: left;
2998 }
2998 }
2999
2999
3000 table.code-browser .submodule-dir {
3000 table.code-browser .submodule-dir {
3001 background: url("../images/icons/disconnect.png") no-repeat scroll 3px;
3001 background: url("../images/icons/disconnect.png") no-repeat scroll 3px;
3002 height: 16px;
3002 height: 16px;
3003 padding-left: 20px;
3003 padding-left: 20px;
3004 text-align: left;
3004 text-align: left;
3005 }
3005 }
3006
3006
3007
3007
3008 .box .search {
3008 .box .search {
3009 clear: both;
3009 clear: both;
3010 overflow: hidden;
3010 overflow: hidden;
3011 margin: 0;
3011 margin: 0;
3012 padding: 0 20px 10px;
3012 padding: 0 20px 10px;
3013 }
3013 }
3014
3014
3015 .box .search div.search_path {
3015 .box .search div.search_path {
3016 background: none repeat scroll 0 0 #EEE;
3016 background: none repeat scroll 0 0 #EEE;
3017 border: 1px solid #CCC;
3017 border: 1px solid #CCC;
3018 color: blue;
3018 color: blue;
3019 margin-bottom: 10px;
3019 margin-bottom: 10px;
3020 padding: 10px 0;
3020 padding: 10px 0;
3021 }
3021 }
3022
3022
3023 .box .search div.search_path div.link {
3023 .box .search div.search_path div.link {
3024 font-weight: 700;
3024 font-weight: 700;
3025 margin-left: 25px;
3025 margin-left: 25px;
3026 }
3026 }
3027
3027
3028 .box .search div.search_path div.link a {
3028 .box .search div.search_path div.link a {
3029 color: #003367;
3029 color: #003367;
3030 cursor: pointer;
3030 cursor: pointer;
3031 text-decoration: none;
3031 text-decoration: none;
3032 }
3032 }
3033
3033
3034 #path_unlock {
3034 #path_unlock {
3035 color: red;
3035 color: red;
3036 font-size: 1.2em;
3036 font-size: 1.2em;
3037 padding-left: 4px;
3037 padding-left: 4px;
3038 }
3038 }
3039
3039
3040 .info_box span {
3040 .info_box span {
3041 margin-left: 3px;
3041 margin-left: 3px;
3042 margin-right: 3px;
3042 margin-right: 3px;
3043 }
3043 }
3044
3044
3045 .info_box .rev {
3045 .info_box .rev {
3046 color: #003367;
3046 color: #003367;
3047 font-size: 1.6em;
3047 font-size: 1.6em;
3048 font-weight: bold;
3048 font-weight: bold;
3049 vertical-align: sub;
3049 vertical-align: sub;
3050 }
3050 }
3051
3051
3052 .info_box input#at_rev, .info_box input#size {
3052 .info_box input#at_rev, .info_box input#size {
3053 background: #FFF;
3053 background: #FFF;
3054 border-top: 1px solid #b3b3b3;
3054 border-top: 1px solid #b3b3b3;
3055 border-left: 1px solid #b3b3b3;
3055 border-left: 1px solid #b3b3b3;
3056 border-right: 1px solid #eaeaea;
3056 border-right: 1px solid #eaeaea;
3057 border-bottom: 1px solid #eaeaea;
3057 border-bottom: 1px solid #eaeaea;
3058 color: #000;
3058 color: #000;
3059 font-size: 12px;
3059 font-size: 12px;
3060 margin: 0;
3060 margin: 0;
3061 padding: 1px 5px 1px;
3061 padding: 1px 5px 1px;
3062 }
3062 }
3063
3063
3064 .info_box input#view {
3064 .info_box input#view {
3065 text-align: center;
3065 text-align: center;
3066 padding: 4px 3px 2px 2px;
3066 padding: 4px 3px 2px 2px;
3067 }
3067 }
3068
3068
3069 .yui-overlay, .yui-panel-container {
3069 .yui-overlay, .yui-panel-container {
3070 visibility: hidden;
3070 visibility: hidden;
3071 position: absolute;
3071 position: absolute;
3072 z-index: 2;
3072 z-index: 2;
3073 }
3073 }
3074
3074
3075 #tip-box {
3075 #tip-box {
3076 position: absolute;
3076 position: absolute;
3077
3077
3078 background-color: #FFF;
3078 background-color: #FFF;
3079 border: 2px solid #003367;
3079 border: 2px solid #003367;
3080 font: 100% sans-serif;
3080 font: 100% sans-serif;
3081 width: auto;
3081 width: auto;
3082 opacity: 1;
3082 opacity: 1;
3083 padding: 8px;
3083 padding: 8px;
3084
3084
3085 white-space: pre-wrap;
3085 white-space: pre-wrap;
3086 -webkit-border-radius: 8px 8px 8px 8px;
3086 -webkit-border-radius: 8px 8px 8px 8px;
3087 -khtml-border-radius: 8px 8px 8px 8px;
3087 -khtml-border-radius: 8px 8px 8px 8px;
3088 border-radius: 8px 8px 8px 8px;
3088 border-radius: 8px 8px 8px 8px;
3089 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3089 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3090 -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3090 -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3091 }
3091 }
3092
3092
3093 .hl-tip-box {
3093 .hl-tip-box {
3094 visibility: hidden;
3094 visibility: hidden;
3095 position: absolute;
3095 position: absolute;
3096 color: #666;
3096 color: #666;
3097 background-color: #FFF;
3097 background-color: #FFF;
3098 border: 2px solid #003367;
3098 border: 2px solid #003367;
3099 font: 100% sans-serif;
3099 font: 100% sans-serif;
3100 width: auto;
3100 width: auto;
3101 opacity: 1;
3101 opacity: 1;
3102 padding: 8px;
3102 padding: 8px;
3103 white-space: pre-wrap;
3103 white-space: pre-wrap;
3104 -webkit-border-radius: 8px 8px 8px 8px;
3104 -webkit-border-radius: 8px 8px 8px 8px;
3105 -khtml-border-radius: 8px 8px 8px 8px;
3105 -khtml-border-radius: 8px 8px 8px 8px;
3106 border-radius: 8px 8px 8px 8px;
3106 border-radius: 8px 8px 8px 8px;
3107 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3107 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3108 }
3108 }
3109
3109
3110
3110
3111 .mentions-container {
3111 .mentions-container {
3112 width: 90% !important;
3112 width: 90% !important;
3113 }
3113 }
3114 .mentions-container .yui-ac-content {
3114 .mentions-container .yui-ac-content {
3115 width: 100% !important;
3115 width: 100% !important;
3116 }
3116 }
3117
3117
3118 .ac {
3118 .ac {
3119 vertical-align: top;
3119 vertical-align: top;
3120 }
3120 }
3121
3121
3122 .ac .yui-ac {
3122 .ac .yui-ac {
3123 position: inherit;
3123 position: inherit;
3124 font-size: 100%;
3124 font-size: 100%;
3125 }
3125 }
3126
3126
3127 .ac .perm_ac {
3127 .ac .perm_ac {
3128 width: 20em;
3128 width: 20em;
3129 }
3129 }
3130
3130
3131 .ac .yui-ac-input {
3131 .ac .yui-ac-input {
3132 width: 100%;
3132 width: 100%;
3133 }
3133 }
3134
3134
3135 .ac .yui-ac-container {
3135 .ac .yui-ac-container {
3136 position: absolute;
3136 position: absolute;
3137 top: 1.6em;
3137 top: 1.6em;
3138 width: auto;
3138 width: auto;
3139 }
3139 }
3140
3140
3141 .ac .yui-ac-content {
3141 .ac .yui-ac-content {
3142 position: absolute;
3142 position: absolute;
3143 border: 1px solid gray;
3143 border: 1px solid gray;
3144 background: #fff;
3144 background: #fff;
3145 z-index: 9050;
3145 z-index: 9050;
3146 }
3146 }
3147
3147
3148 .ac .yui-ac-shadow {
3148 .ac .yui-ac-shadow {
3149 position: absolute;
3149 position: absolute;
3150 width: 100%;
3150 width: 100%;
3151 background: #000;
3151 background: #000;
3152 opacity: .10;
3152 opacity: .10;
3153 filter: alpha(opacity = 10);
3153 filter: alpha(opacity = 10);
3154 z-index: 9049;
3154 z-index: 9049;
3155 margin: .3em;
3155 margin: .3em;
3156 }
3156 }
3157
3157
3158 .ac .yui-ac-content ul {
3158 .ac .yui-ac-content ul {
3159 width: 100%;
3159 width: 100%;
3160 margin: 0;
3160 margin: 0;
3161 padding: 0;
3161 padding: 0;
3162 z-index: 9050;
3162 z-index: 9050;
3163 }
3163 }
3164
3164
3165 .ac .yui-ac-content li {
3165 .ac .yui-ac-content li {
3166 cursor: default;
3166 cursor: default;
3167 white-space: nowrap;
3167 white-space: nowrap;
3168 margin: 0;
3168 margin: 0;
3169 padding: 2px 5px;
3169 padding: 2px 5px;
3170 height: 18px;
3170 height: 18px;
3171 z-index: 9050;
3171 z-index: 9050;
3172 display: block;
3172 display: block;
3173 width: auto !important;
3173 width: auto !important;
3174 }
3174 }
3175
3175
3176 .ac .yui-ac-content li .ac-container-wrap {
3176 .ac .yui-ac-content li .ac-container-wrap {
3177 width: auto;
3177 width: auto;
3178 }
3178 }
3179
3179
3180 .ac .yui-ac-content li.yui-ac-prehighlight {
3180 .ac .yui-ac-content li.yui-ac-prehighlight {
3181 background: #B3D4FF;
3181 background: #B3D4FF;
3182 z-index: 9050;
3182 z-index: 9050;
3183 }
3183 }
3184
3184
3185 .ac .yui-ac-content li.yui-ac-highlight {
3185 .ac .yui-ac-content li.yui-ac-highlight {
3186 background: #556CB5;
3186 background: #556CB5;
3187 color: #FFF;
3187 color: #FFF;
3188 z-index: 9050;
3188 z-index: 9050;
3189 }
3189 }
3190 .ac .yui-ac-bd {
3190 .ac .yui-ac-bd {
3191 z-index: 9050;
3191 z-index: 9050;
3192 }
3192 }
3193
3193
3194 .reposize {
3194 .reposize {
3195 background: url("../images/icons/server.png") no-repeat scroll 3px;
3195 background: url("../images/icons/server.png") no-repeat scroll 3px;
3196 height: 16px;
3196 height: 16px;
3197 width: 20px;
3197 width: 20px;
3198 cursor: pointer;
3198 cursor: pointer;
3199 display: block;
3199 display: block;
3200 float: right;
3200 float: right;
3201 margin-top: 2px;
3201 margin-top: 2px;
3202 }
3202 }
3203
3203
3204 #repo_size {
3204 #repo_size {
3205 display: block;
3205 display: block;
3206 margin-top: 4px;
3206 margin-top: 4px;
3207 color: #666;
3207 color: #666;
3208 float: right;
3208 float: right;
3209 }
3209 }
3210
3210
3211 .locking_locked {
3211 .locking_locked {
3212 background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px;
3212 background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px;
3213 height: 16px;
3213 height: 16px;
3214 width: 20px;
3214 width: 20px;
3215 cursor: pointer;
3215 cursor: pointer;
3216 display: block;
3216 display: block;
3217 float: right;
3217 float: right;
3218 margin-top: 2px;
3218 margin-top: 2px;
3219 }
3219 }
3220
3220
3221 .locking_unlocked {
3221 .locking_unlocked {
3222 background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px;
3222 background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px;
3223 height: 16px;
3223 height: 16px;
3224 width: 20px;
3224 width: 20px;
3225 cursor: pointer;
3225 cursor: pointer;
3226 display: block;
3226 display: block;
3227 float: right;
3227 float: right;
3228 margin-top: 2px;
3228 margin-top: 2px;
3229 }
3229 }
3230
3230
3231 .currently_following {
3231 .currently_following {
3232 padding-left: 10px;
3232 padding-left: 10px;
3233 padding-bottom: 5px;
3233 padding-bottom: 5px;
3234 }
3234 }
3235
3235
3236 .add_icon {
3236 .add_icon {
3237 background: url("../images/icons/add.png") no-repeat scroll 3px;
3237 background: url("../images/icons/add.png") no-repeat scroll 3px;
3238 padding-left: 20px;
3238 padding-left: 20px;
3239 padding-top: 0px;
3239 padding-top: 0px;
3240 text-align: left;
3240 text-align: left;
3241 }
3241 }
3242
3242
3243 .accept_icon {
3243 .accept_icon {
3244 background: url("../images/icons/accept.png") no-repeat scroll 3px;
3244 background: url("../images/icons/accept.png") no-repeat scroll 3px;
3245 padding-left: 20px;
3245 padding-left: 20px;
3246 padding-top: 0px;
3246 padding-top: 0px;
3247 text-align: left;
3247 text-align: left;
3248 }
3248 }
3249
3249
3250 .edit_icon {
3250 .edit_icon {
3251 background: url("../images/icons/application_form_edit.png") no-repeat scroll 3px;
3251 background: url("../images/icons/application_form_edit.png") no-repeat scroll 3px;
3252 padding-left: 20px;
3252 padding-left: 20px;
3253 padding-top: 0px;
3253 padding-top: 0px;
3254 text-align: left;
3254 text-align: left;
3255 }
3255 }
3256
3256
3257 .delete_icon {
3257 .delete_icon {
3258 background: url("../images/icons/delete.png") no-repeat scroll 3px;
3258 background: url("../images/icons/delete.png") no-repeat scroll 3px;
3259 padding-left: 20px;
3259 padding-left: 20px;
3260 padding-top: 0px;
3260 padding-top: 0px;
3261 text-align: left;
3261 text-align: left;
3262 }
3262 }
3263
3263
3264 .refresh_icon {
3264 .refresh_icon {
3265 background: url("../images/icons/arrow_refresh.png") no-repeat scroll
3265 background: url("../images/icons/arrow_refresh.png") no-repeat scroll
3266 3px;
3266 3px;
3267 padding-left: 20px;
3267 padding-left: 20px;
3268 padding-top: 0px;
3268 padding-top: 0px;
3269 text-align: left;
3269 text-align: left;
3270 }
3270 }
3271
3271
3272 .pull_icon {
3272 .pull_icon {
3273 background: url("../images/icons/connect.png") no-repeat scroll 3px;
3273 background: url("../images/icons/connect.png") no-repeat scroll 3px;
3274 padding-left: 20px;
3274 padding-left: 20px;
3275 padding-top: 0px;
3275 padding-top: 0px;
3276 text-align: left;
3276 text-align: left;
3277 }
3277 }
3278
3278
3279 .rss_icon {
3279 .rss_icon {
3280 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3280 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3281 padding-left: 20px;
3281 padding-left: 20px;
3282 padding-top: 4px;
3282 padding-top: 4px;
3283 text-align: left;
3283 text-align: left;
3284 font-size: 8px
3284 font-size: 8px
3285 }
3285 }
3286
3286
3287 .atom_icon {
3287 .atom_icon {
3288 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3288 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3289 padding-left: 20px;
3289 padding-left: 20px;
3290 padding-top: 4px;
3290 padding-top: 4px;
3291 text-align: left;
3291 text-align: left;
3292 font-size: 8px
3292 font-size: 8px
3293 }
3293 }
3294
3294
3295 .archive_icon {
3295 .archive_icon {
3296 background: url("../images/icons/compress.png") no-repeat scroll 3px;
3296 background: url("../images/icons/compress.png") no-repeat scroll 3px;
3297 padding-left: 20px;
3297 padding-left: 20px;
3298 text-align: left;
3298 text-align: left;
3299 padding-top: 1px;
3299 padding-top: 1px;
3300 }
3300 }
3301
3301
3302 .start_following_icon {
3302 .start_following_icon {
3303 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3303 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3304 padding-left: 20px;
3304 padding-left: 20px;
3305 text-align: left;
3305 text-align: left;
3306 padding-top: 0px;
3306 padding-top: 0px;
3307 }
3307 }
3308
3308
3309 .stop_following_icon {
3309 .stop_following_icon {
3310 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3310 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3311 padding-left: 20px;
3311 padding-left: 20px;
3312 text-align: left;
3312 text-align: left;
3313 padding-top: 0px;
3313 padding-top: 0px;
3314 }
3314 }
3315
3315
3316 .action_button {
3316 .action_button {
3317 border: 0;
3317 border: 0;
3318 display: inline;
3318 display: inline;
3319 }
3319 }
3320
3320
3321 .action_button:hover {
3321 .action_button:hover {
3322 border: 0;
3322 border: 0;
3323 text-decoration: underline;
3323 text-decoration: underline;
3324 cursor: pointer;
3324 cursor: pointer;
3325 }
3325 }
3326
3326
3327 #switch_repos {
3327 #switch_repos {
3328 position: absolute;
3328 position: absolute;
3329 height: 25px;
3329 height: 25px;
3330 z-index: 1;
3330 z-index: 1;
3331 }
3331 }
3332
3332
3333 #switch_repos select {
3333 #switch_repos select {
3334 min-width: 150px;
3334 min-width: 150px;
3335 max-height: 250px;
3335 max-height: 250px;
3336 z-index: 1;
3336 z-index: 1;
3337 }
3337 }
3338
3338
3339 .breadcrumbs {
3339 .breadcrumbs {
3340 border: medium none;
3340 border: medium none;
3341 color: #FFF;
3341 color: #FFF;
3342 float: left;
3342 float: left;
3343 font-weight: 700;
3343 font-weight: 700;
3344 font-size: 14px;
3344 font-size: 14px;
3345 margin: 0;
3345 margin: 0;
3346 padding: 11px 0 11px 10px;
3346 padding: 11px 0 11px 10px;
3347 }
3347 }
3348
3348
3349 .breadcrumbs .hash {
3349 .breadcrumbs .hash {
3350 text-transform: none;
3350 text-transform: none;
3351 color: #fff;
3351 color: #fff;
3352 }
3352 }
3353
3353
3354 .breadcrumbs a {
3354 .breadcrumbs a {
3355 color: #FFF;
3355 color: #FFF;
3356 }
3356 }
3357
3357
3358 .flash_msg {
3358 .flash_msg {
3359 }
3359 }
3360
3360
3361 .flash_msg ul {
3361 .flash_msg ul {
3362 }
3362 }
3363
3363
3364 .error_red {
3364 .error_red {
3365 color: red;
3365 color: red;
3366 }
3366 }
3367
3367
3368 .error_msg {
3368 .error_msg {
3369 background-color: #c43c35;
3369 background-color: #c43c35;
3370 background-repeat: repeat-x;
3370 background-repeat: repeat-x;
3371 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35) );
3371 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35) );
3372 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3372 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3373 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3373 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3374 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) );
3374 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) );
3375 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3375 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3376 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3376 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3377 background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);
3377 background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);
3378 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 );
3378 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 );
3379 border-color: #c43c35 #c43c35 #882a25;
3379 border-color: #c43c35 #c43c35 #882a25;
3380 }
3380 }
3381
3381
3382 .error_msg a {
3382 .error_msg a {
3383 text-decoration: underline;
3383 text-decoration: underline;
3384 }
3384 }
3385
3385
3386 .warning_msg {
3386 .warning_msg {
3387 color: #404040 !important;
3387 color: #404040 !important;
3388 background-color: #eedc94;
3388 background-color: #eedc94;
3389 background-repeat: repeat-x;
3389 background-repeat: repeat-x;
3390 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94) );
3390 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94) );
3391 background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
3391 background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
3392 background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
3392 background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
3393 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) );
3393 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) );
3394 background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
3394 background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
3395 background-image: -o-linear-gradient(top, #fceec1, #eedc94);
3395 background-image: -o-linear-gradient(top, #fceec1, #eedc94);
3396 background-image: linear-gradient(to bottom, #fceec1, #eedc94);
3396 background-image: linear-gradient(to bottom, #fceec1, #eedc94);
3397 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 );
3397 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 );
3398 border-color: #eedc94 #eedc94 #e4c652;
3398 border-color: #eedc94 #eedc94 #e4c652;
3399 }
3399 }
3400
3400
3401 .warning_msg a {
3401 .warning_msg a {
3402 text-decoration: underline;
3402 text-decoration: underline;
3403 }
3403 }
3404
3404
3405 .success_msg {
3405 .success_msg {
3406 background-color: #57a957;
3406 background-color: #57a957;
3407 background-repeat: repeat-x !important;
3407 background-repeat: repeat-x !important;
3408 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957) );
3408 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957) );
3409 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3409 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3410 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3410 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3411 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) );
3411 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) );
3412 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3412 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3413 background-image: -o-linear-gradient(top, #62c462, #57a957);
3413 background-image: -o-linear-gradient(top, #62c462, #57a957);
3414 background-image: linear-gradient(to bottom, #62c462, #57a957);
3414 background-image: linear-gradient(to bottom, #62c462, #57a957);
3415 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 );
3415 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 );
3416 border-color: #57a957 #57a957 #3d773d;
3416 border-color: #57a957 #57a957 #3d773d;
3417 }
3417 }
3418
3418
3419 .success_msg a {
3419 .success_msg a {
3420 text-decoration: underline;
3420 text-decoration: underline;
3421 color: #FFF !important;
3421 color: #FFF !important;
3422 }
3422 }
3423
3423
3424 .notice_msg {
3424 .notice_msg {
3425 background-color: #339bb9;
3425 background-color: #339bb9;
3426 background-repeat: repeat-x;
3426 background-repeat: repeat-x;
3427 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9) );
3427 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9) );
3428 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3428 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3429 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3429 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3430 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) );
3430 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) );
3431 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3431 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3432 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3432 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3433 background-image: linear-gradient(to bottom, #5bc0de, #339bb9);
3433 background-image: linear-gradient(to bottom, #5bc0de, #339bb9);
3434 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 );
3434 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 );
3435 border-color: #339bb9 #339bb9 #22697d;
3435 border-color: #339bb9 #339bb9 #22697d;
3436 }
3436 }
3437
3437
3438 .notice_msg a {
3438 .notice_msg a {
3439 text-decoration: underline;
3439 text-decoration: underline;
3440 }
3440 }
3441
3441
3442 .success_msg, .error_msg, .notice_msg, .warning_msg {
3442 .success_msg, .error_msg, .notice_msg, .warning_msg {
3443 font-size: 12px;
3443 font-size: 12px;
3444 font-weight: 700;
3444 font-weight: 700;
3445 min-height: 14px;
3445 min-height: 14px;
3446 line-height: 14px;
3446 line-height: 14px;
3447 margin-bottom: 10px;
3447 margin-bottom: 10px;
3448 margin-top: 0;
3448 margin-top: 0;
3449 display: block;
3449 display: block;
3450 overflow: auto;
3450 overflow: auto;
3451 padding: 6px 10px 6px 10px;
3451 padding: 6px 10px 6px 10px;
3452 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3452 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3453 position: relative;
3453 position: relative;
3454 color: #FFF;
3454 color: #FFF;
3455 border-width: 1px;
3455 border-width: 1px;
3456 border-style: solid;
3456 border-style: solid;
3457 -webkit-border-radius: 4px;
3457 -webkit-border-radius: 4px;
3458 border-radius: 4px;
3458 border-radius: 4px;
3459 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3459 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3460 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3460 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3461 }
3461 }
3462
3462
3463 #msg_close {
3463 #msg_close {
3464 background: transparent url("../icons/cross_grey_small.png") no-repeat scroll 0 0;
3464 background: transparent url("../icons/cross_grey_small.png") no-repeat scroll 0 0;
3465 cursor: pointer;
3465 cursor: pointer;
3466 height: 16px;
3466 height: 16px;
3467 position: absolute;
3467 position: absolute;
3468 right: 5px;
3468 right: 5px;
3469 top: 5px;
3469 top: 5px;
3470 width: 16px;
3470 width: 16px;
3471 }
3471 }
3472 div#legend_data {
3472 div#legend_data {
3473 padding-left: 10px;
3473 padding-left: 10px;
3474 }
3474 }
3475 div#legend_container table {
3475 div#legend_container table {
3476 border: none !important;
3476 border: none !important;
3477 }
3477 }
3478 div#legend_container table, div#legend_choices table {
3478 div#legend_container table, div#legend_choices table {
3479 width: auto !important;
3479 width: auto !important;
3480 }
3480 }
3481
3481
3482 table#permissions_manage {
3482 table#permissions_manage {
3483 width: 0 !important;
3483 width: 0 !important;
3484 }
3484 }
3485
3485
3486 table#permissions_manage span.private_repo_msg {
3486 table#permissions_manage span.private_repo_msg {
3487 font-size: 0.8em;
3487 font-size: 0.8em;
3488 opacity: 0.6;
3488 opacity: 0.6;
3489 }
3489 }
3490
3490
3491 table#permissions_manage td.private_repo_msg {
3491 table#permissions_manage td.private_repo_msg {
3492 font-size: 0.8em;
3492 font-size: 0.8em;
3493 }
3493 }
3494
3494
3495 table#permissions_manage tr#add_perm_input td {
3495 table#permissions_manage tr#add_perm_input td {
3496 vertical-align: middle;
3496 vertical-align: middle;
3497 }
3497 }
3498
3498
3499 div.gravatar {
3499 div.gravatar {
3500 background-color: #FFF;
3500 background-color: #FFF;
3501 float: left;
3501 float: left;
3502 margin-right: 0.7em;
3502 margin-right: 0.7em;
3503 padding: 1px 1px 1px 1px;
3503 padding: 1px 1px 1px 1px;
3504 line-height: 0;
3504 line-height: 0;
3505 -webkit-border-radius: 3px;
3505 -webkit-border-radius: 3px;
3506 -khtml-border-radius: 3px;
3506 -khtml-border-radius: 3px;
3507 border-radius: 3px;
3507 border-radius: 3px;
3508 }
3508 }
3509
3509
3510 div.gravatar img {
3510 div.gravatar img {
3511 -webkit-border-radius: 2px;
3511 -webkit-border-radius: 2px;
3512 -khtml-border-radius: 2px;
3512 -khtml-border-radius: 2px;
3513 border-radius: 2px;
3513 border-radius: 2px;
3514 }
3514 }
3515
3515
3516 #header, #content, #footer {
3516 #header, #content, #footer {
3517 min-width: 978px;
3517 min-width: 978px;
3518 }
3518 }
3519
3519
3520 #content {
3520 #content {
3521 clear: both;
3521 clear: both;
3522 padding: 10px 10px 14px 10px;
3522 padding: 10px 10px 14px 10px;
3523 }
3523 }
3524
3524
3525 #content.hover {
3525 #content.hover {
3526 padding: 55px 10px 14px 10px !important;
3526 padding: 55px 10px 14px 10px !important;
3527 }
3527 }
3528
3528
3529 #content div.box div.title div.search {
3529 #content div.box div.title div.search {
3530 border-left: 1px solid #316293;
3530 border-left: 1px solid #316293;
3531 }
3531 }
3532
3532
3533 #content div.box div.title div.search div.input input {
3533 #content div.box div.title div.search div.input input {
3534 border: 1px solid #316293;
3534 border: 1px solid #316293;
3535 }
3535 }
3536
3536
3537 .ui-btn {
3537 .ui-btn {
3538 color: #515151;
3538 color: #515151;
3539 background-color: #DADADA;
3539 background-color: #DADADA;
3540 background-repeat: repeat-x;
3540 background-repeat: repeat-x;
3541 background-image: -khtml-gradient(linear, left top, left bottom, from(#F4F4F4),to(#DADADA) );
3541 background-image: -khtml-gradient(linear, left top, left bottom, from(#F4F4F4),to(#DADADA) );
3542 background-image: -moz-linear-gradient(top, #F4F4F4, #DADADA);
3542 background-image: -moz-linear-gradient(top, #F4F4F4, #DADADA);
3543 background-image: -ms-linear-gradient(top, #F4F4F4, #DADADA);
3543 background-image: -ms-linear-gradient(top, #F4F4F4, #DADADA);
3544 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) );
3544 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) );
3545 background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) );
3545 background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) );
3546 background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) );
3546 background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) );
3547 background-image: linear-gradient(to bottom, #F4F4F4, #DADADA);
3547 background-image: linear-gradient(to bottom, #F4F4F4, #DADADA);
3548 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0);
3548 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0);
3549
3549
3550 border-top: 1px solid #DDD;
3550 border-top: 1px solid #DDD;
3551 border-left: 1px solid #c6c6c6;
3551 border-left: 1px solid #c6c6c6;
3552 border-right: 1px solid #DDD;
3552 border-right: 1px solid #DDD;
3553 border-bottom: 1px solid #c6c6c6;
3553 border-bottom: 1px solid #c6c6c6;
3554 color: #515151;
3554 color: #515151;
3555 outline: none;
3555 outline: none;
3556 margin: 0px 3px 3px 0px;
3556 margin: 0px 3px 3px 0px;
3557 -webkit-border-radius: 4px 4px 4px 4px !important;
3557 -webkit-border-radius: 4px 4px 4px 4px !important;
3558 -khtml-border-radius: 4px 4px 4px 4px !important;
3558 -khtml-border-radius: 4px 4px 4px 4px !important;
3559 border-radius: 4px 4px 4px 4px !important;
3559 border-radius: 4px 4px 4px 4px !important;
3560 cursor: pointer !important;
3560 cursor: pointer !important;
3561 padding: 3px 3px 3px 3px;
3561 padding: 3px 3px 3px 3px;
3562 background-position: 0 -15px;
3562 background-position: 0 -15px;
3563
3563
3564 }
3564 }
3565
3565
3566 .ui-btn.disabled {
3566 .ui-btn.disabled {
3567 color: #999;
3567 color: #999;
3568 }
3568 }
3569
3569
3570 .ui-btn.xsmall {
3570 .ui-btn.xsmall {
3571 padding: 1px 2px 1px 1px;
3571 padding: 1px 2px 1px 1px;
3572 }
3572 }
3573
3573
3574 .ui-btn.large {
3574 .ui-btn.large {
3575 padding: 6px 12px;
3575 padding: 6px 12px;
3576 }
3576 }
3577
3577
3578 .ui-btn.clone {
3578 .ui-btn.clone {
3579 padding: 5px 2px 6px 1px;
3579 padding: 5px 2px 6px 1px;
3580 margin: 0px 0px 3px -4px;
3580 margin: 0px 0px 3px -4px;
3581 -webkit-border-radius: 0px 4px 4px 0px !important;
3581 -webkit-border-radius: 0px 4px 4px 0px !important;
3582 -khtml-border-radius: 0px 4px 4px 0px !important;
3582 -khtml-border-radius: 0px 4px 4px 0px !important;
3583 border-radius: 0px 4px 4px 0px !important;
3583 border-radius: 0px 4px 4px 0px !important;
3584 width: 100px;
3584 width: 100px;
3585 text-align: center;
3585 text-align: center;
3586 display: inline-block;
3586 display: inline-block;
3587 position: relative;
3587 position: relative;
3588 top: -2px;
3588 top: -2px;
3589 }
3589 }
3590 .ui-btn:focus {
3590 .ui-btn:focus {
3591 outline: none;
3591 outline: none;
3592 }
3592 }
3593 .ui-btn:hover {
3593 .ui-btn:hover {
3594 background-position: 0 -15px;
3594 background-position: 0 -15px;
3595 text-decoration: none;
3595 text-decoration: none;
3596 color: #515151;
3596 color: #515151;
3597 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 3px #FFFFFF !important;
3597 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 3px #FFFFFF !important;
3598 }
3598 }
3599
3599
3600 .ui-btn.disabled:hover {
3600 .ui-btn.disabled:hover {
3601 background-position: 0;
3601 background-position: 0;
3602 color: #999;
3602 color: #999;
3603 text-decoration: none;
3603 text-decoration: none;
3604 box-shadow: none !important;
3604 box-shadow: none !important;
3605 }
3605 }
3606
3606
3607 .ui-btn.red {
3607 .ui-btn.red {
3608 color: #fff;
3608 color: #fff;
3609 background-color: #c43c35;
3609 background-color: #c43c35;
3610 background-repeat: repeat-x;
3610 background-repeat: repeat-x;
3611 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
3611 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
3612 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3612 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3613 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3613 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3614 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));
3614 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));
3615 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3615 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3616 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3616 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3617 background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);
3617 background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);
3618 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
3618 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
3619 border-color: #c43c35 #c43c35 #882a25;
3619 border-color: #c43c35 #c43c35 #882a25;
3620 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3620 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3621 }
3621 }
3622
3622
3623
3623
3624 .ui-btn.blue {
3624 .ui-btn.blue {
3625 color: #fff;
3625 color: #fff;
3626 background-color: #339bb9;
3626 background-color: #339bb9;
3627 background-repeat: repeat-x;
3627 background-repeat: repeat-x;
3628 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));
3628 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));
3629 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3629 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3630 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3630 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3631 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));
3631 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));
3632 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3632 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3633 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3633 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3634 background-image: linear-gradient(to bottom, #5bc0de, #339bb9);
3634 background-image: linear-gradient(to bottom, #5bc0de, #339bb9);
3635 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
3635 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
3636 border-color: #339bb9 #339bb9 #22697d;
3636 border-color: #339bb9 #339bb9 #22697d;
3637 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
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 .ui-btn.green {
3640 .ui-btn.green {
3641 background-color: #57a957;
3641 background-color: #57a957;
3642 background-repeat: repeat-x;
3642 background-repeat: repeat-x;
3643 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));
3643 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));
3644 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3644 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3645 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3645 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3646 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));
3646 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));
3647 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3647 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3648 background-image: -o-linear-gradient(top, #62c462, #57a957);
3648 background-image: -o-linear-gradient(top, #62c462, #57a957);
3649 background-image: linear-gradient(to bottom, #62c462, #57a957);
3649 background-image: linear-gradient(to bottom, #62c462, #57a957);
3650 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
3650 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
3651 border-color: #57a957 #57a957 #3d773d;
3651 border-color: #57a957 #57a957 #3d773d;
3652 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3652 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3653 }
3653 }
3654
3654
3655 .ui-btn.blue.hidden {
3655 .ui-btn.blue.hidden {
3656 display: none;
3656 display: none;
3657 }
3657 }
3658
3658
3659 .ui-btn.active {
3659 .ui-btn.active {
3660 font-weight: bold;
3660 font-weight: bold;
3661 }
3661 }
3662
3662
3663 ins, div.options a:hover {
3663 ins, div.options a:hover {
3664 text-decoration: none;
3664 text-decoration: none;
3665 }
3665 }
3666
3666
3667 img,
3667 img,
3668 #header #header-inner #quick li a:hover span.normal,
3668 #header #header-inner #quick li a:hover span.normal,
3669 #content div.box div.form div.fields div.field div.textarea table td table td a,
3669 #content div.box div.form div.fields div.field div.textarea table td table td a,
3670 #clone_url,
3670 #clone_url,
3671 #clone_url_id
3671 #clone_url_id
3672 {
3672 {
3673 border: none;
3673 border: none;
3674 }
3674 }
3675
3675
3676 img.icon, .right .merge img {
3676 img.icon, .right .merge img {
3677 vertical-align: bottom;
3677 vertical-align: bottom;
3678 }
3678 }
3679
3679
3680 #header ul#logged-user, #content div.box div.title ul.links,
3680 #header ul#logged-user, #content div.box div.title ul.links,
3681 #content div.box div.message div.dismiss,
3681 #content div.box div.message div.dismiss,
3682 #content div.box div.traffic div.legend ul {
3682 #content div.box div.traffic div.legend ul {
3683 float: right;
3683 float: right;
3684 margin: 0;
3684 margin: 0;
3685 padding: 0;
3685 padding: 0;
3686 }
3686 }
3687
3687
3688 #header #header-inner #home, #header #header-inner #logo,
3688 #header #header-inner #home, #header #header-inner #logo,
3689 #content div.box ul.left, #content div.box ol.left,
3689 #content div.box ul.left, #content div.box ol.left,
3690 div#commit_history,
3690 div#commit_history,
3691 div#legend_data, div#legend_container, div#legend_choices {
3691 div#legend_data, div#legend_container, div#legend_choices {
3692 float: left;
3692 float: left;
3693 }
3693 }
3694
3694
3695 #header #header-inner #quick li #quick_login,
3695 #header #header-inner #quick li #quick_login,
3696 #header #header-inner #quick li:hover ul ul,
3696 #header #header-inner #quick li:hover ul ul,
3697 #header #header-inner #quick li:hover ul ul ul,
3697 #header #header-inner #quick li:hover ul ul ul,
3698 #header #header-inner #quick li:hover ul ul ul ul,
3698 #header #header-inner #quick li:hover ul ul ul ul,
3699 #content #left #menu ul.closed, #content #left #menu li ul.collapsed, .yui-tt-shadow {
3699 #content #left #menu ul.closed, #content #left #menu li ul.collapsed, .yui-tt-shadow {
3700 display: none;
3700 display: none;
3701 }
3701 }
3702
3702
3703 #header #header-inner #quick li:hover #quick_login,
3703 #header #header-inner #quick li:hover #quick_login,
3704 #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 {
3704 #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 {
3705 display: block;
3705 display: block;
3706 }
3706 }
3707
3707
3708 #content div.graph {
3708 #content div.graph {
3709 padding: 0 10px 10px;
3709 padding: 0 10px 10px;
3710 }
3710 }
3711
3711
3712 #content div.box div.title ul.links li a:hover,
3712 #content div.box div.title ul.links li a:hover,
3713 #content div.box div.title ul.links li.ui-tabs-selected a {
3713 #content div.box div.title ul.links li.ui-tabs-selected a {
3714
3714
3715 background: #6388ad; /* Old browsers */
3715 background: #6388ad; /* Old browsers */
3716 background: -moz-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* FF3.6+ */
3716 background: -moz-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* FF3.6+ */
3717 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.1)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
3717 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.1)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
3718 background: -webkit-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* Chrome10+,Safari5.1+ */
3718 background: -webkit-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* Chrome10+,Safari5.1+ */
3719 background: -o-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* Opera 11.10+ */
3719 background: -o-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* Opera 11.10+ */
3720 background: -ms-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* IE10+ */
3720 background: -ms-linear-gradient(top, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* IE10+ */
3721 background: linear-gradient(to bottom, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* W3C */
3721 background: linear-gradient(to bottom, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%); /* W3C */
3722 /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#88bfe8', endColorstr='#70b0e0',GradientType=0 ); /* IE6-9 */*/
3722 /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#88bfe8', endColorstr='#70b0e0',GradientType=0 ); /* IE6-9 */*/
3723 }
3723 }
3724
3724
3725 #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 {
3725 #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 {
3726 margin: 10px 24px 10px 44px;
3726 margin: 10px 24px 10px 44px;
3727 }
3727 }
3728
3728
3729 #content div.box div.form, #content div.box div.table, #content div.box div.traffic {
3729 #content div.box div.form, #content div.box div.table, #content div.box div.traffic {
3730 position: relative;
3730 position: relative;
3731 clear: both;
3731 clear: both;
3732 margin: 0;
3732 margin: 0;
3733 padding: 0 20px 10px;
3733 padding: 0 20px 10px;
3734 }
3734 }
3735
3735
3736 #content div.box div.form div.fields, #login div.form, #login div.form div.fields, #register div.form, #register div.form div.fields {
3736 #content div.box div.form div.fields, #login div.form, #login div.form div.fields, #register div.form, #register div.form div.fields {
3737 clear: both;
3737 clear: both;
3738 overflow: hidden;
3738 overflow: hidden;
3739 margin: 0;
3739 margin: 0;
3740 padding: 0;
3740 padding: 0;
3741 }
3741 }
3742
3742
3743 #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 {
3743 #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 {
3744 height: 1%;
3744 height: 1%;
3745 display: block;
3745 display: block;
3746 color: #363636;
3746 color: #363636;
3747 margin: 0;
3747 margin: 0;
3748 padding: 2px 0 0;
3748 padding: 2px 0 0;
3749 }
3749 }
3750
3750
3751 #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 {
3751 #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 {
3752 background: #FBE3E4;
3752 background: #FBE3E4;
3753 border-top: 1px solid #e1b2b3;
3753 border-top: 1px solid #e1b2b3;
3754 border-left: 1px solid #e1b2b3;
3754 border-left: 1px solid #e1b2b3;
3755 border-right: 1px solid #FBC2C4;
3755 border-right: 1px solid #FBC2C4;
3756 border-bottom: 1px solid #FBC2C4;
3756 border-bottom: 1px solid #FBC2C4;
3757 }
3757 }
3758
3758
3759 #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 {
3759 #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 {
3760 background: #E6EFC2;
3760 background: #E6EFC2;
3761 border-top: 1px solid #cebb98;
3761 border-top: 1px solid #cebb98;
3762 border-left: 1px solid #cebb98;
3762 border-left: 1px solid #cebb98;
3763 border-right: 1px solid #c6d880;
3763 border-right: 1px solid #c6d880;
3764 border-bottom: 1px solid #c6d880;
3764 border-bottom: 1px solid #c6d880;
3765 }
3765 }
3766
3766
3767 #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 {
3767 #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 {
3768 margin: 0;
3768 margin: 0;
3769 }
3769 }
3770
3770
3771 #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 {
3771 #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 {
3772 margin: 0 0 0 0px !important;
3772 margin: 0 0 0 0px !important;
3773 padding: 0;
3773 padding: 0;
3774 }
3774 }
3775
3775
3776 #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 {
3776 #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 {
3777 margin: 0 0 0 200px;
3777 margin: 0 0 0 200px;
3778 padding: 0;
3778 padding: 0;
3779 }
3779 }
3780
3780
3781 #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 {
3781 #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 {
3782 color: #000;
3782 color: #000;
3783 text-decoration: none;
3783 text-decoration: none;
3784 }
3784 }
3785
3785
3786 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus, #content div.box div.action a.ui-selectmenu-focus {
3786 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus, #content div.box div.action a.ui-selectmenu-focus {
3787 border: 1px solid #666;
3787 border: 1px solid #666;
3788 }
3788 }
3789
3789
3790 #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 {
3790 #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 {
3791 clear: both;
3791 clear: both;
3792 overflow: hidden;
3792 overflow: hidden;
3793 margin: 0;
3793 margin: 0;
3794 padding: 8px 0 2px;
3794 padding: 8px 0 2px;
3795 }
3795 }
3796
3796
3797 #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 {
3797 #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 {
3798 float: left;
3798 float: left;
3799 margin: 0;
3799 margin: 0;
3800 }
3800 }
3801
3801
3802 #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 {
3802 #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 {
3803 height: 1%;
3803 height: 1%;
3804 display: block;
3804 display: block;
3805 float: left;
3805 float: left;
3806 margin: 2px 0 0 4px;
3806 margin: 2px 0 0 4px;
3807 }
3807 }
3808
3808
3809 div.form div.fields div.field div.button input,
3809 div.form div.fields div.field div.button input,
3810 #content div.box div.form div.fields div.buttons input
3810 #content div.box div.form div.fields div.buttons input
3811 div.form div.fields div.buttons input,
3811 div.form div.fields div.buttons input,
3812 #content div.box div.action div.button input {
3812 #content div.box div.action div.button input {
3813 font-size: 11px;
3813 font-size: 11px;
3814 font-weight: 700;
3814 font-weight: 700;
3815 margin: 0;
3815 margin: 0;
3816 }
3816 }
3817
3817
3818 input.ui-button {
3818 input.ui-button {
3819 background: #e5e3e3 url("../images/button.png") repeat-x;
3819 background: #e5e3e3 url("../images/button.png") repeat-x;
3820 border-top: 1px solid #DDD;
3820 border-top: 1px solid #DDD;
3821 border-left: 1px solid #c6c6c6;
3821 border-left: 1px solid #c6c6c6;
3822 border-right: 1px solid #DDD;
3822 border-right: 1px solid #DDD;
3823 border-bottom: 1px solid #c6c6c6;
3823 border-bottom: 1px solid #c6c6c6;
3824 color: #515151 !important;
3824 color: #515151 !important;
3825 outline: none;
3825 outline: none;
3826 margin: 0;
3826 margin: 0;
3827 padding: 6px 12px;
3827 padding: 6px 12px;
3828 -webkit-border-radius: 4px 4px 4px 4px;
3828 -webkit-border-radius: 4px 4px 4px 4px;
3829 -khtml-border-radius: 4px 4px 4px 4px;
3829 -khtml-border-radius: 4px 4px 4px 4px;
3830 border-radius: 4px 4px 4px 4px;
3830 border-radius: 4px 4px 4px 4px;
3831 box-shadow: 0 1px 0 #ececec;
3831 box-shadow: 0 1px 0 #ececec;
3832 cursor: pointer;
3832 cursor: pointer;
3833 }
3833 }
3834
3834
3835 input.ui-button:hover {
3835 input.ui-button:hover {
3836 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3836 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3837 border-top: 1px solid #ccc;
3837 border-top: 1px solid #ccc;
3838 border-left: 1px solid #bebebe;
3838 border-left: 1px solid #bebebe;
3839 border-right: 1px solid #b1b1b1;
3839 border-right: 1px solid #b1b1b1;
3840 border-bottom: 1px solid #afafaf;
3840 border-bottom: 1px solid #afafaf;
3841 }
3841 }
3842
3842
3843 div.form div.fields div.field div.highlight, #content div.box div.form div.fields div.buttons div.highlight {
3843 div.form div.fields div.field div.highlight, #content div.box div.form div.fields div.buttons div.highlight {
3844 display: inline;
3844 display: inline;
3845 }
3845 }
3846
3846
3847 #content div.box div.form div.fields div.buttons, div.form div.fields div.buttons {
3847 #content div.box div.form div.fields div.buttons, div.form div.fields div.buttons {
3848 margin: 10px 0 0 200px;
3848 margin: 10px 0 0 200px;
3849 padding: 0;
3849 padding: 0;
3850 }
3850 }
3851
3851
3852 #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 {
3852 #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 {
3853 margin: 10px 0 0;
3853 margin: 10px 0 0;
3854 }
3854 }
3855
3855
3856 #content div.box table td.user, #content div.box table td.address {
3856 #content div.box table td.user, #content div.box table td.address {
3857 width: 10%;
3857 width: 10%;
3858 text-align: center;
3858 text-align: center;
3859 }
3859 }
3860
3860
3861 #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 {
3861 #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 {
3862 text-align: right;
3862 text-align: right;
3863 margin: 6px 0 0;
3863 margin: 6px 0 0;
3864 padding: 0;
3864 padding: 0;
3865 }
3865 }
3866
3866
3867 #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 {
3867 #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 {
3868 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3868 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3869 border-top: 1px solid #ccc;
3869 border-top: 1px solid #ccc;
3870 border-left: 1px solid #bebebe;
3870 border-left: 1px solid #bebebe;
3871 border-right: 1px solid #b1b1b1;
3871 border-right: 1px solid #b1b1b1;
3872 border-bottom: 1px solid #afafaf;
3872 border-bottom: 1px solid #afafaf;
3873 color: #515151;
3873 color: #515151;
3874 margin: 0;
3874 margin: 0;
3875 padding: 6px 12px;
3875 padding: 6px 12px;
3876 }
3876 }
3877
3877
3878 #content div.box div.pagination div.results, #content div.box div.pagination-wh div.results {
3878 #content div.box div.pagination div.results, #content div.box div.pagination-wh div.results {
3879 text-align: left;
3879 text-align: left;
3880 float: left;
3880 float: left;
3881 margin: 0;
3881 margin: 0;
3882 padding: 0;
3882 padding: 0;
3883 }
3883 }
3884
3884
3885 #content div.box div.pagination div.results span, #content div.box div.pagination-wh div.results span {
3885 #content div.box div.pagination div.results span, #content div.box div.pagination-wh div.results span {
3886 height: 1%;
3886 height: 1%;
3887 display: block;
3887 display: block;
3888 float: left;
3888 float: left;
3889 background: #ebebeb url("../images/pager.png") repeat-x;
3889 background: #ebebeb url("../images/pager.png") repeat-x;
3890 border-top: 1px solid #dedede;
3890 border-top: 1px solid #dedede;
3891 border-left: 1px solid #cfcfcf;
3891 border-left: 1px solid #cfcfcf;
3892 border-right: 1px solid #c4c4c4;
3892 border-right: 1px solid #c4c4c4;
3893 border-bottom: 1px solid #c4c4c4;
3893 border-bottom: 1px solid #c4c4c4;
3894 color: #4A4A4A;
3894 color: #4A4A4A;
3895 font-weight: 700;
3895 font-weight: 700;
3896 margin: 0;
3896 margin: 0;
3897 padding: 6px 8px;
3897 padding: 6px 8px;
3898 }
3898 }
3899
3899
3900 #content div.box div.pagination ul.pager li.disabled, #content div.box div.pagination-wh a.disabled {
3900 #content div.box div.pagination ul.pager li.disabled, #content div.box div.pagination-wh a.disabled {
3901 color: #B4B4B4;
3901 color: #B4B4B4;
3902 padding: 6px;
3902 padding: 6px;
3903 }
3903 }
3904
3904
3905 #login, #register {
3905 #login, #register {
3906 width: 520px;
3906 width: 520px;
3907 margin: 10% auto 0;
3907 margin: 10% auto 0;
3908 padding: 0;
3908 padding: 0;
3909 }
3909 }
3910
3910
3911 #login div.color, #register div.color {
3911 #login div.color, #register div.color {
3912 clear: both;
3912 clear: both;
3913 overflow: hidden;
3913 overflow: hidden;
3914 background: #FFF;
3914 background: #FFF;
3915 margin: 10px auto 0;
3915 margin: 10px auto 0;
3916 padding: 3px 3px 3px 0;
3916 padding: 3px 3px 3px 0;
3917 }
3917 }
3918
3918
3919 #login div.color a, #register div.color a {
3919 #login div.color a, #register div.color a {
3920 width: 20px;
3920 width: 20px;
3921 height: 20px;
3921 height: 20px;
3922 display: block;
3922 display: block;
3923 float: left;
3923 float: left;
3924 margin: 0 0 0 3px;
3924 margin: 0 0 0 3px;
3925 padding: 0;
3925 padding: 0;
3926 }
3926 }
3927
3927
3928 #login div.title h5, #register div.title h5 {
3928 #login div.title h5, #register div.title h5 {
3929 color: #fff;
3929 color: #fff;
3930 margin: 10px;
3930 margin: 10px;
3931 padding: 0;
3931 padding: 0;
3932 }
3932 }
3933
3933
3934 #login div.form div.fields div.field, #register div.form div.fields div.field {
3934 #login div.form div.fields div.field, #register div.form div.fields div.field {
3935 clear: both;
3935 clear: both;
3936 overflow: hidden;
3936 overflow: hidden;
3937 margin: 0;
3937 margin: 0;
3938 padding: 0 0 10px;
3938 padding: 0 0 10px;
3939 }
3939 }
3940
3940
3941 #login div.form div.fields div.field span.error-message, #register div.form div.fields div.field span.error-message {
3941 #login div.form div.fields div.field span.error-message, #register div.form div.fields div.field span.error-message {
3942 height: 1%;
3942 height: 1%;
3943 display: block;
3943 display: block;
3944 color: red;
3944 color: red;
3945 margin: 8px 0 0;
3945 margin: 8px 0 0;
3946 padding: 0;
3946 padding: 0;
3947 max-width: 320px;
3947 max-width: 320px;
3948 }
3948 }
3949
3949
3950 #login div.form div.fields div.field div.label label, #register div.form div.fields div.field div.label label {
3950 #login div.form div.fields div.field div.label label, #register div.form div.fields div.field div.label label {
3951 color: #000;
3951 color: #000;
3952 font-weight: 700;
3952 font-weight: 700;
3953 }
3953 }
3954
3954
3955 #login div.form div.fields div.field div.input, #register div.form div.fields div.field div.input {
3955 #login div.form div.fields div.field div.input, #register div.form div.fields div.field div.input {
3956 float: left;
3956 float: left;
3957 margin: 0;
3957 margin: 0;
3958 padding: 0;
3958 padding: 0;
3959 }
3959 }
3960
3960
3961 #login div.form div.fields div.field div.input input.large {
3961 #login div.form div.fields div.field div.input input.large {
3962 width: 250px;
3962 width: 250px;
3963 }
3963 }
3964
3964
3965 #login div.form div.fields div.field div.checkbox, #register div.form div.fields div.field div.checkbox {
3965 #login div.form div.fields div.field div.checkbox, #register div.form div.fields div.field div.checkbox {
3966 margin: 0 0 0 184px;
3966 margin: 0 0 0 184px;
3967 padding: 0;
3967 padding: 0;
3968 }
3968 }
3969
3969
3970 #login div.form div.fields div.field div.checkbox label, #register div.form div.fields div.field div.checkbox label {
3970 #login div.form div.fields div.field div.checkbox label, #register div.form div.fields div.field div.checkbox label {
3971 color: #565656;
3971 color: #565656;
3972 font-weight: 700;
3972 font-weight: 700;
3973 }
3973 }
3974
3974
3975 #login div.form div.fields div.buttons input, #register div.form div.fields div.buttons input {
3975 #login div.form div.fields div.buttons input, #register div.form div.fields div.buttons input {
3976 color: #000;
3976 color: #000;
3977 font-size: 1em;
3977 font-size: 1em;
3978 font-weight: 700;
3978 font-weight: 700;
3979 margin: 0;
3979 margin: 0;
3980 }
3980 }
3981
3981
3982 #changeset_content .container .wrapper, #graph_content .container .wrapper {
3982 #changeset_content .container .wrapper, #graph_content .container .wrapper {
3983 width: 600px;
3983 width: 600px;
3984 }
3984 }
3985
3985
3986 #changeset_content .container .date, .ac .match {
3986 #changeset_content .container .date, .ac .match {
3987 font-weight: 700;
3987 font-weight: 700;
3988 padding-top: 5px;
3988 padding-top: 5px;
3989 padding-bottom: 5px;
3989 padding-bottom: 5px;
3990 }
3990 }
3991
3991
3992 div#legend_container table td, div#legend_choices table td {
3992 div#legend_container table td, div#legend_choices table td {
3993 border: none !important;
3993 border: none !important;
3994 height: 20px !important;
3994 height: 20px !important;
3995 padding: 0 !important;
3995 padding: 0 !important;
3996 }
3996 }
3997
3997
3998 .q_filter_box {
3998 .q_filter_box {
3999 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3999 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4000 -webkit-border-radius: 4px;
4000 -webkit-border-radius: 4px;
4001 border-radius: 4px;
4001 border-radius: 4px;
4002 border: 0 none;
4002 border: 0 none;
4003 color: #AAAAAA;
4003 color: #AAAAAA;
4004 margin-bottom: -4px;
4004 margin-bottom: -4px;
4005 margin-top: -4px;
4005 margin-top: -4px;
4006 padding-left: 3px;
4006 padding-left: 3px;
4007 }
4007 }
4008
4008
4009 #node_filter {
4009 #node_filter {
4010 border: 0px solid #545454;
4010 border: 0px solid #545454;
4011 color: #AAAAAA;
4011 color: #AAAAAA;
4012 padding-left: 3px;
4012 padding-left: 3px;
4013 }
4013 }
4014
4014
4015
4015
4016 .group_members_wrap {
4016 .group_members_wrap {
4017 min-height: 85px;
4017 min-height: 85px;
4018 padding-left: 20px;
4018 padding-left: 20px;
4019 }
4019 }
4020
4020
4021 .group_members .group_member {
4021 .group_members .group_member {
4022 height: 30px;
4022 height: 30px;
4023 padding: 0px 0px 0px 0px;
4023 padding: 0px 0px 0px 0px;
4024 }
4024 }
4025
4025
4026 .reviewers_member {
4026 .reviewers_member {
4027 height: 15px;
4027 height: 15px;
4028 padding: 0px 0px 0px 10px;
4028 padding: 0px 0px 0px 10px;
4029 }
4029 }
4030
4030
4031 .emails_wrap {
4031 .emails_wrap {
4032 padding: 0px 20px;
4032 padding: 0px 20px;
4033 }
4033 }
4034
4034
4035 .emails_wrap .email_entry {
4035 .emails_wrap .email_entry {
4036 height: 30px;
4036 height: 30px;
4037 padding: 0px 0px 0px 10px;
4037 padding: 0px 0px 0px 10px;
4038 }
4038 }
4039 .emails_wrap .email_entry .email {
4039 .emails_wrap .email_entry .email {
4040 float: left
4040 float: left
4041 }
4041 }
4042 .emails_wrap .email_entry .email_action {
4042 .emails_wrap .email_entry .email_action {
4043 float: left
4043 float: left
4044 }
4044 }
4045
4045
4046 .ips_wrap {
4046 .ips_wrap {
4047 padding: 0px 20px;
4047 padding: 0px 20px;
4048 }
4048 }
4049
4049
4050 .ips_wrap .ip_entry {
4050 .ips_wrap .ip_entry {
4051 height: 30px;
4051 height: 30px;
4052 padding: 0px 0px 0px 10px;
4052 padding: 0px 0px 0px 10px;
4053 }
4053 }
4054 .ips_wrap .ip_entry .ip {
4054 .ips_wrap .ip_entry .ip {
4055 float: left
4055 float: left
4056 }
4056 }
4057 .ips_wrap .ip_entry .ip_action {
4057 .ips_wrap .ip_entry .ip_action {
4058 float: left
4058 float: left
4059 }
4059 }
4060
4060
4061
4061
4062 /*README STYLE*/
4062 /*README STYLE*/
4063
4063
4064 div.readme {
4064 div.readme {
4065 padding: 0px;
4065 padding: 0px;
4066 }
4066 }
4067
4067
4068 div.readme h2 {
4068 div.readme h2 {
4069 font-weight: normal;
4069 font-weight: normal;
4070 }
4070 }
4071
4071
4072 div.readme .readme_box {
4072 div.readme .readme_box {
4073 background-color: #fafafa;
4073 background-color: #fafafa;
4074 }
4074 }
4075
4075
4076 div.readme .readme_box {
4076 div.readme .readme_box {
4077 clear: both;
4077 clear: both;
4078 overflow: hidden;
4078 overflow: hidden;
4079 margin: 0;
4079 margin: 0;
4080 padding: 0 20px 10px;
4080 padding: 0 20px 10px;
4081 }
4081 }
4082
4082
4083 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 {
4083 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 {
4084 border-bottom: 0 !important;
4084 border-bottom: 0 !important;
4085 margin: 0 !important;
4085 margin: 0 !important;
4086 padding: 0 !important;
4086 padding: 0 !important;
4087 line-height: 1.5em !important;
4087 line-height: 1.5em !important;
4088 }
4088 }
4089
4089
4090
4090
4091 div.readme .readme_box h1:first-child {
4091 div.readme .readme_box h1:first-child {
4092 padding-top: .25em !important;
4092 padding-top: .25em !important;
4093 }
4093 }
4094
4094
4095 div.readme .readme_box h2, div.readme .readme_box h3 {
4095 div.readme .readme_box h2, div.readme .readme_box h3 {
4096 margin: 1em 0 !important;
4096 margin: 1em 0 !important;
4097 }
4097 }
4098
4098
4099 div.readme .readme_box h2 {
4099 div.readme .readme_box h2 {
4100 margin-top: 1.5em !important;
4100 margin-top: 1.5em !important;
4101 border-top: 4px solid #e0e0e0 !important;
4101 border-top: 4px solid #e0e0e0 !important;
4102 padding-top: .5em !important;
4102 padding-top: .5em !important;
4103 }
4103 }
4104
4104
4105 div.readme .readme_box p {
4105 div.readme .readme_box p {
4106 color: black !important;
4106 color: black !important;
4107 margin: 1em 0 !important;
4107 margin: 1em 0 !important;
4108 line-height: 1.5em !important;
4108 line-height: 1.5em !important;
4109 }
4109 }
4110
4110
4111 div.readme .readme_box ul {
4111 div.readme .readme_box ul {
4112 list-style: disc !important;
4112 list-style: disc !important;
4113 margin: 1em 0 1em 2em !important;
4113 margin: 1em 0 1em 2em !important;
4114 }
4114 }
4115
4115
4116 div.readme .readme_box ol {
4116 div.readme .readme_box ol {
4117 list-style: decimal;
4117 list-style: decimal;
4118 margin: 1em 0 1em 2em !important;
4118 margin: 1em 0 1em 2em !important;
4119 }
4119 }
4120
4120
4121 div.readme .readme_box pre, code {
4121 div.readme .readme_box pre, code {
4122 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4122 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4123 }
4123 }
4124
4124
4125 div.readme .readme_box code {
4125 div.readme .readme_box code {
4126 font-size: 12px !important;
4126 font-size: 12px !important;
4127 background-color: ghostWhite !important;
4127 background-color: ghostWhite !important;
4128 color: #444 !important;
4128 color: #444 !important;
4129 padding: 0 .2em !important;
4129 padding: 0 .2em !important;
4130 border: 1px solid #dedede !important;
4130 border: 1px solid #dedede !important;
4131 }
4131 }
4132
4132
4133 div.readme .readme_box pre code {
4133 div.readme .readme_box pre code {
4134 padding: 0 !important;
4134 padding: 0 !important;
4135 font-size: 12px !important;
4135 font-size: 12px !important;
4136 background-color: #eee !important;
4136 background-color: #eee !important;
4137 border: none !important;
4137 border: none !important;
4138 }
4138 }
4139
4139
4140 div.readme .readme_box pre {
4140 div.readme .readme_box pre {
4141 margin: 1em 0;
4141 margin: 1em 0;
4142 font-size: 12px;
4142 font-size: 12px;
4143 background-color: #eee;
4143 background-color: #eee;
4144 border: 1px solid #ddd;
4144 border: 1px solid #ddd;
4145 padding: 5px;
4145 padding: 5px;
4146 color: #444;
4146 color: #444;
4147 overflow: auto;
4147 overflow: auto;
4148 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4148 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4149 -webkit-border-radius: 3px;
4149 -webkit-border-radius: 3px;
4150 border-radius: 3px;
4150 border-radius: 3px;
4151 }
4151 }
4152
4152
4153 div.readme .readme_box table {
4153 div.readme .readme_box table {
4154 display: table;
4154 display: table;
4155 border-collapse: separate;
4155 border-collapse: separate;
4156 border-spacing: 2px;
4156 border-spacing: 2px;
4157 border-color: gray;
4157 border-color: gray;
4158 width: auto !important;
4158 width: auto !important;
4159 }
4159 }
4160
4160
4161
4161
4162 /** RST STYLE **/
4162 /** RST STYLE **/
4163
4163
4164
4164
4165 div.rst-block {
4165 div.rst-block {
4166 padding: 0px;
4166 padding: 0px;
4167 }
4167 }
4168
4168
4169 div.rst-block h2 {
4169 div.rst-block h2 {
4170 font-weight: normal;
4170 font-weight: normal;
4171 }
4171 }
4172
4172
4173 div.rst-block {
4173 div.rst-block {
4174 background-color: #fafafa;
4174 background-color: #fafafa;
4175 }
4175 }
4176
4176
4177 div.rst-block {
4177 div.rst-block {
4178 clear: both;
4178 clear: both;
4179 overflow: hidden;
4179 overflow: hidden;
4180 margin: 0;
4180 margin: 0;
4181 padding: 0 20px 10px;
4181 padding: 0 20px 10px;
4182 }
4182 }
4183
4183
4184 div.rst-block h1, div.rst-block h2, div.rst-block h3, div.rst-block h4, div.rst-block h5, div.rst-block h6 {
4184 div.rst-block h1, div.rst-block h2, div.rst-block h3, div.rst-block h4, div.rst-block h5, div.rst-block h6 {
4185 border-bottom: 0 !important;
4185 border-bottom: 0 !important;
4186 margin: 0 !important;
4186 margin: 0 !important;
4187 padding: 0 !important;
4187 padding: 0 !important;
4188 line-height: 1.5em !important;
4188 line-height: 1.5em !important;
4189 }
4189 }
4190
4190
4191
4191
4192 div.rst-block h1:first-child {
4192 div.rst-block h1:first-child {
4193 padding-top: .25em !important;
4193 padding-top: .25em !important;
4194 }
4194 }
4195
4195
4196 div.rst-block h2, div.rst-block h3 {
4196 div.rst-block h2, div.rst-block h3 {
4197 margin: 1em 0 !important;
4197 margin: 1em 0 !important;
4198 }
4198 }
4199
4199
4200 div.rst-block h2 {
4200 div.rst-block h2 {
4201 margin-top: 1.5em !important;
4201 margin-top: 1.5em !important;
4202 border-top: 4px solid #e0e0e0 !important;
4202 border-top: 4px solid #e0e0e0 !important;
4203 padding-top: .5em !important;
4203 padding-top: .5em !important;
4204 }
4204 }
4205
4205
4206 div.rst-block p {
4206 div.rst-block p {
4207 color: black !important;
4207 color: black !important;
4208 margin: 1em 0 !important;
4208 margin: 1em 0 !important;
4209 line-height: 1.5em !important;
4209 line-height: 1.5em !important;
4210 }
4210 }
4211
4211
4212 div.rst-block ul {
4212 div.rst-block ul {
4213 list-style: disc !important;
4213 list-style: disc !important;
4214 margin: 1em 0 1em 2em !important;
4214 margin: 1em 0 1em 2em !important;
4215 }
4215 }
4216
4216
4217 div.rst-block ol {
4217 div.rst-block ol {
4218 list-style: decimal;
4218 list-style: decimal;
4219 margin: 1em 0 1em 2em !important;
4219 margin: 1em 0 1em 2em !important;
4220 }
4220 }
4221
4221
4222 div.rst-block pre, code {
4222 div.rst-block pre, code {
4223 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4223 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4224 }
4224 }
4225
4225
4226 div.rst-block code {
4226 div.rst-block code {
4227 font-size: 12px !important;
4227 font-size: 12px !important;
4228 background-color: ghostWhite !important;
4228 background-color: ghostWhite !important;
4229 color: #444 !important;
4229 color: #444 !important;
4230 padding: 0 .2em !important;
4230 padding: 0 .2em !important;
4231 border: 1px solid #dedede !important;
4231 border: 1px solid #dedede !important;
4232 }
4232 }
4233
4233
4234 div.rst-block pre code {
4234 div.rst-block pre code {
4235 padding: 0 !important;
4235 padding: 0 !important;
4236 font-size: 12px !important;
4236 font-size: 12px !important;
4237 background-color: #eee !important;
4237 background-color: #eee !important;
4238 border: none !important;
4238 border: none !important;
4239 }
4239 }
4240
4240
4241 div.rst-block pre {
4241 div.rst-block pre {
4242 margin: 1em 0;
4242 margin: 1em 0;
4243 font-size: 12px;
4243 font-size: 12px;
4244 background-color: #eee;
4244 background-color: #eee;
4245 border: 1px solid #ddd;
4245 border: 1px solid #ddd;
4246 padding: 5px;
4246 padding: 5px;
4247 color: #444;
4247 color: #444;
4248 overflow: auto;
4248 overflow: auto;
4249 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4249 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4250 -webkit-border-radius: 3px;
4250 -webkit-border-radius: 3px;
4251 border-radius: 3px;
4251 border-radius: 3px;
4252 }
4252 }
4253
4253
4254
4254
4255 /** comment main **/
4255 /** comment main **/
4256 .comments {
4256 .comments {
4257 padding: 10px 20px;
4257 padding: 10px 20px;
4258 }
4258 }
4259
4259
4260 .comments .comment {
4260 .comments .comment {
4261 border: 1px solid #ddd;
4261 border: 1px solid #ddd;
4262 margin-top: 10px;
4262 margin-top: 10px;
4263 -webkit-border-radius: 4px;
4263 -webkit-border-radius: 4px;
4264 border-radius: 4px;
4264 border-radius: 4px;
4265 }
4265 }
4266
4266
4267 .comments .comment .meta {
4267 .comments .comment .meta {
4268 background: #f8f8f8;
4268 background: #f8f8f8;
4269 padding: 4px;
4269 padding: 4px;
4270 border-bottom: 1px solid #ddd;
4270 border-bottom: 1px solid #ddd;
4271 height: 18px;
4271 height: 18px;
4272 }
4272 }
4273
4273
4274 .comments .comment .meta img {
4274 .comments .comment .meta img {
4275 vertical-align: middle;
4275 vertical-align: middle;
4276 }
4276 }
4277
4277
4278 .comments .comment .meta .user {
4278 .comments .comment .meta .user {
4279 font-weight: bold;
4279 font-weight: bold;
4280 float: left;
4280 float: left;
4281 padding: 4px 2px 2px 2px;
4281 padding: 4px 2px 2px 2px;
4282 }
4282 }
4283
4283
4284 .comments .comment .meta .date {
4284 .comments .comment .meta .date {
4285 float: left;
4285 float: left;
4286 padding: 4px 4px 0px 4px;
4286 padding: 4px 4px 0px 4px;
4287 }
4287 }
4288
4288
4289 .comments .comment .text {
4289 .comments .comment .text {
4290 background-color: #FAFAFA;
4290 background-color: #FAFAFA;
4291 }
4291 }
4292 .comment .text div.rst-block p {
4292 .comment .text div.rst-block p {
4293 margin: 0.5em 0px !important;
4293 margin: 0.5em 0px !important;
4294 }
4294 }
4295
4295
4296 .comments .comments-number {
4296 .comments .comments-number {
4297 padding: 0px 0px 10px 0px;
4297 padding: 0px 0px 10px 0px;
4298 font-weight: bold;
4298 font-weight: bold;
4299 color: #666;
4299 color: #666;
4300 font-size: 16px;
4300 font-size: 16px;
4301 }
4301 }
4302
4302
4303 /** comment form **/
4303 /** comment form **/
4304
4304
4305 .status-block {
4305 .status-block {
4306 min-height: 80px;
4306 min-height: 80px;
4307 clear: both
4307 clear: both
4308 }
4308 }
4309
4309
4310
4310
4311 div.comment-form {
4311 div.comment-form {
4312 margin-top: 20px;
4312 margin-top: 20px;
4313 }
4313 }
4314
4314
4315 .comment-form strong {
4315 .comment-form strong {
4316 display: block;
4316 display: block;
4317 margin-bottom: 15px;
4317 margin-bottom: 15px;
4318 }
4318 }
4319
4319
4320 .comment-form textarea {
4320 .comment-form textarea {
4321 width: 100%;
4321 width: 100%;
4322 height: 100px;
4322 height: 100px;
4323 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4323 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4324 }
4324 }
4325
4325
4326 form.comment-form {
4326 form.comment-form {
4327 margin-top: 10px;
4327 margin-top: 10px;
4328 margin-left: 10px;
4328 margin-left: 10px;
4329 }
4329 }
4330
4330
4331 .comment-inline-form .comment-block-ta,
4331 .comment-inline-form .comment-block-ta,
4332 .comment-form .comment-block-ta {
4332 .comment-form .comment-block-ta {
4333 border: 1px solid #ccc;
4333 border: 1px solid #ccc;
4334 border-radius: 3px;
4334 border-radius: 3px;
4335 box-sizing: border-box;
4335 box-sizing: border-box;
4336 }
4336 }
4337
4337
4338 .comment-form-submit {
4338 .comment-form-submit {
4339 margin-top: 5px;
4339 margin-top: 5px;
4340 margin-left: 525px;
4340 margin-left: 525px;
4341 }
4341 }
4342
4342
4343 .file-comments {
4343 .file-comments {
4344 display: none;
4344 display: none;
4345 }
4345 }
4346
4346
4347 .comment-form .comment {
4347 .comment-form .comment {
4348 margin-left: 10px;
4348 margin-left: 10px;
4349 }
4349 }
4350
4350
4351 .comment-form .comment-help {
4351 .comment-form .comment-help {
4352 padding: 5px 5px 5px 5px;
4352 padding: 5px 5px 5px 5px;
4353 color: #666;
4353 color: #666;
4354 }
4354 }
4355 .comment-form .comment-help .preview-btn,
4355 .comment-form .comment-help .preview-btn,
4356 .comment-form .comment-help .edit-btn {
4356 .comment-form .comment-help .edit-btn {
4357 float: right;
4357 float: right;
4358 margin: -6px 0px 0px 0px;
4358 margin: -6px 0px 0px 0px;
4359 }
4359 }
4360
4360
4361 .comment-form .preview-box.unloaded,
4361 .comment-form .preview-box.unloaded,
4362 .comment-inline-form .preview-box.unloaded {
4362 .comment-inline-form .preview-box.unloaded {
4363 height: 50px;
4363 height: 50px;
4364 text-align: center;
4364 text-align: center;
4365 padding: 20px;
4365 padding: 20px;
4366 background-color: #fafafa;
4366 background-color: #fafafa;
4367 }
4367 }
4368
4368
4369 .comment-form .comment-button {
4369 .comment-form .comment-button {
4370 padding-top: 5px;
4370 padding-top: 5px;
4371 }
4371 }
4372
4372
4373 .add-another-button {
4373 .add-another-button {
4374 margin-left: 10px;
4374 margin-left: 10px;
4375 margin-top: 10px;
4375 margin-top: 10px;
4376 margin-bottom: 10px;
4376 margin-bottom: 10px;
4377 }
4377 }
4378
4378
4379 .comment .buttons {
4379 .comment .buttons {
4380 float: right;
4380 float: right;
4381 margin: -1px 0px 0px 0px;
4381 margin: -1px 0px 0px 0px;
4382 }
4382 }
4383
4383
4384
4384
4385 .show-inline-comments {
4385 .show-inline-comments {
4386 position: relative;
4386 position: relative;
4387 top: 1px
4387 top: 1px
4388 }
4388 }
4389
4389
4390 /** comment inline form **/
4390 /** comment inline form **/
4391 .comment-inline-form {
4391 .comment-inline-form {
4392 margin: 4px;
4392 margin: 4px;
4393 }
4393 }
4394 .comment-inline-form .overlay {
4394 .comment-inline-form .overlay {
4395 display: none;
4395 display: none;
4396 }
4396 }
4397 .comment-inline-form .overlay.submitting {
4397 .comment-inline-form .overlay.submitting {
4398 display: block;
4398 display: block;
4399 background: none repeat scroll 0 0 white;
4399 background: none repeat scroll 0 0 white;
4400 font-size: 16px;
4400 font-size: 16px;
4401 opacity: 0.5;
4401 opacity: 0.5;
4402 position: absolute;
4402 position: absolute;
4403 text-align: center;
4403 text-align: center;
4404 vertical-align: top;
4404 vertical-align: top;
4405
4405
4406 }
4406 }
4407 .comment-inline-form .overlay.submitting .overlay-text {
4407 .comment-inline-form .overlay.submitting .overlay-text {
4408 width: 100%;
4408 width: 100%;
4409 margin-top: 5%;
4409 margin-top: 5%;
4410 }
4410 }
4411
4411
4412 .comment-inline-form .clearfix,
4412 .comment-inline-form .clearfix,
4413 .comment-form .clearfix {
4413 .comment-form .clearfix {
4414 background: #EEE;
4414 background: #EEE;
4415 -webkit-border-radius: 4px;
4415 -webkit-border-radius: 4px;
4416 border-radius: 4px;
4416 border-radius: 4px;
4417 padding: 5px;
4417 padding: 5px;
4418 margin: 0px;
4418 margin: 0px;
4419 }
4419 }
4420
4420
4421 div.comment-inline-form {
4421 div.comment-inline-form {
4422 padding: 4px 0px 6px 0px;
4422 padding: 4px 0px 6px 0px;
4423 }
4423 }
4424
4424
4425 .comment-inline-form strong {
4425 .comment-inline-form strong {
4426 display: block;
4426 display: block;
4427 margin-bottom: 15px;
4427 margin-bottom: 15px;
4428 }
4428 }
4429
4429
4430 .comment-inline-form textarea {
4430 .comment-inline-form textarea {
4431 width: 100%;
4431 width: 100%;
4432 height: 100px;
4432 height: 100px;
4433 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4433 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4434 }
4434 }
4435
4435
4436 form.comment-inline-form {
4436 form.comment-inline-form {
4437 margin-top: 10px;
4437 margin-top: 10px;
4438 margin-left: 10px;
4438 margin-left: 10px;
4439 }
4439 }
4440
4440
4441 .comment-inline-form-submit {
4441 .comment-inline-form-submit {
4442 margin-top: 5px;
4442 margin-top: 5px;
4443 margin-left: 525px;
4443 margin-left: 525px;
4444 }
4444 }
4445
4445
4446 .file-comments {
4446 .file-comments {
4447 display: none;
4447 display: none;
4448 }
4448 }
4449
4449
4450 .comment-inline-form .comment {
4450 .comment-inline-form .comment {
4451 margin-left: 10px;
4451 margin-left: 10px;
4452 }
4452 }
4453
4453
4454 .comment-inline-form .comment-help {
4454 .comment-inline-form .comment-help {
4455 padding: 5px 5px 5px 5px;
4455 padding: 5px 5px 5px 5px;
4456 color: #666;
4456 color: #666;
4457 }
4457 }
4458
4458
4459 .comment-inline-form .comment-help .preview-btn,
4459 .comment-inline-form .comment-help .preview-btn,
4460 .comment-inline-form .comment-help .edit-btn {
4460 .comment-inline-form .comment-help .edit-btn {
4461 float: right;
4461 float: right;
4462 margin: -6px 0px 0px 0px;
4462 margin: -6px 0px 0px 0px;
4463 }
4463 }
4464
4464
4465 .comment-inline-form .comment-button {
4465 .comment-inline-form .comment-button {
4466 padding-top: 5px;
4466 padding-top: 5px;
4467 }
4467 }
4468
4468
4469 /** comment inline **/
4469 /** comment inline **/
4470 .inline-comments {
4470 .inline-comments {
4471 padding: 10px 20px;
4471 padding: 10px 20px;
4472 }
4472 }
4473
4473
4474 .inline-comments div.rst-block {
4474 .inline-comments div.rst-block {
4475 clear: both;
4475 clear: both;
4476 overflow: hidden;
4476 overflow: hidden;
4477 margin: 0;
4477 margin: 0;
4478 padding: 0 20px 0px;
4478 padding: 0 20px 0px;
4479 }
4479 }
4480 .inline-comments .comment {
4480 .inline-comments .comment {
4481 border: 1px solid #ddd;
4481 border: 1px solid #ddd;
4482 -webkit-border-radius: 4px;
4482 -webkit-border-radius: 4px;
4483 border-radius: 4px;
4483 border-radius: 4px;
4484 margin: 3px 3px 5px 5px;
4484 margin: 3px 3px 5px 5px;
4485 background-color: #FAFAFA;
4485 background-color: #FAFAFA;
4486 }
4486 }
4487 .inline-comments .add-comment {
4487 .inline-comments .add-comment {
4488 padding: 2px 4px 8px 5px;
4488 padding: 2px 4px 8px 5px;
4489 }
4489 }
4490
4490
4491 .inline-comments .comment-wrapp {
4491 .inline-comments .comment-wrapp {
4492 padding: 1px;
4492 padding: 1px;
4493 }
4493 }
4494 .inline-comments .comment .meta {
4494 .inline-comments .comment .meta {
4495 background: #f8f8f8;
4495 background: #f8f8f8;
4496 padding: 4px;
4496 padding: 4px;
4497 border-bottom: 1px solid #ddd;
4497 border-bottom: 1px solid #ddd;
4498 height: 20px;
4498 height: 20px;
4499 }
4499 }
4500
4500
4501 .inline-comments .comment .meta img {
4501 .inline-comments .comment .meta img {
4502 vertical-align: middle;
4502 vertical-align: middle;
4503 }
4503 }
4504
4504
4505 .inline-comments .comment .meta .user {
4505 .inline-comments .comment .meta .user {
4506 font-weight: bold;
4506 font-weight: bold;
4507 float: left;
4507 float: left;
4508 padding: 3px;
4508 padding: 3px;
4509 }
4509 }
4510
4510
4511 .inline-comments .comment .meta .date {
4511 .inline-comments .comment .meta .date {
4512 float: left;
4512 float: left;
4513 padding: 3px;
4513 padding: 3px;
4514 }
4514 }
4515
4515
4516 .inline-comments .comment .text {
4516 .inline-comments .comment .text {
4517 background-color: #FAFAFA;
4517 background-color: #FAFAFA;
4518 }
4518 }
4519
4519
4520 .inline-comments .comments-number {
4520 .inline-comments .comments-number {
4521 padding: 0px 0px 10px 0px;
4521 padding: 0px 0px 10px 0px;
4522 font-weight: bold;
4522 font-weight: bold;
4523 color: #666;
4523 color: #666;
4524 font-size: 16px;
4524 font-size: 16px;
4525 }
4525 }
4526 .inline-comments-button .add-comment {
4526 .inline-comments-button .add-comment {
4527 margin: 2px 0px 8px 5px !important
4527 margin: 2px 0px 8px 5px !important
4528 }
4528 }
4529
4529
4530 .notification-paginator {
4530 .notification-paginator {
4531 padding: 0px 0px 4px 16px;
4531 padding: 0px 0px 4px 16px;
4532 }
4532 }
4533
4533
4534 #context-pages .pull-request span,
4534 #context-pages .pull-request span,
4535 .menu_link_notifications {
4535 .menu_link_notifications {
4536 padding: 4px 4px !important;
4536 padding: 4px 4px !important;
4537 text-align: center;
4537 text-align: center;
4538 color: #888 !important;
4538 color: #888 !important;
4539 background-color: #DEDEDE !important;
4539 background-color: #DEDEDE !important;
4540 border-radius: 4px !important;
4540 border-radius: 4px !important;
4541 -webkit-border-radius: 4px !important;
4541 -webkit-border-radius: 4px !important;
4542 }
4542 }
4543
4543
4544 #context-pages .forks span,
4544 #context-pages .forks span,
4545 .menu_link_notifications {
4545 .menu_link_notifications {
4546 padding: 4px 4px !important;
4546 padding: 4px 4px !important;
4547 text-align: center;
4547 text-align: center;
4548 color: #888 !important;
4548 color: #888 !important;
4549 background-color: #DEDEDE !important;
4549 background-color: #DEDEDE !important;
4550 border-radius: 4px !important;
4550 border-radius: 4px !important;
4551 -webkit-border-radius: 4px !important;
4551 -webkit-border-radius: 4px !important;
4552 }
4552 }
4553
4553
4554
4554
4555 .notification-header {
4555 .notification-header {
4556 padding-top: 6px;
4556 padding-top: 6px;
4557 }
4557 }
4558 .notification-header .desc {
4558 .notification-header .desc {
4559 font-size: 16px;
4559 font-size: 16px;
4560 height: 24px;
4560 height: 24px;
4561 float: left
4561 float: left
4562 }
4562 }
4563 .notification-list .container.unread {
4563 .notification-list .container.unread {
4564 background: none repeat scroll 0 0 rgba(255, 255, 180, 0.6);
4564 background: none repeat scroll 0 0 rgba(255, 255, 180, 0.6);
4565 }
4565 }
4566 .notification-header .gravatar {
4566 .notification-header .gravatar {
4567 background: none repeat scroll 0 0 transparent;
4567 background: none repeat scroll 0 0 transparent;
4568 padding: 0px 0px 0px 8px;
4568 padding: 0px 0px 0px 8px;
4569 }
4569 }
4570 .notification-list .container .notification-header .desc {
4570 .notification-list .container .notification-header .desc {
4571 font-weight: bold;
4571 font-weight: bold;
4572 font-size: 17px;
4572 font-size: 17px;
4573 }
4573 }
4574 .notification-table {
4574 .notification-table {
4575 border: 1px solid #ccc;
4575 border: 1px solid #ccc;
4576 -webkit-border-radius: 6px 6px 6px 6px;
4576 -webkit-border-radius: 6px 6px 6px 6px;
4577 border-radius: 6px 6px 6px 6px;
4577 border-radius: 6px 6px 6px 6px;
4578 clear: both;
4578 clear: both;
4579 margin: 0px 20px 0px 20px;
4579 margin: 0px 20px 0px 20px;
4580 }
4580 }
4581 .notification-header .delete-notifications {
4581 .notification-header .delete-notifications {
4582 float: right;
4582 float: right;
4583 padding-top: 8px;
4583 padding-top: 8px;
4584 cursor: pointer;
4584 cursor: pointer;
4585 }
4585 }
4586 .notification-header .read-notifications {
4586 .notification-header .read-notifications {
4587 float: right;
4587 float: right;
4588 padding-top: 8px;
4588 padding-top: 8px;
4589 cursor: pointer;
4589 cursor: pointer;
4590 }
4590 }
4591 .notification-subject {
4591 .notification-subject {
4592 clear: both;
4592 clear: both;
4593 border-bottom: 1px solid #eee;
4593 border-bottom: 1px solid #eee;
4594 padding: 5px 0px 5px 38px;
4594 padding: 5px 0px 5px 38px;
4595 }
4595 }
4596
4596
4597 .notification-body {
4597 .notification-body {
4598 clear: both;
4598 clear: both;
4599 margin: 34px 2px 2px 8px
4599 margin: 34px 2px 2px 8px
4600 }
4600 }
4601
4601
4602 /****
4602 /****
4603 PULL REQUESTS
4603 PULL REQUESTS
4604 *****/
4604 *****/
4605 .pullrequests_section_head {
4605 .pullrequests_section_head {
4606 padding: 10px 10px 10px 0px;
4606 padding: 10px 10px 10px 0px;
4607 font-size: 16px;
4607 font-size: 16px;
4608 font-weight: bold;
4608 font-weight: bold;
4609 }
4609 }
4610
4610
4611 h3.closed,
4611 h3.closed,
4612 #pullrequests_container li.closed a
4612 #pullrequests_container li.closed a
4613 {
4613 {
4614 color: #555;
4614 color: #555;
4615 background: #eee;
4615 background: #eee;
4616 }
4616 }
4617
4617
4618 div.pr-title {
4618 div.pr-title {
4619 font-size: 1.6em;
4619 font-size: 1.6em;
4620 }
4620 }
4621
4621
4622 div.pr {
4622 div.pr {
4623 border-bottom: 1px solid #DDD;
4623 border-bottom: 1px solid #DDD;
4624 margin: 0px 20px;
4624 margin: 0px 20px;
4625 padding: 10px 4px;
4625 padding: 10px 4px;
4626 }
4626 }
4627 div.pr-closed {
4627 div.pr-closed {
4628 background-color: rgba(245,245,245,0.5);
4628 background-color: rgba(245,245,245,0.5);
4629 }
4629 }
4630
4630
4631 span.pr-closed-tag {
4631 span.pr-closed-tag {
4632 margin-bottom: 1px;
4632 margin-bottom: 1px;
4633 margin-right: 1px;
4633 margin-right: 1px;
4634 padding: 1px 3px;
4634 padding: 1px 3px;
4635 font-size: 10px;
4635 font-size: 10px;
4636 padding: 1px 3px 1px 3px;
4636 padding: 1px 3px 1px 3px;
4637 font-size: 10px;
4637 font-size: 10px;
4638 color: #336699;
4638 color: #336699;
4639 white-space: nowrap;
4639 white-space: nowrap;
4640 -webkit-border-radius: 4px;
4640 -webkit-border-radius: 4px;
4641 border-radius: 4px;
4641 border-radius: 4px;
4642 border: 1px solid #d9e8f8;
4642 border: 1px solid #d9e8f8;
4643 line-height: 1.5em;
4643 line-height: 1.5em;
4644 }
4644 }
4645
4645
4646 /****
4646 /****
4647 PERMS
4647 PERMS
4648 *****/
4648 *****/
4649 #perms .perms_section_head {
4649 #perms .perms_section_head {
4650 padding: 10px 10px 10px 0px;
4650 padding: 10px 10px 10px 0px;
4651 font-size: 16px;
4651 font-size: 16px;
4652 font-weight: bold;
4652 font-weight: bold;
4653 }
4653 }
4654
4654
4655 #perms .perm_tag {
4655 #perms .perm_tag {
4656 padding: 1px 3px 1px 3px;
4656 padding: 1px 3px 1px 3px;
4657 font-size: 10px;
4657 font-size: 10px;
4658 font-weight: bold;
4658 font-weight: bold;
4659 text-transform: uppercase;
4659 text-transform: uppercase;
4660 white-space: nowrap;
4660 white-space: nowrap;
4661 -webkit-border-radius: 3px;
4661 -webkit-border-radius: 3px;
4662 border-radius: 3px;
4662 border-radius: 3px;
4663 }
4663 }
4664
4664
4665 #perms .perm_tag.admin {
4665 #perms .perm_tag.admin {
4666 background-color: #B94A48;
4666 background-color: #B94A48;
4667 color: #ffffff;
4667 color: #ffffff;
4668 }
4668 }
4669
4669
4670 #perms .perm_tag.write {
4670 #perms .perm_tag.write {
4671 background-color: #DB7525;
4671 background-color: #DB7525;
4672 color: #ffffff;
4672 color: #ffffff;
4673 }
4673 }
4674
4674
4675 #perms .perm_tag.read {
4675 #perms .perm_tag.read {
4676 background-color: #468847;
4676 background-color: #468847;
4677 color: #ffffff;
4677 color: #ffffff;
4678 }
4678 }
4679
4679
4680 #perms .perm_tag.none {
4680 #perms .perm_tag.none {
4681 background-color: #bfbfbf;
4681 background-color: #bfbfbf;
4682 color: #ffffff;
4682 color: #ffffff;
4683 }
4683 }
4684
4684
4685 .perm-gravatar {
4685 .perm-gravatar {
4686 vertical-align: middle;
4686 vertical-align: middle;
4687 padding: 2px;
4687 padding: 2px;
4688 }
4688 }
4689 .perm-gravatar-ac {
4689 .perm-gravatar-ac {
4690 vertical-align: middle;
4690 vertical-align: middle;
4691 padding: 2px;
4691 padding: 2px;
4692 width: 14px;
4692 width: 14px;
4693 height: 14px;
4693 height: 14px;
4694 }
4694 }
4695
4695
4696 /*****************************************************************************
4696 /*****************************************************************************
4697 DIFFS CSS
4697 DIFFS CSS
4698 ******************************************************************************/
4698 ******************************************************************************/
4699 .diff-collapse {
4699 .diff-collapse {
4700 text-align: center;
4700 text-align: center;
4701 margin-bottom: -15px;
4701 margin-bottom: -15px;
4702 }
4702 }
4703 .diff-collapse-button {
4703 .diff-collapse-button {
4704 cursor: pointer;
4704 cursor: pointer;
4705 color: #666;
4705 color: #666;
4706 font-size: 16px;
4706 font-size: 16px;
4707 }
4707 }
4708 .diff-container {
4708 .diff-container {
4709
4709
4710 }
4710 }
4711
4711
4712 .diff-container.hidden {
4712 .diff-container.hidden {
4713 display: none;
4713 display: none;
4714 overflow: hidden;
4714 overflow: hidden;
4715 }
4715 }
4716
4716
4717
4717
4718 div.diffblock {
4718 div.diffblock {
4719 overflow: auto;
4719 overflow: auto;
4720 padding: 0px;
4720 padding: 0px;
4721 border: 1px solid #ccc;
4721 border: 1px solid #ccc;
4722 background: #f8f8f8;
4722 background: #f8f8f8;
4723 font-size: 100%;
4723 font-size: 100%;
4724 line-height: 100%;
4724 line-height: 100%;
4725 /* new */
4725 /* new */
4726 line-height: 125%;
4726 line-height: 125%;
4727 -webkit-border-radius: 6px 6px 0px 0px;
4727 -webkit-border-radius: 6px 6px 0px 0px;
4728 border-radius: 6px 6px 0px 0px;
4728 border-radius: 6px 6px 0px 0px;
4729 }
4729 }
4730 div.diffblock.margined {
4730 div.diffblock.margined {
4731 margin: 0px 20px 0px 20px;
4731 margin: 0px 20px 0px 20px;
4732 }
4732 }
4733 div.diffblock .code-header {
4733 div.diffblock .code-header {
4734 border-bottom: 1px solid #CCCCCC;
4734 border-bottom: 1px solid #CCCCCC;
4735 background: #EEEEEE;
4735 background: #EEEEEE;
4736 padding: 10px 0 10px 0;
4736 padding: 10px 0 10px 0;
4737 height: 14px;
4737 height: 14px;
4738 }
4738 }
4739
4739
4740 div.diffblock .code-header.banner {
4740 div.diffblock .code-header.banner {
4741 border-bottom: 1px solid #CCCCCC;
4741 border-bottom: 1px solid #CCCCCC;
4742 background: #EEEEEE;
4742 background: #EEEEEE;
4743 height: 14px;
4743 height: 14px;
4744 margin: 0px 95px 0px 95px;
4744 margin: 0px 95px 0px 95px;
4745 padding: 3px 3px 11px 3px;
4745 padding: 3px 3px 11px 3px;
4746 }
4746 }
4747
4747
4748 div.diffblock .code-header-title {
4748 div.diffblock .code-header-title {
4749 padding: 0px 0px 10px 5px !important;
4749 padding: 0px 0px 10px 5px !important;
4750 margin: 0 !important;
4750 margin: 0 !important;
4751 }
4751 }
4752 div.diffblock .code-header .hash {
4752 div.diffblock .code-header .hash {
4753 float: left;
4753 float: left;
4754 padding: 2px 0 0 2px;
4754 padding: 2px 0 0 2px;
4755 }
4755 }
4756 div.diffblock .code-header .date {
4756 div.diffblock .code-header .date {
4757 float: left;
4757 float: left;
4758 text-transform: uppercase;
4758 text-transform: uppercase;
4759 padding: 2px 0px 0px 2px;
4759 padding: 2px 0px 0px 2px;
4760 }
4760 }
4761 div.diffblock .code-header div {
4761 div.diffblock .code-header div {
4762 margin-left: 4px;
4762 margin-left: 4px;
4763 font-weight: bold;
4763 font-weight: bold;
4764 font-size: 14px;
4764 font-size: 14px;
4765 }
4765 }
4766
4766
4767 div.diffblock .parents {
4767 div.diffblock .parents {
4768 float: left;
4768 float: left;
4769 height: 26px;
4769 height: 26px;
4770 width: 100px;
4770 width: 100px;
4771 font-size: 10px;
4771 font-size: 10px;
4772 font-weight: 400;
4772 font-weight: 400;
4773 vertical-align: middle;
4773 vertical-align: middle;
4774 padding: 0px 2px 2px 2px;
4774 padding: 0px 2px 2px 2px;
4775 background-color: #eeeeee;
4775 background-color: #eeeeee;
4776 border-bottom: 1px solid #CCCCCC;
4776 border-bottom: 1px solid #CCCCCC;
4777 }
4777 }
4778
4778
4779 div.diffblock .children {
4779 div.diffblock .children {
4780 float: right;
4780 float: right;
4781 height: 26px;
4781 height: 26px;
4782 width: 100px;
4782 width: 100px;
4783 font-size: 10px;
4783 font-size: 10px;
4784 font-weight: 400;
4784 font-weight: 400;
4785 vertical-align: middle;
4785 vertical-align: middle;
4786 text-align: right;
4786 text-align: right;
4787 padding: 0px 2px 2px 2px;
4787 padding: 0px 2px 2px 2px;
4788 background-color: #eeeeee;
4788 background-color: #eeeeee;
4789 border-bottom: 1px solid #CCCCCC;
4789 border-bottom: 1px solid #CCCCCC;
4790 }
4790 }
4791
4791
4792 div.diffblock .code-body {
4792 div.diffblock .code-body {
4793 background: #FFFFFF;
4793 background: #FFFFFF;
4794 }
4794 }
4795 div.diffblock pre.raw {
4795 div.diffblock pre.raw {
4796 background: #FFFFFF;
4796 background: #FFFFFF;
4797 color: #000000;
4797 color: #000000;
4798 }
4798 }
4799 table.code-difftable {
4799 table.code-difftable {
4800 border-collapse: collapse;
4800 border-collapse: collapse;
4801 width: 99%;
4801 width: 99%;
4802 border-radius: 0px !important;
4802 border-radius: 0px !important;
4803 }
4803 }
4804 table.code-difftable td {
4804 table.code-difftable td {
4805 padding: 0 !important;
4805 padding: 0 !important;
4806 background: none !important;
4806 background: none !important;
4807 border: 0 !important;
4807 border: 0 !important;
4808 vertical-align: baseline !important
4808 vertical-align: baseline !important
4809 }
4809 }
4810 table.code-difftable .context {
4810 table.code-difftable .context {
4811 background: none repeat scroll 0 0 #DDE7EF;
4811 background: none repeat scroll 0 0 #DDE7EF;
4812 }
4812 }
4813 table.code-difftable .add {
4813 table.code-difftable .add {
4814 background: none repeat scroll 0 0 #DDFFDD;
4814 background: none repeat scroll 0 0 #DDFFDD;
4815 }
4815 }
4816 table.code-difftable .add ins {
4816 table.code-difftable .add ins {
4817 background: none repeat scroll 0 0 #AAFFAA;
4817 background: none repeat scroll 0 0 #AAFFAA;
4818 text-decoration: none;
4818 text-decoration: none;
4819 }
4819 }
4820 table.code-difftable .del {
4820 table.code-difftable .del {
4821 background: none repeat scroll 0 0 #FFDDDD;
4821 background: none repeat scroll 0 0 #FFDDDD;
4822 }
4822 }
4823 table.code-difftable .del del {
4823 table.code-difftable .del del {
4824 background: none repeat scroll 0 0 #FFAAAA;
4824 background: none repeat scroll 0 0 #FFAAAA;
4825 text-decoration: none;
4825 text-decoration: none;
4826 }
4826 }
4827
4827
4828 /** LINE NUMBERS **/
4828 /** LINE NUMBERS **/
4829 table.code-difftable .lineno {
4829 table.code-difftable .lineno {
4830
4830
4831 padding-left: 2px;
4831 padding-left: 2px;
4832 padding-right: 2px;
4832 padding-right: 2px;
4833 text-align: right;
4833 text-align: right;
4834 width: 32px;
4834 width: 32px;
4835 -moz-user-select: none;
4835 -moz-user-select: none;
4836 -webkit-user-select: none;
4836 -webkit-user-select: none;
4837 border-right: 1px solid #CCC !important;
4837 border-right: 1px solid #CCC !important;
4838 border-left: 0px solid #CCC !important;
4838 border-left: 0px solid #CCC !important;
4839 border-top: 0px solid #CCC !important;
4839 border-top: 0px solid #CCC !important;
4840 border-bottom: none !important;
4840 border-bottom: none !important;
4841 vertical-align: middle !important;
4841 vertical-align: middle !important;
4842
4842
4843 }
4843 }
4844 table.code-difftable .lineno.new {
4844 table.code-difftable .lineno.new {
4845 }
4845 }
4846 table.code-difftable .lineno.old {
4846 table.code-difftable .lineno.old {
4847 }
4847 }
4848 table.code-difftable .lineno a {
4848 table.code-difftable .lineno a {
4849 color: #747474 !important;
4849 color: #747474 !important;
4850 font: 11px "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace !important;
4850 font: 11px "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace !important;
4851 letter-spacing: -1px;
4851 letter-spacing: -1px;
4852 text-align: right;
4852 text-align: right;
4853 padding-right: 2px;
4853 padding-right: 2px;
4854 cursor: pointer;
4854 cursor: pointer;
4855 display: block;
4855 display: block;
4856 width: 32px;
4856 width: 32px;
4857 }
4857 }
4858
4858
4859 table.code-difftable .lineno-inline {
4859 table.code-difftable .lineno-inline {
4860 background: none repeat scroll 0 0 #FFF !important;
4860 background: none repeat scroll 0 0 #FFF !important;
4861 padding-left: 2px;
4861 padding-left: 2px;
4862 padding-right: 2px;
4862 padding-right: 2px;
4863 text-align: right;
4863 text-align: right;
4864 width: 30px;
4864 width: 30px;
4865 -moz-user-select: none;
4865 -moz-user-select: none;
4866 -webkit-user-select: none;
4866 -webkit-user-select: none;
4867 }
4867 }
4868
4868
4869 /** CODE **/
4869 /** CODE **/
4870 table.code-difftable .code {
4870 table.code-difftable .code {
4871 display: block;
4871 display: block;
4872 width: 100%;
4872 width: 100%;
4873 }
4873 }
4874 table.code-difftable .code td {
4874 table.code-difftable .code td {
4875 margin: 0;
4875 margin: 0;
4876 padding: 0;
4876 padding: 0;
4877 }
4877 }
4878 table.code-difftable .code pre {
4878 table.code-difftable .code pre {
4879 margin: 0;
4879 margin: 0;
4880 padding: 0;
4880 padding: 0;
4881 height: 17px;
4881 height: 17px;
4882 line-height: 17px;
4882 line-height: 17px;
4883 }
4883 }
4884
4884
4885
4885
4886 .diffblock.margined.comm .line .code:hover {
4886 .diffblock.margined.comm .line .code:hover {
4887 background-color: #FFFFCC !important;
4887 background-color: #FFFFCC !important;
4888 cursor: pointer !important;
4888 cursor: pointer !important;
4889 background-image: url("../images/icons/comment_add.png") !important;
4889 background-image: url("../images/icons/comment_add.png") !important;
4890 background-repeat: no-repeat !important;
4890 background-repeat: no-repeat !important;
4891 background-position: right !important;
4891 background-position: right !important;
4892 background-position: 0% 50% !important;
4892 background-position: 0% 50% !important;
4893 }
4893 }
4894 .diffblock.margined.comm .line .code.no-comment:hover {
4894 .diffblock.margined.comm .line .code.no-comment:hover {
4895 background-image: none !important;
4895 background-image: none !important;
4896 cursor: auto !important;
4896 cursor: auto !important;
4897 background-color: inherit !important;
4897 background-color: inherit !important;
4898 }
4898 }
4899
4899
4900 div.comment:target>.comment-wrapp {
4900 div.comment:target>.comment-wrapp {
4901 border: solid 2px #ee0 !important;
4901 border: solid 2px #ee0 !important;
4902 }
4902 }
4903
4903
4904 .lineno:target a {
4904 .lineno:target a {
4905 border: solid 2px #ee0 !important;
4905 border: solid 2px #ee0 !important;
4906 margin: -2px;
4906 margin: -2px;
4907 }
4907 }
@@ -1,2229 +1,2512 b''
1 /**
1 /**
2 RhodeCode JS Files
2 RhodeCode JS Files
3 **/
3 **/
4
4
5 if (typeof console == "undefined" || typeof console.log == "undefined"){
5 if (typeof console == "undefined" || typeof console.log == "undefined"){
6 console = { log: function() {} }
6 console = { log: function() {} }
7 }
7 }
8
8
9
9
10 var str_repeat = function(i, m) {
10 var str_repeat = function(i, m) {
11 for (var o = []; m > 0; o[--m] = i);
11 for (var o = []; m > 0; o[--m] = i);
12 return o.join('');
12 return o.join('');
13 };
13 };
14
14
15 /**
15 /**
16 * INJECT .format function into String
16 * INJECT .format function into String
17 * Usage: "My name is {0} {1}".format("Johny","Bravo")
17 * Usage: "My name is {0} {1}".format("Johny","Bravo")
18 * Return "My name is Johny Bravo"
18 * Return "My name is Johny Bravo"
19 * Inspired by https://gist.github.com/1049426
19 * Inspired by https://gist.github.com/1049426
20 */
20 */
21 String.prototype.format = function() {
21 String.prototype.format = function() {
22
22
23 function format() {
23 function format() {
24 var str = this;
24 var str = this;
25 var len = arguments.length+1;
25 var len = arguments.length+1;
26 var safe = undefined;
26 var safe = undefined;
27 var arg = undefined;
27 var arg = undefined;
28
28
29 // For each {0} {1} {n...} replace with the argument in that position. If
29 // For each {0} {1} {n...} replace with the argument in that position. If
30 // the argument is an object or an array it will be stringified to JSON.
30 // the argument is an object or an array it will be stringified to JSON.
31 for (var i=0; i < len; arg = arguments[i++]) {
31 for (var i=0; i < len; arg = arguments[i++]) {
32 safe = typeof arg === 'object' ? JSON.stringify(arg) : arg;
32 safe = typeof arg === 'object' ? JSON.stringify(arg) : arg;
33 str = str.replace(RegExp('\\{'+(i-1)+'\\}', 'g'), safe);
33 str = str.replace(RegExp('\\{'+(i-1)+'\\}', 'g'), safe);
34 }
34 }
35 return str;
35 return str;
36 }
36 }
37
37
38 // Save a reference of what may already exist under the property native.
38 // Save a reference of what may already exist under the property native.
39 // Allows for doing something like: if("".format.native) { /* use native */ }
39 // Allows for doing something like: if("".format.native) { /* use native */ }
40 format.native = String.prototype.format;
40 format.native = String.prototype.format;
41
41
42 // Replace the prototype property
42 // Replace the prototype property
43 return format;
43 return format;
44
44
45 }();
45 }();
46
46
47 String.prototype.strip = function(char) {
47 String.prototype.strip = function(char) {
48 if(char === undefined){
48 if(char === undefined){
49 char = '\\s';
49 char = '\\s';
50 }
50 }
51 return this.replace(new RegExp('^'+char+'+|'+char+'+$','g'), '');
51 return this.replace(new RegExp('^'+char+'+|'+char+'+$','g'), '');
52 }
52 }
53 String.prototype.lstrip = function(char) {
53 String.prototype.lstrip = function(char) {
54 if(char === undefined){
54 if(char === undefined){
55 char = '\\s';
55 char = '\\s';
56 }
56 }
57 return this.replace(new RegExp('^'+char+'+'),'');
57 return this.replace(new RegExp('^'+char+'+'),'');
58 }
58 }
59 String.prototype.rstrip = function(char) {
59 String.prototype.rstrip = function(char) {
60 if(char === undefined){
60 if(char === undefined){
61 char = '\\s';
61 char = '\\s';
62 }
62 }
63 return this.replace(new RegExp(''+char+'+$'),'');
63 return this.replace(new RegExp(''+char+'+$'),'');
64 }
64 }
65
65
66
66
67 if(!Array.prototype.indexOf) {
67 if(!Array.prototype.indexOf) {
68 Array.prototype.indexOf = function(needle) {
68 Array.prototype.indexOf = function(needle) {
69 for(var i = 0; i < this.length; i++) {
69 for(var i = 0; i < this.length; i++) {
70 if(this[i] === needle) {
70 if(this[i] === needle) {
71 return i;
71 return i;
72 }
72 }
73 }
73 }
74 return -1;
74 return -1;
75 };
75 };
76 }
76 }
77
77
78 // IE(CRAP) doesn't support previousElementSibling
78 // IE(CRAP) doesn't support previousElementSibling
79 var prevElementSibling = function( el ) {
79 var prevElementSibling = function( el ) {
80 if( el.previousElementSibling ) {
80 if( el.previousElementSibling ) {
81 return el.previousElementSibling;
81 return el.previousElementSibling;
82 } else {
82 } else {
83 while( el = el.previousSibling ) {
83 while( el = el.previousSibling ) {
84 if( el.nodeType === 1 ) return el;
84 if( el.nodeType === 1 ) return el;
85 }
85 }
86 }
86 }
87 }
87 }
88
88
89 /**
89 /**
90 * SmartColorGenerator
90 * SmartColorGenerator
91 *
91 *
92 *usage::
92 *usage::
93 * var CG = new ColorGenerator();
93 * var CG = new ColorGenerator();
94 * var col = CG.getColor(key); //returns array of RGB
94 * var col = CG.getColor(key); //returns array of RGB
95 * 'rgb({0})'.format(col.join(',')
95 * 'rgb({0})'.format(col.join(',')
96 *
96 *
97 * @returns {ColorGenerator}
97 * @returns {ColorGenerator}
98 */
98 */
99 var ColorGenerator = function(){
99 var ColorGenerator = function(){
100 this.GOLDEN_RATIO = 0.618033988749895;
100 this.GOLDEN_RATIO = 0.618033988749895;
101 this.CURRENT_RATIO = 0.22717784590367374 // this can be random
101 this.CURRENT_RATIO = 0.22717784590367374 // this can be random
102 this.HSV_1 = 0.75;//saturation
102 this.HSV_1 = 0.75;//saturation
103 this.HSV_2 = 0.95;
103 this.HSV_2 = 0.95;
104 this.color;
104 this.color;
105 this.cacheColorMap = {};
105 this.cacheColorMap = {};
106 };
106 };
107
107
108 ColorGenerator.prototype = {
108 ColorGenerator.prototype = {
109 getColor:function(key){
109 getColor:function(key){
110 if(this.cacheColorMap[key] !== undefined){
110 if(this.cacheColorMap[key] !== undefined){
111 return this.cacheColorMap[key];
111 return this.cacheColorMap[key];
112 }
112 }
113 else{
113 else{
114 this.cacheColorMap[key] = this.generateColor();
114 this.cacheColorMap[key] = this.generateColor();
115 return this.cacheColorMap[key];
115 return this.cacheColorMap[key];
116 }
116 }
117 },
117 },
118 _hsvToRgb:function(h,s,v){
118 _hsvToRgb:function(h,s,v){
119 if (s == 0.0)
119 if (s == 0.0)
120 return [v, v, v];
120 return [v, v, v];
121 i = parseInt(h * 6.0)
121 i = parseInt(h * 6.0)
122 f = (h * 6.0) - i
122 f = (h * 6.0) - i
123 p = v * (1.0 - s)
123 p = v * (1.0 - s)
124 q = v * (1.0 - s * f)
124 q = v * (1.0 - s * f)
125 t = v * (1.0 - s * (1.0 - f))
125 t = v * (1.0 - s * (1.0 - f))
126 i = i % 6
126 i = i % 6
127 if (i == 0)
127 if (i == 0)
128 return [v, t, p]
128 return [v, t, p]
129 if (i == 1)
129 if (i == 1)
130 return [q, v, p]
130 return [q, v, p]
131 if (i == 2)
131 if (i == 2)
132 return [p, v, t]
132 return [p, v, t]
133 if (i == 3)
133 if (i == 3)
134 return [p, q, v]
134 return [p, q, v]
135 if (i == 4)
135 if (i == 4)
136 return [t, p, v]
136 return [t, p, v]
137 if (i == 5)
137 if (i == 5)
138 return [v, p, q]
138 return [v, p, q]
139 },
139 },
140 generateColor:function(){
140 generateColor:function(){
141 this.CURRENT_RATIO = this.CURRENT_RATIO+this.GOLDEN_RATIO;
141 this.CURRENT_RATIO = this.CURRENT_RATIO+this.GOLDEN_RATIO;
142 this.CURRENT_RATIO = this.CURRENT_RATIO %= 1;
142 this.CURRENT_RATIO = this.CURRENT_RATIO %= 1;
143 HSV_tuple = [this.CURRENT_RATIO, this.HSV_1, this.HSV_2]
143 HSV_tuple = [this.CURRENT_RATIO, this.HSV_1, this.HSV_2]
144 RGB_tuple = this._hsvToRgb(HSV_tuple[0],HSV_tuple[1],HSV_tuple[2]);
144 RGB_tuple = this._hsvToRgb(HSV_tuple[0],HSV_tuple[1],HSV_tuple[2]);
145 function toRgb(v){
145 function toRgb(v){
146 return ""+parseInt(v*256)
146 return ""+parseInt(v*256)
147 }
147 }
148 return [toRgb(RGB_tuple[0]),toRgb(RGB_tuple[1]),toRgb(RGB_tuple[2])];
148 return [toRgb(RGB_tuple[0]),toRgb(RGB_tuple[1]),toRgb(RGB_tuple[2])];
149
149
150 }
150 }
151 }
151 }
152
152
153 /**
153 /**
154 * PyRoutesJS
154 * PyRoutesJS
155 *
155 *
156 * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id>
156 * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id>
157 */
157 */
158 var pyroutes = (function() {
158 var pyroutes = (function() {
159 // access global map defined in special file pyroutes
159 // access global map defined in special file pyroutes
160 var matchlist = PROUTES_MAP;
160 var matchlist = PROUTES_MAP;
161 var sprintf = (function() {
161 var sprintf = (function() {
162 function get_type(variable) {
162 function get_type(variable) {
163 return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
163 return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
164 }
164 }
165 function str_repeat(input, multiplier) {
165 function str_repeat(input, multiplier) {
166 for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
166 for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
167 return output.join('');
167 return output.join('');
168 }
168 }
169
169
170 var str_format = function() {
170 var str_format = function() {
171 if (!str_format.cache.hasOwnProperty(arguments[0])) {
171 if (!str_format.cache.hasOwnProperty(arguments[0])) {
172 str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
172 str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
173 }
173 }
174 return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
174 return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
175 };
175 };
176
176
177 str_format.format = function(parse_tree, argv) {
177 str_format.format = function(parse_tree, argv) {
178 var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
178 var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
179 for (i = 0; i < tree_length; i++) {
179 for (i = 0; i < tree_length; i++) {
180 node_type = get_type(parse_tree[i]);
180 node_type = get_type(parse_tree[i]);
181 if (node_type === 'string') {
181 if (node_type === 'string') {
182 output.push(parse_tree[i]);
182 output.push(parse_tree[i]);
183 }
183 }
184 else if (node_type === 'array') {
184 else if (node_type === 'array') {
185 match = parse_tree[i]; // convenience purposes only
185 match = parse_tree[i]; // convenience purposes only
186 if (match[2]) { // keyword argument
186 if (match[2]) { // keyword argument
187 arg = argv[cursor];
187 arg = argv[cursor];
188 for (k = 0; k < match[2].length; k++) {
188 for (k = 0; k < match[2].length; k++) {
189 if (!arg.hasOwnProperty(match[2][k])) {
189 if (!arg.hasOwnProperty(match[2][k])) {
190 throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
190 throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
191 }
191 }
192 arg = arg[match[2][k]];
192 arg = arg[match[2][k]];
193 }
193 }
194 }
194 }
195 else if (match[1]) { // positional argument (explicit)
195 else if (match[1]) { // positional argument (explicit)
196 arg = argv[match[1]];
196 arg = argv[match[1]];
197 }
197 }
198 else { // positional argument (implicit)
198 else { // positional argument (implicit)
199 arg = argv[cursor++];
199 arg = argv[cursor++];
200 }
200 }
201
201
202 if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
202 if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
203 throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
203 throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
204 }
204 }
205 switch (match[8]) {
205 switch (match[8]) {
206 case 'b': arg = arg.toString(2); break;
206 case 'b': arg = arg.toString(2); break;
207 case 'c': arg = String.fromCharCode(arg); break;
207 case 'c': arg = String.fromCharCode(arg); break;
208 case 'd': arg = parseInt(arg, 10); break;
208 case 'd': arg = parseInt(arg, 10); break;
209 case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
209 case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
210 case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
210 case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
211 case 'o': arg = arg.toString(8); break;
211 case 'o': arg = arg.toString(8); break;
212 case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
212 case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
213 case 'u': arg = Math.abs(arg); break;
213 case 'u': arg = Math.abs(arg); break;
214 case 'x': arg = arg.toString(16); break;
214 case 'x': arg = arg.toString(16); break;
215 case 'X': arg = arg.toString(16).toUpperCase(); break;
215 case 'X': arg = arg.toString(16).toUpperCase(); break;
216 }
216 }
217 arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
217 arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
218 pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
218 pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
219 pad_length = match[6] - String(arg).length;
219 pad_length = match[6] - String(arg).length;
220 pad = match[6] ? str_repeat(pad_character, pad_length) : '';
220 pad = match[6] ? str_repeat(pad_character, pad_length) : '';
221 output.push(match[5] ? arg + pad : pad + arg);
221 output.push(match[5] ? arg + pad : pad + arg);
222 }
222 }
223 }
223 }
224 return output.join('');
224 return output.join('');
225 };
225 };
226
226
227 str_format.cache = {};
227 str_format.cache = {};
228
228
229 str_format.parse = function(fmt) {
229 str_format.parse = function(fmt) {
230 var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
230 var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
231 while (_fmt) {
231 while (_fmt) {
232 if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
232 if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
233 parse_tree.push(match[0]);
233 parse_tree.push(match[0]);
234 }
234 }
235 else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
235 else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
236 parse_tree.push('%');
236 parse_tree.push('%');
237 }
237 }
238 else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
238 else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
239 if (match[2]) {
239 if (match[2]) {
240 arg_names |= 1;
240 arg_names |= 1;
241 var field_list = [], replacement_field = match[2], field_match = [];
241 var field_list = [], replacement_field = match[2], field_match = [];
242 if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
242 if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
243 field_list.push(field_match[1]);
243 field_list.push(field_match[1]);
244 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
244 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
245 if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
245 if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
246 field_list.push(field_match[1]);
246 field_list.push(field_match[1]);
247 }
247 }
248 else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
248 else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
249 field_list.push(field_match[1]);
249 field_list.push(field_match[1]);
250 }
250 }
251 else {
251 else {
252 throw('[sprintf] huh?');
252 throw('[sprintf] huh?');
253 }
253 }
254 }
254 }
255 }
255 }
256 else {
256 else {
257 throw('[sprintf] huh?');
257 throw('[sprintf] huh?');
258 }
258 }
259 match[2] = field_list;
259 match[2] = field_list;
260 }
260 }
261 else {
261 else {
262 arg_names |= 2;
262 arg_names |= 2;
263 }
263 }
264 if (arg_names === 3) {
264 if (arg_names === 3) {
265 throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
265 throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
266 }
266 }
267 parse_tree.push(match);
267 parse_tree.push(match);
268 }
268 }
269 else {
269 else {
270 throw('[sprintf] huh?');
270 throw('[sprintf] huh?');
271 }
271 }
272 _fmt = _fmt.substring(match[0].length);
272 _fmt = _fmt.substring(match[0].length);
273 }
273 }
274 return parse_tree;
274 return parse_tree;
275 };
275 };
276
276
277 return str_format;
277 return str_format;
278 })();
278 })();
279
279
280 var vsprintf = function(fmt, argv) {
280 var vsprintf = function(fmt, argv) {
281 argv.unshift(fmt);
281 argv.unshift(fmt);
282 return sprintf.apply(null, argv);
282 return sprintf.apply(null, argv);
283 };
283 };
284 return {
284 return {
285 'url': function(route_name, params) {
285 'url': function(route_name, params) {
286 var result = route_name;
286 var result = route_name;
287 if (typeof(params) != 'object'){
287 if (typeof(params) != 'object'){
288 params = {};
288 params = {};
289 }
289 }
290 if (matchlist.hasOwnProperty(route_name)) {
290 if (matchlist.hasOwnProperty(route_name)) {
291 var route = matchlist[route_name];
291 var route = matchlist[route_name];
292 // param substitution
292 // param substitution
293 for(var i=0; i < route[1].length; i++) {
293 for(var i=0; i < route[1].length; i++) {
294
294
295 if (!params.hasOwnProperty(route[1][i]))
295 if (!params.hasOwnProperty(route[1][i]))
296 throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation');
296 throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation');
297 }
297 }
298 result = sprintf(route[0], params);
298 result = sprintf(route[0], params);
299
299
300 var ret = [];
300 var ret = [];
301 //extra params => GET
301 //extra params => GET
302 for(param in params){
302 for(param in params){
303 if (route[1].indexOf(param) == -1){
303 if (route[1].indexOf(param) == -1){
304 ret.push(encodeURIComponent(param) + "=" + encodeURIComponent(params[param]));
304 ret.push(encodeURIComponent(param) + "=" + encodeURIComponent(params[param]));
305 }
305 }
306 }
306 }
307 var _parts = ret.join("&");
307 var _parts = ret.join("&");
308 if(_parts){
308 if(_parts){
309 result = result +'?'+ _parts
309 result = result +'?'+ _parts
310 }
310 }
311 }
311 }
312
312
313 return result;
313 return result;
314 },
314 },
315 'register': function(route_name, route_tmpl, req_params) {
315 'register': function(route_name, route_tmpl, req_params) {
316 if (typeof(req_params) != 'object') {
316 if (typeof(req_params) != 'object') {
317 req_params = [];
317 req_params = [];
318 }
318 }
319 //fix escape
319 //fix escape
320 route_tmpl = unescape(route_tmpl);
320 route_tmpl = unescape(route_tmpl);
321 keys = [];
321 keys = [];
322 for (o in req_params){
322 for (o in req_params){
323 keys.push(req_params[o])
323 keys.push(req_params[o])
324 }
324 }
325 matchlist[route_name] = [
325 matchlist[route_name] = [
326 route_tmpl,
326 route_tmpl,
327 keys
327 keys
328 ]
328 ]
329 },
329 },
330 '_routes': function(){
330 '_routes': function(){
331 return matchlist;
331 return matchlist;
332 }
332 }
333 }
333 }
334 })();
334 })();
335
335
336
336
337
337
338 /**
338 /**
339 * GLOBAL YUI Shortcuts
339 * GLOBAL YUI Shortcuts
340 */
340 */
341 var YUC = YAHOO.util.Connect;
341 var YUC = YAHOO.util.Connect;
342 var YUD = YAHOO.util.Dom;
342 var YUD = YAHOO.util.Dom;
343 var YUE = YAHOO.util.Event;
343 var YUE = YAHOO.util.Event;
344 var YUQ = YAHOO.util.Selector.query;
344 var YUQ = YAHOO.util.Selector.query;
345
345
346 // defines if push state is enabled for this browser ?
346 // defines if push state is enabled for this browser ?
347 var push_state_enabled = Boolean(
347 var push_state_enabled = Boolean(
348 window.history && window.history.pushState && window.history.replaceState
348 window.history && window.history.pushState && window.history.replaceState
349 && !( /* disable for versions of iOS before version 4.3 (8F190) */
349 && !( /* disable for versions of iOS before version 4.3 (8F190) */
350 (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent)
350 (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent)
351 /* disable for the mercury iOS browser, or at least older versions of the webkit engine */
351 /* disable for the mercury iOS browser, or at least older versions of the webkit engine */
352 || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent)
352 || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent)
353 )
353 )
354 );
354 );
355
355
356 var _run_callbacks = function(callbacks){
356 var _run_callbacks = function(callbacks){
357 if (callbacks !== undefined){
357 if (callbacks !== undefined){
358 var _l = callbacks.length;
358 var _l = callbacks.length;
359 for (var i=0;i<_l;i++){
359 for (var i=0;i<_l;i++){
360 var func = callbacks[i];
360 var func = callbacks[i];
361 if(typeof(func)=='function'){
361 if(typeof(func)=='function'){
362 try{
362 try{
363 func();
363 func();
364 }catch (err){};
364 }catch (err){};
365 }
365 }
366 }
366 }
367 }
367 }
368 }
368 }
369
369
370 /**
370 /**
371 * turns objects into GET query string
371 * turns objects into GET query string
372 */
372 */
373 var toQueryString = function(o) {
373 var toQueryString = function(o) {
374 if(typeof o !== 'object') {
374 if(typeof o !== 'object') {
375 return false;
375 return false;
376 }
376 }
377 var _p, _qs = [];
377 var _p, _qs = [];
378 for(_p in o) {
378 for(_p in o) {
379 _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
379 _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
380 }
380 }
381 return _qs.join('&');
381 return _qs.join('&');
382 };
382 };
383
383
384 /**
384 /**
385 * Partial Ajax Implementation
385 * Partial Ajax Implementation
386 *
386 *
387 * @param url: defines url to make partial request
387 * @param url: defines url to make partial request
388 * @param container: defines id of container to input partial result
388 * @param container: defines id of container to input partial result
389 * @param s_call: success callback function that takes o as arg
389 * @param s_call: success callback function that takes o as arg
390 * o.tId
390 * o.tId
391 * o.status
391 * o.status
392 * o.statusText
392 * o.statusText
393 * o.getResponseHeader[ ]
393 * o.getResponseHeader[ ]
394 * o.getAllResponseHeaders
394 * o.getAllResponseHeaders
395 * o.responseText
395 * o.responseText
396 * o.responseXML
396 * o.responseXML
397 * o.argument
397 * o.argument
398 * @param f_call: failure callback
398 * @param f_call: failure callback
399 * @param args arguments
399 * @param args arguments
400 */
400 */
401 function ypjax(url,container,s_call,f_call,args){
401 function ypjax(url,container,s_call,f_call,args){
402 var method='GET';
402 var method='GET';
403 if(args===undefined){
403 if(args===undefined){
404 args=null;
404 args=null;
405 }
405 }
406
406
407 // Set special header for partial ajax == HTTP_X_PARTIAL_XHR
407 // Set special header for partial ajax == HTTP_X_PARTIAL_XHR
408 YUC.initHeader('X-PARTIAL-XHR',true);
408 YUC.initHeader('X-PARTIAL-XHR',true);
409
409
410 // wrapper of passed callback
410 // wrapper of passed callback
411 var s_wrapper = (function(o){
411 var s_wrapper = (function(o){
412 return function(o){
412 return function(o){
413 YUD.get(container).innerHTML=o.responseText;
413 YUD.get(container).innerHTML=o.responseText;
414 YUD.setStyle(container,'opacity','1.0');
414 YUD.setStyle(container,'opacity','1.0');
415 //execute the given original callback
415 //execute the given original callback
416 if (s_call !== undefined){
416 if (s_call !== undefined){
417 s_call(o);
417 s_call(o);
418 }
418 }
419 }
419 }
420 })()
420 })()
421 YUD.setStyle(container,'opacity','0.3');
421 YUD.setStyle(container,'opacity','0.3');
422 YUC.asyncRequest(method,url,{
422 YUC.asyncRequest(method,url,{
423 success:s_wrapper,
423 success:s_wrapper,
424 failure:function(o){
424 failure:function(o){
425 console.log(o);
425 console.log(o);
426 YUD.get(container).innerHTML='<span class="error_red">ERROR: {0}</span>'.format(o.status);
426 YUD.get(container).innerHTML='<span class="error_red">ERROR: {0}</span>'.format(o.status);
427 YUD.setStyle(container,'opacity','1.0');
427 YUD.setStyle(container,'opacity','1.0');
428 },
428 },
429 cache:false
429 cache:false
430 },args);
430 },args);
431
431
432 };
432 };
433
433
434 var ajaxGET = function(url,success) {
434 var ajaxGET = function(url,success) {
435 // Set special header for ajax == HTTP_X_PARTIAL_XHR
435 // Set special header for ajax == HTTP_X_PARTIAL_XHR
436 YUC.initHeader('X-PARTIAL-XHR',true);
436 YUC.initHeader('X-PARTIAL-XHR',true);
437
437
438 var sUrl = url;
438 var sUrl = url;
439 var callback = {
439 var callback = {
440 success: success,
440 success: success,
441 failure: function (o) {
441 failure: function (o) {
442 if (o.status != 0) {
442 if (o.status != 0) {
443 alert("error: " + o.statusText);
443 alert("error: " + o.statusText);
444 };
444 };
445 },
445 },
446 };
446 };
447
447
448 var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
448 var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
449 return request;
449 return request;
450 };
450 };
451
451
452
452
453
453
454 var ajaxPOST = function(url,postData,success) {
454 var ajaxPOST = function(url,postData,success) {
455 // Set special header for ajax == HTTP_X_PARTIAL_XHR
455 // Set special header for ajax == HTTP_X_PARTIAL_XHR
456 YUC.initHeader('X-PARTIAL-XHR',true);
456 YUC.initHeader('X-PARTIAL-XHR',true);
457
457
458 var sUrl = url;
458 var sUrl = url;
459 var callback = {
459 var callback = {
460 success: success,
460 success: success,
461 failure: function (o) {
461 failure: function (o) {
462 alert("error");
462 alert("error");
463 },
463 },
464 };
464 };
465 var postData = toQueryString(postData);
465 var postData = toQueryString(postData);
466 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
466 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
467 return request;
467 return request;
468 };
468 };
469
469
470
470
471 /**
471 /**
472 * tooltip activate
472 * tooltip activate
473 */
473 */
474 var tooltip_activate = function(){
474 var tooltip_activate = function(){
475 yt = YAHOO.yuitip.main;
475 yt = YAHOO.yuitip.main;
476 YUE.onDOMReady(yt.init);
476 YUE.onDOMReady(yt.init);
477 };
477 };
478
478
479 /**
479 /**
480 * show more
480 * show more
481 */
481 */
482 var show_more_event = function(){
482 var show_more_event = function(){
483 YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
483 YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
484 var el = e.target;
484 var el = e.target;
485 YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
485 YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
486 YUD.setStyle(el.parentNode,'display','none');
486 YUD.setStyle(el.parentNode,'display','none');
487 });
487 });
488 };
488 };
489
489
490 /**
490 /**
491 * show changeset tooltip
491 * show changeset tooltip
492 */
492 */
493 var show_changeset_tooltip = function(){
493 var show_changeset_tooltip = function(){
494 YUE.on(YUD.getElementsByClassName('lazy-cs'), 'mouseover', function(e){
494 YUE.on(YUD.getElementsByClassName('lazy-cs'), 'mouseover', function(e){
495 var target = e.currentTarget;
495 var target = e.currentTarget;
496 var rid = YUD.getAttribute(target,'raw_id');
496 var rid = YUD.getAttribute(target,'raw_id');
497 var repo_name = YUD.getAttribute(target,'repo_name');
497 var repo_name = YUD.getAttribute(target,'repo_name');
498 var ttid = 'tt-'+rid;
498 var ttid = 'tt-'+rid;
499 var success = function(o){
499 var success = function(o){
500 var json = JSON.parse(o.responseText);
500 var json = JSON.parse(o.responseText);
501 YUD.addClass(target,'tooltip')
501 YUD.addClass(target,'tooltip')
502 YUD.setAttribute(target, 'title',json['message']);
502 YUD.setAttribute(target, 'title',json['message']);
503 YAHOO.yuitip.main.show_yuitip(e, target);
503 YAHOO.yuitip.main.show_yuitip(e, target);
504 }
504 }
505 if(rid && !YUD.hasClass(target, 'tooltip')){
505 if(rid && !YUD.hasClass(target, 'tooltip')){
506 YUD.setAttribute(target,'id',ttid);
506 YUD.setAttribute(target,'id',ttid);
507 YUD.setAttribute(target, 'title',_TM['loading...']);
507 YUD.setAttribute(target, 'title',_TM['loading...']);
508 YAHOO.yuitip.main.set_listeners(target);
508 YAHOO.yuitip.main.set_listeners(target);
509 YAHOO.yuitip.main.show_yuitip(e, target);
509 YAHOO.yuitip.main.show_yuitip(e, target);
510 var url = pyroutes.url('changeset_info', {"repo_name":repo_name, "revision": rid});
510 var url = pyroutes.url('changeset_info', {"repo_name":repo_name, "revision": rid});
511 ajaxGET(url, success)
511 ajaxGET(url, success)
512 }
512 }
513 });
513 });
514 };
514 };
515
515
516 var onSuccessFollow = function(target){
516 var onSuccessFollow = function(target){
517 var f = YUD.get(target);
517 var f = YUD.get(target);
518 var f_cnt = YUD.get('current_followers_count');
518 var f_cnt = YUD.get('current_followers_count');
519
519
520 if(YUD.hasClass(f, 'follow')){
520 if(YUD.hasClass(f, 'follow')){
521 f.setAttribute('class','following');
521 f.setAttribute('class','following');
522 f.setAttribute('title',_TM['Stop following this repository']);
522 f.setAttribute('title',_TM['Stop following this repository']);
523
523
524 if(f_cnt){
524 if(f_cnt){
525 var cnt = Number(f_cnt.innerHTML)+1;
525 var cnt = Number(f_cnt.innerHTML)+1;
526 f_cnt.innerHTML = cnt;
526 f_cnt.innerHTML = cnt;
527 }
527 }
528 }
528 }
529 else{
529 else{
530 f.setAttribute('class','follow');
530 f.setAttribute('class','follow');
531 f.setAttribute('title',_TM['Start following this repository']);
531 f.setAttribute('title',_TM['Start following this repository']);
532 if(f_cnt){
532 if(f_cnt){
533 var cnt = Number(f_cnt.innerHTML)-1;
533 var cnt = Number(f_cnt.innerHTML)-1;
534 f_cnt.innerHTML = cnt;
534 f_cnt.innerHTML = cnt;
535 }
535 }
536 }
536 }
537 }
537 }
538
538
539 var toggleFollowingUser = function(target,fallows_user_id,token,user_id){
539 var toggleFollowingUser = function(target,fallows_user_id,token,user_id){
540 args = 'follows_user_id='+fallows_user_id;
540 args = 'follows_user_id='+fallows_user_id;
541 args+= '&amp;auth_token='+token;
541 args+= '&amp;auth_token='+token;
542 if(user_id != undefined){
542 if(user_id != undefined){
543 args+="&amp;user_id="+user_id;
543 args+="&amp;user_id="+user_id;
544 }
544 }
545 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
545 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
546 success:function(o){
546 success:function(o){
547 onSuccessFollow(target);
547 onSuccessFollow(target);
548 }
548 }
549 },args);
549 },args);
550 return false;
550 return false;
551 }
551 }
552
552
553 var toggleFollowingRepo = function(target,fallows_repo_id,token,user_id){
553 var toggleFollowingRepo = function(target,fallows_repo_id,token,user_id){
554
554
555 args = 'follows_repo_id='+fallows_repo_id;
555 args = 'follows_repo_id='+fallows_repo_id;
556 args+= '&amp;auth_token='+token;
556 args+= '&amp;auth_token='+token;
557 if(user_id != undefined){
557 if(user_id != undefined){
558 args+="&amp;user_id="+user_id;
558 args+="&amp;user_id="+user_id;
559 }
559 }
560 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
560 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
561 success:function(o){
561 success:function(o){
562 onSuccessFollow(target);
562 onSuccessFollow(target);
563 }
563 }
564 },args);
564 },args);
565 return false;
565 return false;
566 }
566 }
567
567
568 var showRepoSize = function(target, repo_name, token){
568 var showRepoSize = function(target, repo_name, token){
569 var args= 'auth_token='+token;
569 var args= 'auth_token='+token;
570
570
571 if(!YUD.hasClass(target, 'loaded')){
571 if(!YUD.hasClass(target, 'loaded')){
572 YUD.get(target).innerHTML = _TM['Loading ...'];
572 YUD.get(target).innerHTML = _TM['Loading ...'];
573 var url = pyroutes.url('repo_size', {"repo_name":repo_name});
573 var url = pyroutes.url('repo_size', {"repo_name":repo_name});
574 YUC.asyncRequest('POST',url,{
574 YUC.asyncRequest('POST',url,{
575 success:function(o){
575 success:function(o){
576 YUD.get(target).innerHTML = JSON.parse(o.responseText);
576 YUD.get(target).innerHTML = JSON.parse(o.responseText);
577 YUD.addClass(target, 'loaded');
577 YUD.addClass(target, 'loaded');
578 }
578 }
579 },args);
579 },args);
580 }
580 }
581 return false;
581 return false;
582 }
582 }
583
583
584 /**
584 /**
585 * TOOLTIP IMPL.
585 * TOOLTIP IMPL.
586 */
586 */
587 YAHOO.namespace('yuitip');
587 YAHOO.namespace('yuitip');
588 YAHOO.yuitip.main = {
588 YAHOO.yuitip.main = {
589
589
590 $: YAHOO.util.Dom.get,
590 $: YAHOO.util.Dom.get,
591
591
592 bgColor: '#000',
592 bgColor: '#000',
593 speed: 0.3,
593 speed: 0.3,
594 opacity: 0.9,
594 opacity: 0.9,
595 offset: [15,15],
595 offset: [15,15],
596 useAnim: false,
596 useAnim: false,
597 maxWidth: 600,
597 maxWidth: 600,
598 add_links: false,
598 add_links: false,
599 yuitips: [],
599 yuitips: [],
600
600
601 set_listeners: function(tt){
601 set_listeners: function(tt){
602 YUE.on(tt, 'mouseover', yt.show_yuitip, tt);
602 YUE.on(tt, 'mouseover', yt.show_yuitip, tt);
603 YUE.on(tt, 'mousemove', yt.move_yuitip, tt);
603 YUE.on(tt, 'mousemove', yt.move_yuitip, tt);
604 YUE.on(tt, 'mouseout', yt.close_yuitip, tt);
604 YUE.on(tt, 'mouseout', yt.close_yuitip, tt);
605 },
605 },
606
606
607 init: function(){
607 init: function(){
608 yt.tipBox = yt.$('tip-box');
608 yt.tipBox = yt.$('tip-box');
609 if(!yt.tipBox){
609 if(!yt.tipBox){
610 yt.tipBox = document.createElement('div');
610 yt.tipBox = document.createElement('div');
611 document.body.appendChild(yt.tipBox);
611 document.body.appendChild(yt.tipBox);
612 yt.tipBox.id = 'tip-box';
612 yt.tipBox.id = 'tip-box';
613 }
613 }
614
614
615 YUD.setStyle(yt.tipBox, 'display', 'none');
615 YUD.setStyle(yt.tipBox, 'display', 'none');
616 YUD.setStyle(yt.tipBox, 'position', 'absolute');
616 YUD.setStyle(yt.tipBox, 'position', 'absolute');
617 if(yt.maxWidth !== null){
617 if(yt.maxWidth !== null){
618 YUD.setStyle(yt.tipBox, 'max-width', yt.maxWidth+'px');
618 YUD.setStyle(yt.tipBox, 'max-width', yt.maxWidth+'px');
619 }
619 }
620
620
621 var yuitips = YUD.getElementsByClassName('tooltip');
621 var yuitips = YUD.getElementsByClassName('tooltip');
622
622
623 if(yt.add_links === true){
623 if(yt.add_links === true){
624 var links = document.getElementsByTagName('a');
624 var links = document.getElementsByTagName('a');
625 var linkLen = links.length;
625 var linkLen = links.length;
626 for(i=0;i<linkLen;i++){
626 for(i=0;i<linkLen;i++){
627 yuitips.push(links[i]);
627 yuitips.push(links[i]);
628 }
628 }
629 }
629 }
630
630
631 var yuiLen = yuitips.length;
631 var yuiLen = yuitips.length;
632
632
633 for(i=0;i<yuiLen;i++){
633 for(i=0;i<yuiLen;i++){
634 yt.set_listeners(yuitips[i]);
634 yt.set_listeners(yuitips[i]);
635 }
635 }
636 },
636 },
637
637
638 show_yuitip: function(e, el){
638 show_yuitip: function(e, el){
639 YUE.stopEvent(e);
639 YUE.stopEvent(e);
640 if(el.tagName.toLowerCase() === 'img'){
640 if(el.tagName.toLowerCase() === 'img'){
641 yt.tipText = el.alt ? el.alt : '';
641 yt.tipText = el.alt ? el.alt : '';
642 } else {
642 } else {
643 yt.tipText = el.title ? el.title : '';
643 yt.tipText = el.title ? el.title : '';
644 }
644 }
645
645
646 if(yt.tipText !== ''){
646 if(yt.tipText !== ''){
647 // save org title
647 // save org title
648 YUD.setAttribute(el, 'tt_title', yt.tipText);
648 YUD.setAttribute(el, 'tt_title', yt.tipText);
649 // reset title to not show org tooltips
649 // reset title to not show org tooltips
650 YUD.setAttribute(el, 'title', '');
650 YUD.setAttribute(el, 'title', '');
651
651
652 yt.tipBox.innerHTML = yt.tipText;
652 yt.tipBox.innerHTML = yt.tipText;
653 YUD.setStyle(yt.tipBox, 'display', 'block');
653 YUD.setStyle(yt.tipBox, 'display', 'block');
654 if(yt.useAnim === true){
654 if(yt.useAnim === true){
655 YUD.setStyle(yt.tipBox, 'opacity', '0');
655 YUD.setStyle(yt.tipBox, 'opacity', '0');
656 var newAnim = new YAHOO.util.Anim(yt.tipBox,
656 var newAnim = new YAHOO.util.Anim(yt.tipBox,
657 {
657 {
658 opacity: { to: yt.opacity }
658 opacity: { to: yt.opacity }
659 }, yt.speed, YAHOO.util.Easing.easeOut
659 }, yt.speed, YAHOO.util.Easing.easeOut
660 );
660 );
661 newAnim.animate();
661 newAnim.animate();
662 }
662 }
663 }
663 }
664 },
664 },
665
665
666 move_yuitip: function(e, el){
666 move_yuitip: function(e, el){
667 YUE.stopEvent(e);
667 YUE.stopEvent(e);
668 var movePos = YUE.getXY(e);
668 var movePos = YUE.getXY(e);
669 YUD.setStyle(yt.tipBox, 'top', (movePos[1] + yt.offset[1]) + 'px');
669 YUD.setStyle(yt.tipBox, 'top', (movePos[1] + yt.offset[1]) + 'px');
670 YUD.setStyle(yt.tipBox, 'left', (movePos[0] + yt.offset[0]) + 'px');
670 YUD.setStyle(yt.tipBox, 'left', (movePos[0] + yt.offset[0]) + 'px');
671 },
671 },
672
672
673 close_yuitip: function(e, el){
673 close_yuitip: function(e, el){
674 YUE.stopEvent(e);
674 YUE.stopEvent(e);
675
675
676 if(yt.useAnim === true){
676 if(yt.useAnim === true){
677 var newAnim = new YAHOO.util.Anim(yt.tipBox,
677 var newAnim = new YAHOO.util.Anim(yt.tipBox,
678 {
678 {
679 opacity: { to: 0 }
679 opacity: { to: 0 }
680 }, yt.speed, YAHOO.util.Easing.easeOut
680 }, yt.speed, YAHOO.util.Easing.easeOut
681 );
681 );
682 newAnim.animate();
682 newAnim.animate();
683 } else {
683 } else {
684 YUD.setStyle(yt.tipBox, 'display', 'none');
684 YUD.setStyle(yt.tipBox, 'display', 'none');
685 }
685 }
686 YUD.setAttribute(el,'title', YUD.getAttribute(el, 'tt_title'));
686 YUD.setAttribute(el,'title', YUD.getAttribute(el, 'tt_title'));
687 }
687 }
688 }
688 }
689
689
690 /**
690 /**
691 * Quick filter widget
691 * Quick filter widget
692 *
692 *
693 * @param target: filter input target
693 * @param target: filter input target
694 * @param nodes: list of nodes in html we want to filter.
694 * @param nodes: list of nodes in html we want to filter.
695 * @param display_element function that takes current node from nodes and
695 * @param display_element function that takes current node from nodes and
696 * does hide or show based on the node
696 * does hide or show based on the node
697 *
697 *
698 */
698 */
699 var q_filter = function(target,nodes,display_element){
699 var q_filter = function(target,nodes,display_element){
700
700
701 var nodes = nodes;
701 var nodes = nodes;
702 var q_filter_field = YUD.get(target);
702 var q_filter_field = YUD.get(target);
703 var F = YAHOO.namespace(target);
703 var F = YAHOO.namespace(target);
704
704
705 YUE.on(q_filter_field,'keyup',function(e){
705 YUE.on(q_filter_field,'keyup',function(e){
706 clearTimeout(F.filterTimeout);
706 clearTimeout(F.filterTimeout);
707 F.filterTimeout = setTimeout(F.updateFilter,600);
707 F.filterTimeout = setTimeout(F.updateFilter,600);
708 });
708 });
709
709
710 F.filterTimeout = null;
710 F.filterTimeout = null;
711
711
712 var show_node = function(node){
712 var show_node = function(node){
713 YUD.setStyle(node,'display','')
713 YUD.setStyle(node,'display','')
714 }
714 }
715 var hide_node = function(node){
715 var hide_node = function(node){
716 YUD.setStyle(node,'display','none');
716 YUD.setStyle(node,'display','none');
717 }
717 }
718
718
719 F.updateFilter = function() {
719 F.updateFilter = function() {
720 // Reset timeout
720 // Reset timeout
721 F.filterTimeout = null;
721 F.filterTimeout = null;
722
722
723 var obsolete = [];
723 var obsolete = [];
724
724
725 var req = q_filter_field.value.toLowerCase();
725 var req = q_filter_field.value.toLowerCase();
726
726
727 var l = nodes.length;
727 var l = nodes.length;
728 var i;
728 var i;
729 var showing = 0;
729 var showing = 0;
730
730
731 for (i=0;i<l;i++ ){
731 for (i=0;i<l;i++ ){
732 var n = nodes[i];
732 var n = nodes[i];
733 var target_element = display_element(n)
733 var target_element = display_element(n)
734 if(req && n.innerHTML.toLowerCase().indexOf(req) == -1){
734 if(req && n.innerHTML.toLowerCase().indexOf(req) == -1){
735 hide_node(target_element);
735 hide_node(target_element);
736 }
736 }
737 else{
737 else{
738 show_node(target_element);
738 show_node(target_element);
739 showing+=1;
739 showing+=1;
740 }
740 }
741 }
741 }
742
742
743 // if repo_count is set update the number
743 // if repo_count is set update the number
744 var cnt = YUD.get('repo_count');
744 var cnt = YUD.get('repo_count');
745 if(cnt){
745 if(cnt){
746 YUD.get('repo_count').innerHTML = showing;
746 YUD.get('repo_count').innerHTML = showing;
747 }
747 }
748
748
749 }
749 }
750 };
750 };
751
751
752 var tableTr = function(cls, body){
752 var tableTr = function(cls, body){
753 var _el = document.createElement('div');
753 var _el = document.createElement('div');
754 var cont = new YAHOO.util.Element(body);
754 var cont = new YAHOO.util.Element(body);
755 var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
755 var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
756 var id = 'comment-tr-{0}'.format(comment_id);
756 var id = 'comment-tr-{0}'.format(comment_id);
757 var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
757 var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
758 '<td class="lineno-inline new-inline"></td>'+
758 '<td class="lineno-inline new-inline"></td>'+
759 '<td class="lineno-inline old-inline"></td>'+
759 '<td class="lineno-inline old-inline"></td>'+
760 '<td>{2}</td>'+
760 '<td>{2}</td>'+
761 '</tr></tbody></table>').format(id, cls, body);
761 '</tr></tbody></table>').format(id, cls, body);
762 _el.innerHTML = _html;
762 _el.innerHTML = _html;
763 return _el.children[0].children[0].children[0];
763 return _el.children[0].children[0].children[0];
764 };
764 };
765
765
766 /** comments **/
766 /** comments **/
767 var removeInlineForm = function(form) {
767 var removeInlineForm = function(form) {
768 form.parentNode.removeChild(form);
768 form.parentNode.removeChild(form);
769 };
769 };
770
770
771 var createInlineForm = function(parent_tr, f_path, line) {
771 var createInlineForm = function(parent_tr, f_path, line) {
772 var tmpl = YUD.get('comment-inline-form-template').innerHTML;
772 var tmpl = YUD.get('comment-inline-form-template').innerHTML;
773 tmpl = tmpl.format(f_path, line);
773 tmpl = tmpl.format(f_path, line);
774 var form = tableTr('comment-form-inline',tmpl)
774 var form = tableTr('comment-form-inline',tmpl)
775
775
776 // create event for hide button
776 // create event for hide button
777 form = new YAHOO.util.Element(form);
777 form = new YAHOO.util.Element(form);
778 var form_hide_button = new YAHOO.util.Element(YUD.getElementsByClassName('hide-inline-form',null,form)[0]);
778 var form_hide_button = new YAHOO.util.Element(YUD.getElementsByClassName('hide-inline-form',null,form)[0]);
779 form_hide_button.on('click', function(e) {
779 form_hide_button.on('click', function(e) {
780 var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
780 var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
781 if(YUD.hasClass(newtr.nextElementSibling,'inline-comments-button')){
781 if(YUD.hasClass(newtr.nextElementSibling,'inline-comments-button')){
782 YUD.setStyle(newtr.nextElementSibling,'display','');
782 YUD.setStyle(newtr.nextElementSibling,'display','');
783 }
783 }
784 removeInlineForm(newtr);
784 removeInlineForm(newtr);
785 YUD.removeClass(parent_tr, 'form-open');
785 YUD.removeClass(parent_tr, 'form-open');
786 YUD.removeClass(parent_tr, 'hl-comment');
786 YUD.removeClass(parent_tr, 'hl-comment');
787
787
788 });
788 });
789
789
790 return form
790 return form
791 };
791 };
792
792
793 /**
793 /**
794 * Inject inline comment for on given TR this tr should be always an .line
794 * Inject inline comment for on given TR this tr should be always an .line
795 * tr containing the line. Code will detect comment, and always put the comment
795 * tr containing the line. Code will detect comment, and always put the comment
796 * block at the very bottom
796 * block at the very bottom
797 */
797 */
798 var injectInlineForm = function(tr){
798 var injectInlineForm = function(tr){
799 if(!YUD.hasClass(tr, 'line')){
799 if(!YUD.hasClass(tr, 'line')){
800 return
800 return
801 }
801 }
802 var submit_url = AJAX_COMMENT_URL;
802 var submit_url = AJAX_COMMENT_URL;
803 var _td = YUD.getElementsByClassName('code',null,tr)[0];
803 var _td = YUD.getElementsByClassName('code',null,tr)[0];
804 if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(_td,'no-comment')){
804 if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(_td,'no-comment')){
805 return
805 return
806 }
806 }
807 YUD.addClass(tr,'form-open');
807 YUD.addClass(tr,'form-open');
808 YUD.addClass(tr,'hl-comment');
808 YUD.addClass(tr,'hl-comment');
809 var node = YUD.getElementsByClassName('full_f_path',null,tr.parentNode.parentNode.parentNode)[0];
809 var node = YUD.getElementsByClassName('full_f_path',null,tr.parentNode.parentNode.parentNode)[0];
810 var f_path = YUD.getAttribute(node,'path');
810 var f_path = YUD.getAttribute(node,'path');
811 var lineno = getLineNo(tr);
811 var lineno = getLineNo(tr);
812 var form = createInlineForm(tr, f_path, lineno, submit_url);
812 var form = createInlineForm(tr, f_path, lineno, submit_url);
813
813
814 var parent = tr;
814 var parent = tr;
815 while (1){
815 while (1){
816 var n = parent.nextElementSibling;
816 var n = parent.nextElementSibling;
817 // next element are comments !
817 // next element are comments !
818 if(YUD.hasClass(n,'inline-comments')){
818 if(YUD.hasClass(n,'inline-comments')){
819 parent = n;
819 parent = n;
820 }
820 }
821 else{
821 else{
822 break;
822 break;
823 }
823 }
824 }
824 }
825 YUD.insertAfter(form,parent);
825 YUD.insertAfter(form,parent);
826 var f = YUD.get(form);
826 var f = YUD.get(form);
827 var overlay = YUD.getElementsByClassName('overlay',null,f)[0];
827 var overlay = YUD.getElementsByClassName('overlay',null,f)[0];
828 var _form = YUD.getElementsByClassName('inline-form',null,f)[0];
828 var _form = YUD.getElementsByClassName('inline-form',null,f)[0];
829
829
830 YUE.on(YUD.get(_form), 'submit',function(e){
830 YUE.on(YUD.get(_form), 'submit',function(e){
831 YUE.preventDefault(e);
831 YUE.preventDefault(e);
832
832
833 //ajax submit
833 //ajax submit
834 var text = YUD.get('text_'+lineno).value;
834 var text = YUD.get('text_'+lineno).value;
835 var postData = {
835 var postData = {
836 'text':text,
836 'text':text,
837 'f_path':f_path,
837 'f_path':f_path,
838 'line':lineno
838 'line':lineno
839 };
839 };
840
840
841 if(lineno === undefined){
841 if(lineno === undefined){
842 alert('missing line !');
842 alert('missing line !');
843 return
843 return
844 }
844 }
845 if(f_path === undefined){
845 if(f_path === undefined){
846 alert('missing file path !');
846 alert('missing file path !');
847 return
847 return
848 }
848 }
849
849
850 if(text == ""){
850 if(text == ""){
851 return
851 return
852 }
852 }
853
853
854 var success = function(o){
854 var success = function(o){
855 YUD.removeClass(tr, 'form-open');
855 YUD.removeClass(tr, 'form-open');
856 removeInlineForm(f);
856 removeInlineForm(f);
857 var json_data = JSON.parse(o.responseText);
857 var json_data = JSON.parse(o.responseText);
858 renderInlineComment(json_data);
858 renderInlineComment(json_data);
859 };
859 };
860
860
861 if (YUD.hasClass(overlay,'overlay')){
861 if (YUD.hasClass(overlay,'overlay')){
862 var w = _form.offsetWidth;
862 var w = _form.offsetWidth;
863 var h = _form.offsetHeight;
863 var h = _form.offsetHeight;
864 YUD.setStyle(overlay,'width',w+'px');
864 YUD.setStyle(overlay,'width',w+'px');
865 YUD.setStyle(overlay,'height',h+'px');
865 YUD.setStyle(overlay,'height',h+'px');
866 }
866 }
867 YUD.addClass(overlay, 'submitting');
867 YUD.addClass(overlay, 'submitting');
868
868
869 ajaxPOST(submit_url, postData, success);
869 ajaxPOST(submit_url, postData, success);
870 });
870 });
871
871
872 YUE.on('preview-btn_'+lineno, 'click', function(e){
872 YUE.on('preview-btn_'+lineno, 'click', function(e){
873 var _text = YUD.get('text_'+lineno).value;
873 var _text = YUD.get('text_'+lineno).value;
874 if(!_text){
874 if(!_text){
875 return
875 return
876 }
876 }
877 var post_data = {'text': _text};
877 var post_data = {'text': _text};
878 YUD.addClass('preview-box_'+lineno, 'unloaded');
878 YUD.addClass('preview-box_'+lineno, 'unloaded');
879 YUD.get('preview-box_'+lineno).innerHTML = _TM['Loading ...'];
879 YUD.get('preview-box_'+lineno).innerHTML = _TM['Loading ...'];
880 YUD.setStyle('edit-container_'+lineno, 'display', 'none');
880 YUD.setStyle('edit-container_'+lineno, 'display', 'none');
881 YUD.setStyle('preview-container_'+lineno, 'display', '');
881 YUD.setStyle('preview-container_'+lineno, 'display', '');
882
882
883 var url = pyroutes.url('changeset_comment_preview', {'repo_name': REPO_NAME});
883 var url = pyroutes.url('changeset_comment_preview', {'repo_name': REPO_NAME});
884 ajaxPOST(url,post_data,function(o){
884 ajaxPOST(url,post_data,function(o){
885 YUD.get('preview-box_'+lineno).innerHTML = o.responseText;
885 YUD.get('preview-box_'+lineno).innerHTML = o.responseText;
886 YUD.removeClass('preview-box_'+lineno, 'unloaded');
886 YUD.removeClass('preview-box_'+lineno, 'unloaded');
887 })
887 })
888 })
888 })
889 YUE.on('edit-btn_'+lineno, 'click', function(e){
889 YUE.on('edit-btn_'+lineno, 'click', function(e){
890 YUD.setStyle('edit-container_'+lineno, 'display', '');
890 YUD.setStyle('edit-container_'+lineno, 'display', '');
891 YUD.setStyle('preview-container_'+lineno, 'display', 'none');
891 YUD.setStyle('preview-container_'+lineno, 'display', 'none');
892 })
892 })
893
893
894
894
895 setTimeout(function(){
895 setTimeout(function(){
896 // callbacks
896 // callbacks
897 tooltip_activate();
897 tooltip_activate();
898 MentionsAutoComplete('text_'+lineno, 'mentions_container_'+lineno,
898 MentionsAutoComplete('text_'+lineno, 'mentions_container_'+lineno,
899 _USERS_AC_DATA, _GROUPS_AC_DATA);
899 _USERS_AC_DATA, _GROUPS_AC_DATA);
900 var _e = YUD.get('text_'+lineno);
900 var _e = YUD.get('text_'+lineno);
901 if(_e){
901 if(_e){
902 _e.focus();
902 _e.focus();
903 }
903 }
904 },10)
904 },10)
905 };
905 };
906
906
907 var deleteComment = function(comment_id){
907 var deleteComment = function(comment_id){
908 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__',comment_id);
908 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__',comment_id);
909 var postData = {'_method':'delete'};
909 var postData = {'_method':'delete'};
910 var success = function(o){
910 var success = function(o){
911 var n = YUD.get('comment-tr-'+comment_id);
911 var n = YUD.get('comment-tr-'+comment_id);
912 var root = prevElementSibling(prevElementSibling(n));
912 var root = prevElementSibling(prevElementSibling(n));
913 n.parentNode.removeChild(n);
913 n.parentNode.removeChild(n);
914
914
915 // scann nodes, and attach add button to last one only for TR
915 // scann nodes, and attach add button to last one only for TR
916 // which are the inline comments
916 // which are the inline comments
917 if(root && root.tagName == 'TR'){
917 if(root && root.tagName == 'TR'){
918 placeAddButton(root);
918 placeAddButton(root);
919 }
919 }
920 }
920 }
921 ajaxPOST(url,postData,success);
921 ajaxPOST(url,postData,success);
922 }
922 }
923
923
924 var createInlineAddButton = function(tr){
924 var createInlineAddButton = function(tr){
925
925
926 var label = TRANSLATION_MAP['Add another comment'];
926 var label = TRANSLATION_MAP['Add another comment'];
927
927
928 var html_el = document.createElement('div');
928 var html_el = document.createElement('div');
929 YUD.addClass(html_el, 'add-comment');
929 YUD.addClass(html_el, 'add-comment');
930 html_el.innerHTML = '<span class="ui-btn">{0}</span>'.format(label);
930 html_el.innerHTML = '<span class="ui-btn">{0}</span>'.format(label);
931
931
932 var add = new YAHOO.util.Element(html_el);
932 var add = new YAHOO.util.Element(html_el);
933 add.on('click', function(e) {
933 add.on('click', function(e) {
934 injectInlineForm(tr);
934 injectInlineForm(tr);
935 });
935 });
936 return add;
936 return add;
937 };
937 };
938
938
939 var getLineNo = function(tr) {
939 var getLineNo = function(tr) {
940 var line;
940 var line;
941 var o = tr.children[0].id.split('_');
941 var o = tr.children[0].id.split('_');
942 var n = tr.children[1].id.split('_');
942 var n = tr.children[1].id.split('_');
943
943
944 if (n.length >= 2) {
944 if (n.length >= 2) {
945 line = n[n.length-1];
945 line = n[n.length-1];
946 } else if (o.length >= 2) {
946 } else if (o.length >= 2) {
947 line = o[o.length-1];
947 line = o[o.length-1];
948 }
948 }
949
949
950 return line
950 return line
951 };
951 };
952
952
953 var placeAddButton = function(target_tr){
953 var placeAddButton = function(target_tr){
954 if(!target_tr){
954 if(!target_tr){
955 return
955 return
956 }
956 }
957 var last_node = target_tr;
957 var last_node = target_tr;
958 //scann
958 //scann
959 while (1){
959 while (1){
960 var n = last_node.nextElementSibling;
960 var n = last_node.nextElementSibling;
961 // next element are comments !
961 // next element are comments !
962 if(YUD.hasClass(n,'inline-comments')){
962 if(YUD.hasClass(n,'inline-comments')){
963 last_node = n;
963 last_node = n;
964 //also remove the comment button from previous
964 //also remove the comment button from previous
965 var comment_add_buttons = YUD.getElementsByClassName('add-comment',null,last_node);
965 var comment_add_buttons = YUD.getElementsByClassName('add-comment',null,last_node);
966 for(var i=0;i<comment_add_buttons.length;i++){
966 for(var i=0;i<comment_add_buttons.length;i++){
967 var b = comment_add_buttons[i];
967 var b = comment_add_buttons[i];
968 b.parentNode.removeChild(b);
968 b.parentNode.removeChild(b);
969 }
969 }
970 }
970 }
971 else{
971 else{
972 break;
972 break;
973 }
973 }
974 }
974 }
975
975
976 var add = createInlineAddButton(target_tr);
976 var add = createInlineAddButton(target_tr);
977 // get the comment div
977 // get the comment div
978 var comment_block = YUD.getElementsByClassName('comment',null,last_node)[0];
978 var comment_block = YUD.getElementsByClassName('comment',null,last_node)[0];
979 // attach add button
979 // attach add button
980 YUD.insertAfter(add,comment_block);
980 YUD.insertAfter(add,comment_block);
981 }
981 }
982
982
983 /**
983 /**
984 * Places the inline comment into the changeset block in proper line position
984 * Places the inline comment into the changeset block in proper line position
985 */
985 */
986 var placeInline = function(target_container,lineno,html){
986 var placeInline = function(target_container,lineno,html){
987 var lineid = "{0}_{1}".format(target_container,lineno);
987 var lineid = "{0}_{1}".format(target_container,lineno);
988 var target_line = YUD.get(lineid);
988 var target_line = YUD.get(lineid);
989 var comment = new YAHOO.util.Element(tableTr('inline-comments',html))
989 var comment = new YAHOO.util.Element(tableTr('inline-comments',html))
990
990
991 // check if there are comments already !
991 // check if there are comments already !
992 var parent = target_line.parentNode;
992 var parent = target_line.parentNode;
993 var root_parent = parent;
993 var root_parent = parent;
994 while (1){
994 while (1){
995 var n = parent.nextElementSibling;
995 var n = parent.nextElementSibling;
996 // next element are comments !
996 // next element are comments !
997 if(YUD.hasClass(n,'inline-comments')){
997 if(YUD.hasClass(n,'inline-comments')){
998 parent = n;
998 parent = n;
999 }
999 }
1000 else{
1000 else{
1001 break;
1001 break;
1002 }
1002 }
1003 }
1003 }
1004 // put in the comment at the bottom
1004 // put in the comment at the bottom
1005 YUD.insertAfter(comment,parent);
1005 YUD.insertAfter(comment,parent);
1006
1006
1007 // scann nodes, and attach add button to last one
1007 // scann nodes, and attach add button to last one
1008 placeAddButton(root_parent);
1008 placeAddButton(root_parent);
1009
1009
1010 return target_line;
1010 return target_line;
1011 }
1011 }
1012
1012
1013 /**
1013 /**
1014 * make a single inline comment and place it inside
1014 * make a single inline comment and place it inside
1015 */
1015 */
1016 var renderInlineComment = function(json_data){
1016 var renderInlineComment = function(json_data){
1017 try{
1017 try{
1018 var html = json_data['rendered_text'];
1018 var html = json_data['rendered_text'];
1019 var lineno = json_data['line_no'];
1019 var lineno = json_data['line_no'];
1020 var target_id = json_data['target_id'];
1020 var target_id = json_data['target_id'];
1021 placeInline(target_id, lineno, html);
1021 placeInline(target_id, lineno, html);
1022
1022
1023 }catch(e){
1023 }catch(e){
1024 console.log(e);
1024 console.log(e);
1025 }
1025 }
1026 }
1026 }
1027
1027
1028 /**
1028 /**
1029 * Iterates over all the inlines, and places them inside proper blocks of data
1029 * Iterates over all the inlines, and places them inside proper blocks of data
1030 */
1030 */
1031 var renderInlineComments = function(file_comments){
1031 var renderInlineComments = function(file_comments){
1032 for (f in file_comments){
1032 for (f in file_comments){
1033 // holding all comments for a FILE
1033 // holding all comments for a FILE
1034 var box = file_comments[f];
1034 var box = file_comments[f];
1035
1035
1036 var target_id = YUD.getAttribute(box,'target_id');
1036 var target_id = YUD.getAttribute(box,'target_id');
1037 // actually comments with line numbers
1037 // actually comments with line numbers
1038 var comments = box.children;
1038 var comments = box.children;
1039 for(var i=0; i<comments.length; i++){
1039 for(var i=0; i<comments.length; i++){
1040 var data = {
1040 var data = {
1041 'rendered_text': comments[i].outerHTML,
1041 'rendered_text': comments[i].outerHTML,
1042 'line_no': YUD.getAttribute(comments[i],'line'),
1042 'line_no': YUD.getAttribute(comments[i],'line'),
1043 'target_id': target_id
1043 'target_id': target_id
1044 }
1044 }
1045 renderInlineComment(data);
1045 renderInlineComment(data);
1046 }
1046 }
1047 }
1047 }
1048 }
1048 }
1049
1049
1050 var fileBrowserListeners = function(current_url, node_list_url, url_base){
1050 var fileBrowserListeners = function(current_url, node_list_url, url_base){
1051 var current_url_branch = +"?branch=__BRANCH__";
1051 var current_url_branch = +"?branch=__BRANCH__";
1052
1052
1053 YUE.on('stay_at_branch','click',function(e){
1053 YUE.on('stay_at_branch','click',function(e){
1054 if(e.target.checked){
1054 if(e.target.checked){
1055 var uri = current_url_branch;
1055 var uri = current_url_branch;
1056 uri = uri.replace('__BRANCH__',e.target.value);
1056 uri = uri.replace('__BRANCH__',e.target.value);
1057 window.location = uri;
1057 window.location = uri;
1058 }
1058 }
1059 else{
1059 else{
1060 window.location = current_url;
1060 window.location = current_url;
1061 }
1061 }
1062 })
1062 })
1063
1063
1064 var n_filter = YUD.get('node_filter');
1064 var n_filter = YUD.get('node_filter');
1065 var F = YAHOO.namespace('node_filter');
1065 var F = YAHOO.namespace('node_filter');
1066
1066
1067 F.filterTimeout = null;
1067 F.filterTimeout = null;
1068 var nodes = null;
1068 var nodes = null;
1069
1069
1070 F.initFilter = function(){
1070 F.initFilter = function(){
1071 YUD.setStyle('node_filter_box_loading','display','');
1071 YUD.setStyle('node_filter_box_loading','display','');
1072 YUD.setStyle('search_activate_id','display','none');
1072 YUD.setStyle('search_activate_id','display','none');
1073 YUD.setStyle('add_node_id','display','none');
1073 YUD.setStyle('add_node_id','display','none');
1074 YUC.initHeader('X-PARTIAL-XHR',true);
1074 YUC.initHeader('X-PARTIAL-XHR',true);
1075 YUC.asyncRequest('GET', node_list_url, {
1075 YUC.asyncRequest('GET', node_list_url, {
1076 success:function(o){
1076 success:function(o){
1077 nodes = JSON.parse(o.responseText).nodes;
1077 nodes = JSON.parse(o.responseText).nodes;
1078 YUD.setStyle('node_filter_box_loading','display','none');
1078 YUD.setStyle('node_filter_box_loading','display','none');
1079 YUD.setStyle('node_filter_box','display','');
1079 YUD.setStyle('node_filter_box','display','');
1080 n_filter.focus();
1080 n_filter.focus();
1081 if(YUD.hasClass(n_filter,'init')){
1081 if(YUD.hasClass(n_filter,'init')){
1082 n_filter.value = '';
1082 n_filter.value = '';
1083 YUD.removeClass(n_filter,'init');
1083 YUD.removeClass(n_filter,'init');
1084 }
1084 }
1085 },
1085 },
1086 failure:function(o){
1086 failure:function(o){
1087 console.log('failed to load');
1087 console.log('failed to load');
1088 }
1088 }
1089 },null);
1089 },null);
1090 }
1090 }
1091
1091
1092 F.updateFilter = function(e) {
1092 F.updateFilter = function(e) {
1093
1093
1094 return function(){
1094 return function(){
1095 // Reset timeout
1095 // Reset timeout
1096 F.filterTimeout = null;
1096 F.filterTimeout = null;
1097 var query = e.target.value.toLowerCase();
1097 var query = e.target.value.toLowerCase();
1098 var match = [];
1098 var match = [];
1099 var matches = 0;
1099 var matches = 0;
1100 var matches_max = 20;
1100 var matches_max = 20;
1101 if (query != ""){
1101 if (query != ""){
1102 for(var i=0;i<nodes.length;i++){
1102 for(var i=0;i<nodes.length;i++){
1103
1103
1104 var pos = nodes[i].name.toLowerCase().indexOf(query)
1104 var pos = nodes[i].name.toLowerCase().indexOf(query)
1105 if(query && pos != -1){
1105 if(query && pos != -1){
1106
1106
1107 matches++
1107 matches++
1108 //show only certain amount to not kill browser
1108 //show only certain amount to not kill browser
1109 if (matches > matches_max){
1109 if (matches > matches_max){
1110 break;
1110 break;
1111 }
1111 }
1112
1112
1113 var n = nodes[i].name;
1113 var n = nodes[i].name;
1114 var t = nodes[i].type;
1114 var t = nodes[i].type;
1115 var n_hl = n.substring(0,pos)
1115 var n_hl = n.substring(0,pos)
1116 +"<b>{0}</b>".format(n.substring(pos,pos+query.length))
1116 +"<b>{0}</b>".format(n.substring(pos,pos+query.length))
1117 +n.substring(pos+query.length)
1117 +n.substring(pos+query.length)
1118 var new_url = url_base.replace('__FPATH__',n);
1118 var new_url = url_base.replace('__FPATH__',n);
1119 match.push('<tr><td><a class="browser-{0}" href="{1}">{2}</a></td><td colspan="5"></td></tr>'.format(t,new_url,n_hl));
1119 match.push('<tr><td><a class="browser-{0}" href="{1}">{2}</a></td><td colspan="5"></td></tr>'.format(t,new_url,n_hl));
1120 }
1120 }
1121 if(match.length >= matches_max){
1121 if(match.length >= matches_max){
1122 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['Search truncated']));
1122 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['Search truncated']));
1123 }
1123 }
1124 }
1124 }
1125 }
1125 }
1126 if(query != ""){
1126 if(query != ""){
1127 YUD.setStyle('tbody','display','none');
1127 YUD.setStyle('tbody','display','none');
1128 YUD.setStyle('tbody_filtered','display','');
1128 YUD.setStyle('tbody_filtered','display','');
1129
1129
1130 if (match.length==0){
1130 if (match.length==0){
1131 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['No matching files']));
1131 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['No matching files']));
1132 }
1132 }
1133
1133
1134 YUD.get('tbody_filtered').innerHTML = match.join("");
1134 YUD.get('tbody_filtered').innerHTML = match.join("");
1135 }
1135 }
1136 else{
1136 else{
1137 YUD.setStyle('tbody','display','');
1137 YUD.setStyle('tbody','display','');
1138 YUD.setStyle('tbody_filtered','display','none');
1138 YUD.setStyle('tbody_filtered','display','none');
1139 }
1139 }
1140
1140
1141 }
1141 }
1142 };
1142 };
1143
1143
1144 YUE.on(YUD.get('filter_activate'),'click',function(){
1144 YUE.on(YUD.get('filter_activate'),'click',function(){
1145 F.initFilter();
1145 F.initFilter();
1146 })
1146 })
1147 YUE.on(n_filter,'click',function(){
1147 YUE.on(n_filter,'click',function(){
1148 if(YUD.hasClass(n_filter,'init')){
1148 if(YUD.hasClass(n_filter,'init')){
1149 n_filter.value = '';
1149 n_filter.value = '';
1150 YUD.removeClass(n_filter,'init');
1150 YUD.removeClass(n_filter,'init');
1151 }
1151 }
1152 });
1152 });
1153 YUE.on(n_filter,'keyup',function(e){
1153 YUE.on(n_filter,'keyup',function(e){
1154 clearTimeout(F.filterTimeout);
1154 clearTimeout(F.filterTimeout);
1155 F.filterTimeout = setTimeout(F.updateFilter(e),600);
1155 F.filterTimeout = setTimeout(F.updateFilter(e),600);
1156 });
1156 });
1157 };
1157 };
1158
1158
1159
1159
1160 var initCodeMirror = function(textAreadId,resetUrl){
1160 var initCodeMirror = function(textAreadId,resetUrl){
1161 var myCodeMirror = CodeMirror.fromTextArea(YUD.get(textAreadId),{
1161 var myCodeMirror = CodeMirror.fromTextArea(YUD.get(textAreadId),{
1162 mode: "null",
1162 mode: "null",
1163 lineNumbers:true
1163 lineNumbers:true
1164 });
1164 });
1165 YUE.on('reset','click',function(e){
1165 YUE.on('reset','click',function(e){
1166 window.location=resetUrl
1166 window.location=resetUrl
1167 });
1167 });
1168
1168
1169 YUE.on('file_enable','click',function(){
1169 YUE.on('file_enable','click',function(){
1170 YUD.setStyle('editor_container','display','');
1170 YUD.setStyle('editor_container','display','');
1171 YUD.setStyle('upload_file_container','display','none');
1171 YUD.setStyle('upload_file_container','display','none');
1172 YUD.setStyle('filename_container','display','');
1172 YUD.setStyle('filename_container','display','');
1173 });
1173 });
1174
1174
1175 YUE.on('upload_file_enable','click',function(){
1175 YUE.on('upload_file_enable','click',function(){
1176 YUD.setStyle('editor_container','display','none');
1176 YUD.setStyle('editor_container','display','none');
1177 YUD.setStyle('upload_file_container','display','');
1177 YUD.setStyle('upload_file_container','display','');
1178 YUD.setStyle('filename_container','display','none');
1178 YUD.setStyle('filename_container','display','none');
1179 });
1179 });
1180 };
1180 };
1181
1181
1182
1182
1183
1183
1184 var getIdentNode = function(n){
1184 var getIdentNode = function(n){
1185 //iterate thru nodes untill matched interesting node !
1185 //iterate thru nodes untill matched interesting node !
1186
1186
1187 if (typeof n == 'undefined'){
1187 if (typeof n == 'undefined'){
1188 return -1
1188 return -1
1189 }
1189 }
1190
1190
1191 if(typeof n.id != "undefined" && n.id.match('L[0-9]+')){
1191 if(typeof n.id != "undefined" && n.id.match('L[0-9]+')){
1192 return n
1192 return n
1193 }
1193 }
1194 else{
1194 else{
1195 return getIdentNode(n.parentNode);
1195 return getIdentNode(n.parentNode);
1196 }
1196 }
1197 };
1197 };
1198
1198
1199 var getSelectionLink = function(e) {
1199 var getSelectionLink = function(e) {
1200
1200
1201 //get selection from start/to nodes
1201 //get selection from start/to nodes
1202 if (typeof window.getSelection != "undefined") {
1202 if (typeof window.getSelection != "undefined") {
1203 s = window.getSelection();
1203 s = window.getSelection();
1204
1204
1205 from = getIdentNode(s.anchorNode);
1205 from = getIdentNode(s.anchorNode);
1206 till = getIdentNode(s.focusNode);
1206 till = getIdentNode(s.focusNode);
1207
1207
1208 f_int = parseInt(from.id.replace('L',''));
1208 f_int = parseInt(from.id.replace('L',''));
1209 t_int = parseInt(till.id.replace('L',''));
1209 t_int = parseInt(till.id.replace('L',''));
1210
1210
1211 if (f_int > t_int){
1211 if (f_int > t_int){
1212 //highlight from bottom
1212 //highlight from bottom
1213 offset = -35;
1213 offset = -35;
1214 ranges = [t_int,f_int];
1214 ranges = [t_int,f_int];
1215
1215
1216 }
1216 }
1217 else{
1217 else{
1218 //highligth from top
1218 //highligth from top
1219 offset = 35;
1219 offset = 35;
1220 ranges = [f_int,t_int];
1220 ranges = [f_int,t_int];
1221 }
1221 }
1222 // if we select more than 2 lines
1222 // if we select more than 2 lines
1223 if (ranges[0] != ranges[1]){
1223 if (ranges[0] != ranges[1]){
1224 if(YUD.get('linktt') == null){
1224 if(YUD.get('linktt') == null){
1225 hl_div = document.createElement('div');
1225 hl_div = document.createElement('div');
1226 hl_div.id = 'linktt';
1226 hl_div.id = 'linktt';
1227 }
1227 }
1228 hl_div.innerHTML = '';
1228 hl_div.innerHTML = '';
1229
1229
1230 anchor = '#L'+ranges[0]+'-'+ranges[1];
1230 anchor = '#L'+ranges[0]+'-'+ranges[1];
1231 var link = document.createElement('a');
1231 var link = document.createElement('a');
1232 link.href = location.href.substring(0,location.href.indexOf('#'))+anchor;
1232 link.href = location.href.substring(0,location.href.indexOf('#'))+anchor;
1233 link.innerHTML = _TM['Selection link'];
1233 link.innerHTML = _TM['Selection link'];
1234 hl_div.appendChild(link);
1234 hl_div.appendChild(link);
1235 YUD.get('body').appendChild(hl_div);
1235 YUD.get('body').appendChild(hl_div);
1236
1236
1237 xy = YUD.getXY(till.id);
1237 xy = YUD.getXY(till.id);
1238
1238
1239 YUD.addClass('linktt', 'hl-tip-box');
1239 YUD.addClass('linktt', 'hl-tip-box');
1240 YUD.setStyle('linktt','top',xy[1]+offset+'px');
1240 YUD.setStyle('linktt','top',xy[1]+offset+'px');
1241 YUD.setStyle('linktt','left',xy[0]+'px');
1241 YUD.setStyle('linktt','left',xy[0]+'px');
1242 YUD.setStyle('linktt','visibility','visible');
1242 YUD.setStyle('linktt','visibility','visible');
1243
1243
1244 }
1244 }
1245 else{
1245 else{
1246 YUD.setStyle('linktt','visibility','hidden');
1246 YUD.setStyle('linktt','visibility','hidden');
1247 }
1247 }
1248 }
1248 }
1249 };
1249 };
1250
1250
1251 var deleteNotification = function(url, notification_id,callbacks){
1251 var deleteNotification = function(url, notification_id,callbacks){
1252 var callback = {
1252 var callback = {
1253 success:function(o){
1253 success:function(o){
1254 var obj = YUD.get(String("notification_"+notification_id));
1254 var obj = YUD.get(String("notification_"+notification_id));
1255 if(obj.parentNode !== undefined){
1255 if(obj.parentNode !== undefined){
1256 obj.parentNode.removeChild(obj);
1256 obj.parentNode.removeChild(obj);
1257 }
1257 }
1258 _run_callbacks(callbacks);
1258 _run_callbacks(callbacks);
1259 },
1259 },
1260 failure:function(o){
1260 failure:function(o){
1261 alert("error");
1261 alert("error");
1262 },
1262 },
1263 };
1263 };
1264 var postData = '_method=delete';
1264 var postData = '_method=delete';
1265 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1265 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1266 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1266 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1267 callback, postData);
1267 callback, postData);
1268 };
1268 };
1269
1269
1270 var readNotification = function(url, notification_id,callbacks){
1270 var readNotification = function(url, notification_id,callbacks){
1271 var callback = {
1271 var callback = {
1272 success:function(o){
1272 success:function(o){
1273 var obj = YUD.get(String("notification_"+notification_id));
1273 var obj = YUD.get(String("notification_"+notification_id));
1274 YUD.removeClass(obj, 'unread');
1274 YUD.removeClass(obj, 'unread');
1275 var r_button = YUD.getElementsByClassName('read-notification',null,obj.children[0])[0];
1275 var r_button = YUD.getElementsByClassName('read-notification',null,obj.children[0])[0];
1276
1276
1277 if(r_button.parentNode !== undefined){
1277 if(r_button.parentNode !== undefined){
1278 r_button.parentNode.removeChild(r_button);
1278 r_button.parentNode.removeChild(r_button);
1279 }
1279 }
1280 _run_callbacks(callbacks);
1280 _run_callbacks(callbacks);
1281 },
1281 },
1282 failure:function(o){
1282 failure:function(o){
1283 alert("error");
1283 alert("error");
1284 },
1284 },
1285 };
1285 };
1286 var postData = '_method=put';
1286 var postData = '_method=put';
1287 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1287 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1288 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1288 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1289 callback, postData);
1289 callback, postData);
1290 };
1290 };
1291
1291
1292 /** MEMBERS AUTOCOMPLETE WIDGET **/
1292 /** MEMBERS AUTOCOMPLETE WIDGET **/
1293
1293
1294 var MembersAutoComplete = function (divid, cont, users_list, groups_list) {
1294 var MembersAutoComplete = function (divid, cont, users_list, groups_list) {
1295 var myUsers = users_list;
1295 var myUsers = users_list;
1296 var myGroups = groups_list;
1296 var myGroups = groups_list;
1297
1297
1298 // Define a custom search function for the DataSource of users
1298 // Define a custom search function for the DataSource of users
1299 var matchUsers = function (sQuery) {
1299 var matchUsers = function (sQuery) {
1300 // Case insensitive matching
1300 // Case insensitive matching
1301 var query = sQuery.toLowerCase();
1301 var query = sQuery.toLowerCase();
1302 var i = 0;
1302 var i = 0;
1303 var l = myUsers.length;
1303 var l = myUsers.length;
1304 var matches = [];
1304 var matches = [];
1305
1305
1306 // Match against each name of each contact
1306 // Match against each name of each contact
1307 for (; i < l; i++) {
1307 for (; i < l; i++) {
1308 contact = myUsers[i];
1308 contact = myUsers[i];
1309 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1309 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1310 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1310 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1311 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1311 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1312 matches[matches.length] = contact;
1312 matches[matches.length] = contact;
1313 }
1313 }
1314 }
1314 }
1315 return matches;
1315 return matches;
1316 };
1316 };
1317
1317
1318 // Define a custom search function for the DataSource of userGroups
1318 // Define a custom search function for the DataSource of userGroups
1319 var matchGroups = function (sQuery) {
1319 var matchGroups = function (sQuery) {
1320 // Case insensitive matching
1320 // Case insensitive matching
1321 var query = sQuery.toLowerCase();
1321 var query = sQuery.toLowerCase();
1322 var i = 0;
1322 var i = 0;
1323 var l = myGroups.length;
1323 var l = myGroups.length;
1324 var matches = [];
1324 var matches = [];
1325
1325
1326 // Match against each name of each contact
1326 // Match against each name of each contact
1327 for (; i < l; i++) {
1327 for (; i < l; i++) {
1328 matched_group = myGroups[i];
1328 matched_group = myGroups[i];
1329 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1329 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1330 matches[matches.length] = matched_group;
1330 matches[matches.length] = matched_group;
1331 }
1331 }
1332 }
1332 }
1333 return matches;
1333 return matches;
1334 };
1334 };
1335
1335
1336 //match all
1336 //match all
1337 var matchAll = function (sQuery) {
1337 var matchAll = function (sQuery) {
1338 u = matchUsers(sQuery);
1338 u = matchUsers(sQuery);
1339 g = matchGroups(sQuery);
1339 g = matchGroups(sQuery);
1340 return u.concat(g);
1340 return u.concat(g);
1341 };
1341 };
1342
1342
1343 // DataScheme for members
1343 // DataScheme for members
1344 var memberDS = new YAHOO.util.FunctionDataSource(matchAll);
1344 var memberDS = new YAHOO.util.FunctionDataSource(matchAll);
1345 memberDS.responseSchema = {
1345 memberDS.responseSchema = {
1346 fields: ["id", "fname", "lname", "nname", "grname", "grmembers", "gravatar_lnk"]
1346 fields: ["id", "fname", "lname", "nname", "grname", "grmembers", "gravatar_lnk"]
1347 };
1347 };
1348
1348
1349 // DataScheme for owner
1349 // DataScheme for owner
1350 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1350 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1351 ownerDS.responseSchema = {
1351 ownerDS.responseSchema = {
1352 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1352 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1353 };
1353 };
1354
1354
1355 // Instantiate AutoComplete for perms
1355 // Instantiate AutoComplete for perms
1356 var membersAC = new YAHOO.widget.AutoComplete(divid, cont, memberDS);
1356 var membersAC = new YAHOO.widget.AutoComplete(divid, cont, memberDS);
1357 membersAC.useShadow = false;
1357 membersAC.useShadow = false;
1358 membersAC.resultTypeList = false;
1358 membersAC.resultTypeList = false;
1359 membersAC.animVert = false;
1359 membersAC.animVert = false;
1360 membersAC.animHoriz = false;
1360 membersAC.animHoriz = false;
1361 membersAC.animSpeed = 0.1;
1361 membersAC.animSpeed = 0.1;
1362
1362
1363 // Instantiate AutoComplete for owner
1363 // Instantiate AutoComplete for owner
1364 var ownerAC = new YAHOO.widget.AutoComplete("user", "owner_container", ownerDS);
1364 var ownerAC = new YAHOO.widget.AutoComplete("user", "owner_container", ownerDS);
1365 ownerAC.useShadow = false;
1365 ownerAC.useShadow = false;
1366 ownerAC.resultTypeList = false;
1366 ownerAC.resultTypeList = false;
1367 ownerAC.animVert = false;
1367 ownerAC.animVert = false;
1368 ownerAC.animHoriz = false;
1368 ownerAC.animHoriz = false;
1369 ownerAC.animSpeed = 0.1;
1369 ownerAC.animSpeed = 0.1;
1370
1370
1371 // Helper highlight function for the formatter
1371 // Helper highlight function for the formatter
1372 var highlightMatch = function (full, snippet, matchindex) {
1372 var highlightMatch = function (full, snippet, matchindex) {
1373 return full.substring(0, matchindex)
1373 return full.substring(0, matchindex)
1374 + "<span class='match'>"
1374 + "<span class='match'>"
1375 + full.substr(matchindex, snippet.length)
1375 + full.substr(matchindex, snippet.length)
1376 + "</span>" + full.substring(matchindex + snippet.length);
1376 + "</span>" + full.substring(matchindex + snippet.length);
1377 };
1377 };
1378
1378
1379 // Custom formatter to highlight the matching letters
1379 // Custom formatter to highlight the matching letters
1380 var custom_formatter = function (oResultData, sQuery, sResultMatch) {
1380 var custom_formatter = function (oResultData, sQuery, sResultMatch) {
1381 var query = sQuery.toLowerCase();
1381 var query = sQuery.toLowerCase();
1382 var _gravatar = function(res, em, group){
1382 var _gravatar = function(res, em, group){
1383 if (group !== undefined){
1383 if (group !== undefined){
1384 em = '/images/icons/group.png'
1384 em = '/images/icons/group.png'
1385 }
1385 }
1386 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1386 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1387 return tmpl.format(em,res)
1387 return tmpl.format(em,res)
1388 }
1388 }
1389 // group
1389 // group
1390 if (oResultData.grname != undefined) {
1390 if (oResultData.grname != undefined) {
1391 var grname = oResultData.grname;
1391 var grname = oResultData.grname;
1392 var grmembers = oResultData.grmembers;
1392 var grmembers = oResultData.grmembers;
1393 var grnameMatchIndex = grname.toLowerCase().indexOf(query);
1393 var grnameMatchIndex = grname.toLowerCase().indexOf(query);
1394 var grprefix = "{0}: ".format(_TM['Group']);
1394 var grprefix = "{0}: ".format(_TM['Group']);
1395 var grsuffix = " (" + grmembers + " )";
1395 var grsuffix = " (" + grmembers + " )";
1396 var grsuffix = " ({0} {1})".format(grmembers, _TM['members']);
1396 var grsuffix = " ({0} {1})".format(grmembers, _TM['members']);
1397
1397
1398 if (grnameMatchIndex > -1) {
1398 if (grnameMatchIndex > -1) {
1399 return _gravatar(grprefix + highlightMatch(grname, query, grnameMatchIndex) + grsuffix,null,true);
1399 return _gravatar(grprefix + highlightMatch(grname, query, grnameMatchIndex) + grsuffix,null,true);
1400 }
1400 }
1401 return _gravatar(grprefix + oResultData.grname + grsuffix, null,true);
1401 return _gravatar(grprefix + oResultData.grname + grsuffix, null,true);
1402 // Users
1402 // Users
1403 } else if (oResultData.nname != undefined) {
1403 } else if (oResultData.nname != undefined) {
1404 var fname = oResultData.fname || "";
1404 var fname = oResultData.fname || "";
1405 var lname = oResultData.lname || "";
1405 var lname = oResultData.lname || "";
1406 var nname = oResultData.nname;
1406 var nname = oResultData.nname;
1407
1407
1408 // Guard against null value
1408 // Guard against null value
1409 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1409 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1410 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1410 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1411 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1411 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1412 displayfname, displaylname, displaynname;
1412 displayfname, displaylname, displaynname;
1413
1413
1414 if (fnameMatchIndex > -1) {
1414 if (fnameMatchIndex > -1) {
1415 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1415 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1416 } else {
1416 } else {
1417 displayfname = fname;
1417 displayfname = fname;
1418 }
1418 }
1419
1419
1420 if (lnameMatchIndex > -1) {
1420 if (lnameMatchIndex > -1) {
1421 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1421 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1422 } else {
1422 } else {
1423 displaylname = lname;
1423 displaylname = lname;
1424 }
1424 }
1425
1425
1426 if (nnameMatchIndex > -1) {
1426 if (nnameMatchIndex > -1) {
1427 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1427 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1428 } else {
1428 } else {
1429 displaynname = nname ? "(" + nname + ")" : "";
1429 displaynname = nname ? "(" + nname + ")" : "";
1430 }
1430 }
1431
1431
1432 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1432 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1433 } else {
1433 } else {
1434 return '';
1434 return '';
1435 }
1435 }
1436 };
1436 };
1437 membersAC.formatResult = custom_formatter;
1437 membersAC.formatResult = custom_formatter;
1438 ownerAC.formatResult = custom_formatter;
1438 ownerAC.formatResult = custom_formatter;
1439
1439
1440 var myHandler = function (sType, aArgs) {
1440 var myHandler = function (sType, aArgs) {
1441 var nextId = divid.split('perm_new_member_name_')[1];
1441 var nextId = divid.split('perm_new_member_name_')[1];
1442 var myAC = aArgs[0]; // reference back to the AC instance
1442 var myAC = aArgs[0]; // reference back to the AC instance
1443 var elLI = aArgs[1]; // reference to the selected LI element
1443 var elLI = aArgs[1]; // reference to the selected LI element
1444 var oData = aArgs[2]; // object literal of selected item's result data
1444 var oData = aArgs[2]; // object literal of selected item's result data
1445 //fill the autocomplete with value
1445 //fill the autocomplete with value
1446 if (oData.nname != undefined) {
1446 if (oData.nname != undefined) {
1447 //users
1447 //users
1448 myAC.getInputEl().value = oData.nname;
1448 myAC.getInputEl().value = oData.nname;
1449 YUD.get('perm_new_member_type_'+nextId).value = 'user';
1449 YUD.get('perm_new_member_type_'+nextId).value = 'user';
1450 } else {
1450 } else {
1451 //groups
1451 //groups
1452 myAC.getInputEl().value = oData.grname;
1452 myAC.getInputEl().value = oData.grname;
1453 YUD.get('perm_new_member_type_'+nextId).value = 'users_group';
1453 YUD.get('perm_new_member_type_'+nextId).value = 'users_group';
1454 }
1454 }
1455 };
1455 };
1456
1456
1457 membersAC.itemSelectEvent.subscribe(myHandler);
1457 membersAC.itemSelectEvent.subscribe(myHandler);
1458 if(ownerAC.itemSelectEvent){
1458 if(ownerAC.itemSelectEvent){
1459 ownerAC.itemSelectEvent.subscribe(myHandler);
1459 ownerAC.itemSelectEvent.subscribe(myHandler);
1460 }
1460 }
1461
1461
1462 return {
1462 return {
1463 memberDS: memberDS,
1463 memberDS: memberDS,
1464 ownerDS: ownerDS,
1464 ownerDS: ownerDS,
1465 membersAC: membersAC,
1465 membersAC: membersAC,
1466 ownerAC: ownerAC,
1466 ownerAC: ownerAC,
1467 };
1467 };
1468 }
1468 }
1469
1469
1470
1470
1471 var MentionsAutoComplete = function (divid, cont, users_list, groups_list) {
1471 var MentionsAutoComplete = function (divid, cont, users_list, groups_list) {
1472 var myUsers = users_list;
1472 var myUsers = users_list;
1473 var myGroups = groups_list;
1473 var myGroups = groups_list;
1474
1474
1475 // Define a custom search function for the DataSource of users
1475 // Define a custom search function for the DataSource of users
1476 var matchUsers = function (sQuery) {
1476 var matchUsers = function (sQuery) {
1477 var org_sQuery = sQuery;
1477 var org_sQuery = sQuery;
1478 if(this.mentionQuery == null){
1478 if(this.mentionQuery == null){
1479 return []
1479 return []
1480 }
1480 }
1481 sQuery = this.mentionQuery;
1481 sQuery = this.mentionQuery;
1482 // Case insensitive matching
1482 // Case insensitive matching
1483 var query = sQuery.toLowerCase();
1483 var query = sQuery.toLowerCase();
1484 var i = 0;
1484 var i = 0;
1485 var l = myUsers.length;
1485 var l = myUsers.length;
1486 var matches = [];
1486 var matches = [];
1487
1487
1488 // Match against each name of each contact
1488 // Match against each name of each contact
1489 for (; i < l; i++) {
1489 for (; i < l; i++) {
1490 contact = myUsers[i];
1490 contact = myUsers[i];
1491 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1491 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1492 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1492 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1493 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1493 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1494 matches[matches.length] = contact;
1494 matches[matches.length] = contact;
1495 }
1495 }
1496 }
1496 }
1497 return matches
1497 return matches
1498 };
1498 };
1499
1499
1500 //match all
1500 //match all
1501 var matchAll = function (sQuery) {
1501 var matchAll = function (sQuery) {
1502 u = matchUsers(sQuery);
1502 u = matchUsers(sQuery);
1503 return u
1503 return u
1504 };
1504 };
1505
1505
1506 // DataScheme for owner
1506 // DataScheme for owner
1507 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1507 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1508
1508
1509 ownerDS.responseSchema = {
1509 ownerDS.responseSchema = {
1510 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1510 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1511 };
1511 };
1512
1512
1513 // Instantiate AutoComplete for mentions
1513 // Instantiate AutoComplete for mentions
1514 var ownerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1514 var ownerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1515 ownerAC.useShadow = false;
1515 ownerAC.useShadow = false;
1516 ownerAC.resultTypeList = false;
1516 ownerAC.resultTypeList = false;
1517 ownerAC.suppressInputUpdate = true;
1517 ownerAC.suppressInputUpdate = true;
1518 ownerAC.animVert = false;
1518 ownerAC.animVert = false;
1519 ownerAC.animHoriz = false;
1519 ownerAC.animHoriz = false;
1520 ownerAC.animSpeed = 0.1;
1520 ownerAC.animSpeed = 0.1;
1521
1521
1522 // Helper highlight function for the formatter
1522 // Helper highlight function for the formatter
1523 var highlightMatch = function (full, snippet, matchindex) {
1523 var highlightMatch = function (full, snippet, matchindex) {
1524 return full.substring(0, matchindex)
1524 return full.substring(0, matchindex)
1525 + "<span class='match'>"
1525 + "<span class='match'>"
1526 + full.substr(matchindex, snippet.length)
1526 + full.substr(matchindex, snippet.length)
1527 + "</span>" + full.substring(matchindex + snippet.length);
1527 + "</span>" + full.substring(matchindex + snippet.length);
1528 };
1528 };
1529
1529
1530 // Custom formatter to highlight the matching letters
1530 // Custom formatter to highlight the matching letters
1531 ownerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1531 ownerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1532 var org_sQuery = sQuery;
1532 var org_sQuery = sQuery;
1533 if(this.dataSource.mentionQuery != null){
1533 if(this.dataSource.mentionQuery != null){
1534 sQuery = this.dataSource.mentionQuery;
1534 sQuery = this.dataSource.mentionQuery;
1535 }
1535 }
1536
1536
1537 var query = sQuery.toLowerCase();
1537 var query = sQuery.toLowerCase();
1538 var _gravatar = function(res, em, group){
1538 var _gravatar = function(res, em, group){
1539 if (group !== undefined){
1539 if (group !== undefined){
1540 em = '/images/icons/group.png'
1540 em = '/images/icons/group.png'
1541 }
1541 }
1542 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1542 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1543 return tmpl.format(em,res)
1543 return tmpl.format(em,res)
1544 }
1544 }
1545 if (oResultData.nname != undefined) {
1545 if (oResultData.nname != undefined) {
1546 var fname = oResultData.fname || "";
1546 var fname = oResultData.fname || "";
1547 var lname = oResultData.lname || "";
1547 var lname = oResultData.lname || "";
1548 var nname = oResultData.nname;
1548 var nname = oResultData.nname;
1549
1549
1550 // Guard against null value
1550 // Guard against null value
1551 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1551 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1552 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1552 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1553 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1553 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1554 displayfname, displaylname, displaynname;
1554 displayfname, displaylname, displaynname;
1555
1555
1556 if (fnameMatchIndex > -1) {
1556 if (fnameMatchIndex > -1) {
1557 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1557 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1558 } else {
1558 } else {
1559 displayfname = fname;
1559 displayfname = fname;
1560 }
1560 }
1561
1561
1562 if (lnameMatchIndex > -1) {
1562 if (lnameMatchIndex > -1) {
1563 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1563 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1564 } else {
1564 } else {
1565 displaylname = lname;
1565 displaylname = lname;
1566 }
1566 }
1567
1567
1568 if (nnameMatchIndex > -1) {
1568 if (nnameMatchIndex > -1) {
1569 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1569 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1570 } else {
1570 } else {
1571 displaynname = nname ? "(" + nname + ")" : "";
1571 displaynname = nname ? "(" + nname + ")" : "";
1572 }
1572 }
1573
1573
1574 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1574 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1575 } else {
1575 } else {
1576 return '';
1576 return '';
1577 }
1577 }
1578 };
1578 };
1579
1579
1580 if(ownerAC.itemSelectEvent){
1580 if(ownerAC.itemSelectEvent){
1581 ownerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1581 ownerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1582
1582
1583 var myAC = aArgs[0]; // reference back to the AC instance
1583 var myAC = aArgs[0]; // reference back to the AC instance
1584 var elLI = aArgs[1]; // reference to the selected LI element
1584 var elLI = aArgs[1]; // reference to the selected LI element
1585 var oData = aArgs[2]; // object literal of selected item's result data
1585 var oData = aArgs[2]; // object literal of selected item's result data
1586 //fill the autocomplete with value
1586 //fill the autocomplete with value
1587 if (oData.nname != undefined) {
1587 if (oData.nname != undefined) {
1588 //users
1588 //users
1589 //Replace the mention name with replaced
1589 //Replace the mention name with replaced
1590 var re = new RegExp();
1590 var re = new RegExp();
1591 var org = myAC.getInputEl().value;
1591 var org = myAC.getInputEl().value;
1592 var chunks = myAC.dataSource.chunks
1592 var chunks = myAC.dataSource.chunks
1593 // replace middle chunk(the search term) with actuall match
1593 // replace middle chunk(the search term) with actuall match
1594 chunks[1] = chunks[1].replace('@'+myAC.dataSource.mentionQuery,
1594 chunks[1] = chunks[1].replace('@'+myAC.dataSource.mentionQuery,
1595 '@'+oData.nname+' ');
1595 '@'+oData.nname+' ');
1596 myAC.getInputEl().value = chunks.join('')
1596 myAC.getInputEl().value = chunks.join('')
1597 YUD.get(myAC.getInputEl()).focus(); // Y U NO WORK !?
1597 YUD.get(myAC.getInputEl()).focus(); // Y U NO WORK !?
1598 } else {
1598 } else {
1599 //groups
1599 //groups
1600 myAC.getInputEl().value = oData.grname;
1600 myAC.getInputEl().value = oData.grname;
1601 YUD.get('perm_new_member_type').value = 'users_group';
1601 YUD.get('perm_new_member_type').value = 'users_group';
1602 }
1602 }
1603 });
1603 });
1604 }
1604 }
1605
1605
1606 // in this keybuffer we will gather current value of search !
1606 // in this keybuffer we will gather current value of search !
1607 // since we need to get this just when someone does `@` then we do the
1607 // since we need to get this just when someone does `@` then we do the
1608 // search
1608 // search
1609 ownerAC.dataSource.chunks = [];
1609 ownerAC.dataSource.chunks = [];
1610 ownerAC.dataSource.mentionQuery = null;
1610 ownerAC.dataSource.mentionQuery = null;
1611
1611
1612 ownerAC.get_mention = function(msg, max_pos) {
1612 ownerAC.get_mention = function(msg, max_pos) {
1613 var org = msg;
1613 var org = msg;
1614 var re = new RegExp('(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)$')
1614 var re = new RegExp('(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)$')
1615 var chunks = [];
1615 var chunks = [];
1616
1616
1617
1617
1618 // cut first chunk until curret pos
1618 // cut first chunk until curret pos
1619 var to_max = msg.substr(0, max_pos);
1619 var to_max = msg.substr(0, max_pos);
1620 var at_pos = Math.max(0,to_max.lastIndexOf('@')-1);
1620 var at_pos = Math.max(0,to_max.lastIndexOf('@')-1);
1621 var msg2 = to_max.substr(at_pos);
1621 var msg2 = to_max.substr(at_pos);
1622
1622
1623 chunks.push(org.substr(0,at_pos))// prefix chunk
1623 chunks.push(org.substr(0,at_pos))// prefix chunk
1624 chunks.push(msg2) // search chunk
1624 chunks.push(msg2) // search chunk
1625 chunks.push(org.substr(max_pos)) // postfix chunk
1625 chunks.push(org.substr(max_pos)) // postfix chunk
1626
1626
1627 // clean up msg2 for filtering and regex match
1627 // clean up msg2 for filtering and regex match
1628 var msg2 = msg2.lstrip(' ').lstrip('\n');
1628 var msg2 = msg2.lstrip(' ').lstrip('\n');
1629
1629
1630 if(re.test(msg2)){
1630 if(re.test(msg2)){
1631 var unam = re.exec(msg2)[1];
1631 var unam = re.exec(msg2)[1];
1632 return [unam, chunks];
1632 return [unam, chunks];
1633 }
1633 }
1634 return [null, null];
1634 return [null, null];
1635 };
1635 };
1636
1636
1637 if (ownerAC.textboxKeyUpEvent){
1637 if (ownerAC.textboxKeyUpEvent){
1638 ownerAC.textboxKeyUpEvent.subscribe(function(type, args){
1638 ownerAC.textboxKeyUpEvent.subscribe(function(type, args){
1639
1639
1640 var ac_obj = args[0];
1640 var ac_obj = args[0];
1641 var currentMessage = args[1];
1641 var currentMessage = args[1];
1642 var currentCaretPosition = args[0]._elTextbox.selectionStart;
1642 var currentCaretPosition = args[0]._elTextbox.selectionStart;
1643
1643
1644 var unam = ownerAC.get_mention(currentMessage, currentCaretPosition);
1644 var unam = ownerAC.get_mention(currentMessage, currentCaretPosition);
1645 var curr_search = null;
1645 var curr_search = null;
1646 if(unam[0]){
1646 if(unam[0]){
1647 curr_search = unam[0];
1647 curr_search = unam[0];
1648 }
1648 }
1649
1649
1650 ownerAC.dataSource.chunks = unam[1];
1650 ownerAC.dataSource.chunks = unam[1];
1651 ownerAC.dataSource.mentionQuery = curr_search;
1651 ownerAC.dataSource.mentionQuery = curr_search;
1652
1652
1653 })
1653 })
1654 }
1654 }
1655 return {
1655 return {
1656 ownerDS: ownerDS,
1656 ownerDS: ownerDS,
1657 ownerAC: ownerAC,
1657 ownerAC: ownerAC,
1658 };
1658 };
1659 }
1659 }
1660
1660
1661 var addReviewMember = function(id,fname,lname,nname,gravatar_link){
1661 var addReviewMember = function(id,fname,lname,nname,gravatar_link){
1662 var members = YUD.get('review_members');
1662 var members = YUD.get('review_members');
1663 var tmpl = '<li id="reviewer_{2}">'+
1663 var tmpl = '<li id="reviewer_{2}">'+
1664 '<div class="reviewers_member">'+
1664 '<div class="reviewers_member">'+
1665 '<div class="gravatar"><img alt="gravatar" src="{0}"/> </div>'+
1665 '<div class="gravatar"><img alt="gravatar" src="{0}"/> </div>'+
1666 '<div style="float:left">{1}</div>'+
1666 '<div style="float:left">{1}</div>'+
1667 '<input type="hidden" value="{2}" name="review_members" />'+
1667 '<input type="hidden" value="{2}" name="review_members" />'+
1668 '<span class="delete_icon action_button" onclick="removeReviewMember({2})"></span>'+
1668 '<span class="delete_icon action_button" onclick="removeReviewMember({2})"></span>'+
1669 '</div>'+
1669 '</div>'+
1670 '</li>' ;
1670 '</li>' ;
1671 var displayname = "{0} {1} ({2})".format(fname,lname,nname);
1671 var displayname = "{0} {1} ({2})".format(fname,lname,nname);
1672 var element = tmpl.format(gravatar_link,displayname,id);
1672 var element = tmpl.format(gravatar_link,displayname,id);
1673 // check if we don't have this ID already in
1673 // check if we don't have this ID already in
1674 var ids = [];
1674 var ids = [];
1675 var _els = YUQ('#review_members li');
1675 var _els = YUQ('#review_members li');
1676 for (el in _els){
1676 for (el in _els){
1677 ids.push(_els[el].id)
1677 ids.push(_els[el].id)
1678 }
1678 }
1679 if(ids.indexOf('reviewer_'+id) == -1){
1679 if(ids.indexOf('reviewer_'+id) == -1){
1680 //only add if it's not there
1680 //only add if it's not there
1681 members.innerHTML += element;
1681 members.innerHTML += element;
1682 }
1682 }
1683
1683
1684 }
1684 }
1685
1685
1686 var removeReviewMember = function(reviewer_id, repo_name, pull_request_id){
1686 var removeReviewMember = function(reviewer_id, repo_name, pull_request_id){
1687 var el = YUD.get('reviewer_{0}'.format(reviewer_id));
1687 var el = YUD.get('reviewer_{0}'.format(reviewer_id));
1688 if (el.parentNode !== undefined){
1688 if (el.parentNode !== undefined){
1689 el.parentNode.removeChild(el);
1689 el.parentNode.removeChild(el);
1690 }
1690 }
1691 }
1691 }
1692
1692
1693 var updateReviewers = function(reviewers_ids, repo_name, pull_request_id){
1693 var updateReviewers = function(reviewers_ids, repo_name, pull_request_id){
1694 if (reviewers_ids === undefined){
1694 if (reviewers_ids === undefined){
1695 var reviewers_ids = [];
1695 var reviewers_ids = [];
1696 var ids = YUQ('#review_members input');
1696 var ids = YUQ('#review_members input');
1697 for(var i=0; i<ids.length;i++){
1697 for(var i=0; i<ids.length;i++){
1698 var id = ids[i].value
1698 var id = ids[i].value
1699 reviewers_ids.push(id);
1699 reviewers_ids.push(id);
1700 }
1700 }
1701 }
1701 }
1702 var url = pyroutes.url('pullrequest_update', {"repo_name":repo_name,
1702 var url = pyroutes.url('pullrequest_update', {"repo_name":repo_name,
1703 "pull_request_id": pull_request_id});
1703 "pull_request_id": pull_request_id});
1704 var postData = {'_method':'put',
1704 var postData = {'_method':'put',
1705 'reviewers_ids': reviewers_ids};
1705 'reviewers_ids': reviewers_ids};
1706 var success = function(o){
1706 var success = function(o){
1707 window.location.reload();
1707 window.location.reload();
1708 }
1708 }
1709 ajaxPOST(url,postData,success);
1709 ajaxPOST(url,postData,success);
1710 }
1710 }
1711
1711
1712 var PullRequestAutoComplete = function (divid, cont, users_list, groups_list) {
1712 var PullRequestAutoComplete = function (divid, cont, users_list, groups_list) {
1713 var myUsers = users_list;
1713 var myUsers = users_list;
1714 var myGroups = groups_list;
1714 var myGroups = groups_list;
1715
1715
1716 // Define a custom search function for the DataSource of users
1716 // Define a custom search function for the DataSource of users
1717 var matchUsers = function (sQuery) {
1717 var matchUsers = function (sQuery) {
1718 // Case insensitive matching
1718 // Case insensitive matching
1719 var query = sQuery.toLowerCase();
1719 var query = sQuery.toLowerCase();
1720 var i = 0;
1720 var i = 0;
1721 var l = myUsers.length;
1721 var l = myUsers.length;
1722 var matches = [];
1722 var matches = [];
1723
1723
1724 // Match against each name of each contact
1724 // Match against each name of each contact
1725 for (; i < l; i++) {
1725 for (; i < l; i++) {
1726 contact = myUsers[i];
1726 contact = myUsers[i];
1727 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1727 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1728 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1728 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1729 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1729 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1730 matches[matches.length] = contact;
1730 matches[matches.length] = contact;
1731 }
1731 }
1732 }
1732 }
1733 return matches;
1733 return matches;
1734 };
1734 };
1735
1735
1736 // Define a custom search function for the DataSource of userGroups
1736 // Define a custom search function for the DataSource of userGroups
1737 var matchGroups = function (sQuery) {
1737 var matchGroups = function (sQuery) {
1738 // Case insensitive matching
1738 // Case insensitive matching
1739 var query = sQuery.toLowerCase();
1739 var query = sQuery.toLowerCase();
1740 var i = 0;
1740 var i = 0;
1741 var l = myGroups.length;
1741 var l = myGroups.length;
1742 var matches = [];
1742 var matches = [];
1743
1743
1744 // Match against each name of each contact
1744 // Match against each name of each contact
1745 for (; i < l; i++) {
1745 for (; i < l; i++) {
1746 matched_group = myGroups[i];
1746 matched_group = myGroups[i];
1747 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1747 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1748 matches[matches.length] = matched_group;
1748 matches[matches.length] = matched_group;
1749 }
1749 }
1750 }
1750 }
1751 return matches;
1751 return matches;
1752 };
1752 };
1753
1753
1754 //match all
1754 //match all
1755 var matchAll = function (sQuery) {
1755 var matchAll = function (sQuery) {
1756 u = matchUsers(sQuery);
1756 u = matchUsers(sQuery);
1757 return u
1757 return u
1758 };
1758 };
1759
1759
1760 // DataScheme for owner
1760 // DataScheme for owner
1761 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1761 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1762
1762
1763 ownerDS.responseSchema = {
1763 ownerDS.responseSchema = {
1764 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1764 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1765 };
1765 };
1766
1766
1767 // Instantiate AutoComplete for mentions
1767 // Instantiate AutoComplete for mentions
1768 var reviewerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1768 var reviewerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1769 reviewerAC.useShadow = false;
1769 reviewerAC.useShadow = false;
1770 reviewerAC.resultTypeList = false;
1770 reviewerAC.resultTypeList = false;
1771 reviewerAC.suppressInputUpdate = true;
1771 reviewerAC.suppressInputUpdate = true;
1772 reviewerAC.animVert = false;
1772 reviewerAC.animVert = false;
1773 reviewerAC.animHoriz = false;
1773 reviewerAC.animHoriz = false;
1774 reviewerAC.animSpeed = 0.1;
1774 reviewerAC.animSpeed = 0.1;
1775
1775
1776 // Helper highlight function for the formatter
1776 // Helper highlight function for the formatter
1777 var highlightMatch = function (full, snippet, matchindex) {
1777 var highlightMatch = function (full, snippet, matchindex) {
1778 return full.substring(0, matchindex)
1778 return full.substring(0, matchindex)
1779 + "<span class='match'>"
1779 + "<span class='match'>"
1780 + full.substr(matchindex, snippet.length)
1780 + full.substr(matchindex, snippet.length)
1781 + "</span>" + full.substring(matchindex + snippet.length);
1781 + "</span>" + full.substring(matchindex + snippet.length);
1782 };
1782 };
1783
1783
1784 // Custom formatter to highlight the matching letters
1784 // Custom formatter to highlight the matching letters
1785 reviewerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1785 reviewerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1786 var org_sQuery = sQuery;
1786 var org_sQuery = sQuery;
1787 if(this.dataSource.mentionQuery != null){
1787 if(this.dataSource.mentionQuery != null){
1788 sQuery = this.dataSource.mentionQuery;
1788 sQuery = this.dataSource.mentionQuery;
1789 }
1789 }
1790
1790
1791 var query = sQuery.toLowerCase();
1791 var query = sQuery.toLowerCase();
1792 var _gravatar = function(res, em, group){
1792 var _gravatar = function(res, em, group){
1793 if (group !== undefined){
1793 if (group !== undefined){
1794 em = '/images/icons/group.png'
1794 em = '/images/icons/group.png'
1795 }
1795 }
1796 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1796 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1797 return tmpl.format(em,res)
1797 return tmpl.format(em,res)
1798 }
1798 }
1799 if (oResultData.nname != undefined) {
1799 if (oResultData.nname != undefined) {
1800 var fname = oResultData.fname || "";
1800 var fname = oResultData.fname || "";
1801 var lname = oResultData.lname || "";
1801 var lname = oResultData.lname || "";
1802 var nname = oResultData.nname;
1802 var nname = oResultData.nname;
1803
1803
1804 // Guard against null value
1804 // Guard against null value
1805 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1805 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1806 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1806 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1807 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1807 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1808 displayfname, displaylname, displaynname;
1808 displayfname, displaylname, displaynname;
1809
1809
1810 if (fnameMatchIndex > -1) {
1810 if (fnameMatchIndex > -1) {
1811 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1811 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1812 } else {
1812 } else {
1813 displayfname = fname;
1813 displayfname = fname;
1814 }
1814 }
1815
1815
1816 if (lnameMatchIndex > -1) {
1816 if (lnameMatchIndex > -1) {
1817 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1817 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1818 } else {
1818 } else {
1819 displaylname = lname;
1819 displaylname = lname;
1820 }
1820 }
1821
1821
1822 if (nnameMatchIndex > -1) {
1822 if (nnameMatchIndex > -1) {
1823 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1823 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1824 } else {
1824 } else {
1825 displaynname = nname ? "(" + nname + ")" : "";
1825 displaynname = nname ? "(" + nname + ")" : "";
1826 }
1826 }
1827
1827
1828 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1828 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1829 } else {
1829 } else {
1830 return '';
1830 return '';
1831 }
1831 }
1832 };
1832 };
1833
1833
1834 //members cache to catch duplicates
1834 //members cache to catch duplicates
1835 reviewerAC.dataSource.cache = [];
1835 reviewerAC.dataSource.cache = [];
1836 // hack into select event
1836 // hack into select event
1837 if(reviewerAC.itemSelectEvent){
1837 if(reviewerAC.itemSelectEvent){
1838 reviewerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1838 reviewerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1839
1839
1840 var myAC = aArgs[0]; // reference back to the AC instance
1840 var myAC = aArgs[0]; // reference back to the AC instance
1841 var elLI = aArgs[1]; // reference to the selected LI element
1841 var elLI = aArgs[1]; // reference to the selected LI element
1842 var oData = aArgs[2]; // object literal of selected item's result data
1842 var oData = aArgs[2]; // object literal of selected item's result data
1843
1843
1844 //fill the autocomplete with value
1844 //fill the autocomplete with value
1845
1845
1846 if (oData.nname != undefined) {
1846 if (oData.nname != undefined) {
1847 addReviewMember(oData.id, oData.fname, oData.lname, oData.nname,
1847 addReviewMember(oData.id, oData.fname, oData.lname, oData.nname,
1848 oData.gravatar_lnk);
1848 oData.gravatar_lnk);
1849 myAC.dataSource.cache.push(oData.id);
1849 myAC.dataSource.cache.push(oData.id);
1850 YUD.get('user').value = ''
1850 YUD.get('user').value = ''
1851 }
1851 }
1852 });
1852 });
1853 }
1853 }
1854 return {
1854 return {
1855 ownerDS: ownerDS,
1855 ownerDS: ownerDS,
1856 reviewerAC: reviewerAC,
1856 reviewerAC: reviewerAC,
1857 };
1857 };
1858 }
1858 }
1859
1859
1860 /**
1860 /**
1861 * QUICK REPO MENU
1861 * QUICK REPO MENU
1862 */
1862 */
1863 var quick_repo_menu = function(){
1863 var quick_repo_menu = function(){
1864 YUE.on(YUQ('.quick_repo_menu'),'mouseenter',function(e){
1864 YUE.on(YUQ('.quick_repo_menu'),'mouseenter',function(e){
1865 var menu = e.currentTarget.firstElementChild.firstElementChild;
1865 var menu = e.currentTarget.firstElementChild.firstElementChild;
1866 if(YUD.hasClass(menu,'hidden')){
1866 if(YUD.hasClass(menu,'hidden')){
1867 YUD.replaceClass(e.currentTarget,'hidden', 'active');
1867 YUD.replaceClass(e.currentTarget,'hidden', 'active');
1868 YUD.replaceClass(menu, 'hidden', 'active');
1868 YUD.replaceClass(menu, 'hidden', 'active');
1869 }
1869 }
1870 })
1870 })
1871 YUE.on(YUQ('.quick_repo_menu'),'mouseleave',function(e){
1871 YUE.on(YUQ('.quick_repo_menu'),'mouseleave',function(e){
1872 var menu = e.currentTarget.firstElementChild.firstElementChild;
1872 var menu = e.currentTarget.firstElementChild.firstElementChild;
1873 if(YUD.hasClass(menu,'active')){
1873 if(YUD.hasClass(menu,'active')){
1874 YUD.replaceClass(e.currentTarget, 'active', 'hidden');
1874 YUD.replaceClass(e.currentTarget, 'active', 'hidden');
1875 YUD.replaceClass(menu, 'active', 'hidden');
1875 YUD.replaceClass(menu, 'active', 'hidden');
1876 }
1876 }
1877 })
1877 })
1878 };
1878 };
1879
1879
1880
1880
1881 /**
1881 /**
1882 * TABLE SORTING
1882 * TABLE SORTING
1883 */
1883 */
1884
1884
1885 // returns a node from given html;
1885 // returns a node from given html;
1886 var fromHTML = function(html){
1886 var fromHTML = function(html){
1887 var _html = document.createElement('element');
1887 var _html = document.createElement('element');
1888 _html.innerHTML = html;
1888 _html.innerHTML = html;
1889 return _html;
1889 return _html;
1890 }
1890 }
1891 var get_rev = function(node){
1891 var get_rev = function(node){
1892 var n = node.firstElementChild.firstElementChild;
1892 var n = node.firstElementChild.firstElementChild;
1893
1893
1894 if (n===null){
1894 if (n===null){
1895 return -1
1895 return -1
1896 }
1896 }
1897 else{
1897 else{
1898 out = n.firstElementChild.innerHTML.split(':')[0].replace('r','');
1898 out = n.firstElementChild.innerHTML.split(':')[0].replace('r','');
1899 return parseInt(out);
1899 return parseInt(out);
1900 }
1900 }
1901 }
1901 }
1902
1902
1903 var get_name = function(node){
1903 var get_name = function(node){
1904 var name = node.firstElementChild.children[2].innerHTML;
1904 var name = node.firstElementChild.children[2].innerHTML;
1905 return name
1905 return name
1906 }
1906 }
1907 var get_group_name = function(node){
1907 var get_group_name = function(node){
1908 var name = node.firstElementChild.children[1].innerHTML;
1908 var name = node.firstElementChild.children[1].innerHTML;
1909 return name
1909 return name
1910 }
1910 }
1911 var get_date = function(node){
1911 var get_date = function(node){
1912 var date_ = YUD.getAttribute(node.firstElementChild,'date');
1912 var date_ = YUD.getAttribute(node.firstElementChild,'date');
1913 return date_
1913 return date_
1914 }
1914 }
1915
1915
1916 var get_age = function(node){
1916 var get_age = function(node){
1917 return node
1917 return node
1918 }
1918 }
1919
1919
1920 var get_link = function(node){
1920 var get_link = function(node){
1921 return node.firstElementChild.text;
1921 return node.firstElementChild.text;
1922 }
1922 }
1923
1923
1924 var revisionSort = function(a, b, desc, field) {
1924 var revisionSort = function(a, b, desc, field) {
1925
1925
1926 var a_ = fromHTML(a.getData(field));
1926 var a_ = fromHTML(a.getData(field));
1927 var b_ = fromHTML(b.getData(field));
1927 var b_ = fromHTML(b.getData(field));
1928
1928
1929 // extract revisions from string nodes
1929 // extract revisions from string nodes
1930 a_ = get_rev(a_)
1930 a_ = get_rev(a_)
1931 b_ = get_rev(b_)
1931 b_ = get_rev(b_)
1932
1932
1933 var comp = YAHOO.util.Sort.compare;
1933 var comp = YAHOO.util.Sort.compare;
1934 var compState = comp(a_, b_, desc);
1934 var compState = comp(a_, b_, desc);
1935 return compState;
1935 return compState;
1936 };
1936 };
1937 var ageSort = function(a, b, desc, field) {
1937 var ageSort = function(a, b, desc, field) {
1938 var a_ = fromHTML(a.getData(field));
1938 var a_ = fromHTML(a.getData(field));
1939 var b_ = fromHTML(b.getData(field));
1939 var b_ = fromHTML(b.getData(field));
1940
1940
1941 // extract name from table
1941 // extract name from table
1942 a_ = get_date(a_)
1942 a_ = get_date(a_)
1943 b_ = get_date(b_)
1943 b_ = get_date(b_)
1944
1944
1945 var comp = YAHOO.util.Sort.compare;
1945 var comp = YAHOO.util.Sort.compare;
1946 var compState = comp(a_, b_, desc);
1946 var compState = comp(a_, b_, desc);
1947 return compState;
1947 return compState;
1948 };
1948 };
1949
1949
1950 var lastLoginSort = function(a, b, desc, field) {
1950 var lastLoginSort = function(a, b, desc, field) {
1951 var a_ = a.getData('last_login_raw') || 0;
1951 var a_ = a.getData('last_login_raw') || 0;
1952 var b_ = b.getData('last_login_raw') || 0;
1952 var b_ = b.getData('last_login_raw') || 0;
1953
1953
1954 var comp = YAHOO.util.Sort.compare;
1954 var comp = YAHOO.util.Sort.compare;
1955 var compState = comp(a_, b_, desc);
1955 var compState = comp(a_, b_, desc);
1956 return compState;
1956 return compState;
1957 };
1957 };
1958
1958
1959 var nameSort = function(a, b, desc, field) {
1959 var nameSort = function(a, b, desc, field) {
1960 var a_ = fromHTML(a.getData(field));
1960 var a_ = fromHTML(a.getData(field));
1961 var b_ = fromHTML(b.getData(field));
1961 var b_ = fromHTML(b.getData(field));
1962
1962
1963 // extract name from table
1963 // extract name from table
1964 a_ = get_name(a_)
1964 a_ = get_name(a_)
1965 b_ = get_name(b_)
1965 b_ = get_name(b_)
1966
1966
1967 var comp = YAHOO.util.Sort.compare;
1967 var comp = YAHOO.util.Sort.compare;
1968 var compState = comp(a_, b_, desc);
1968 var compState = comp(a_, b_, desc);
1969 return compState;
1969 return compState;
1970 };
1970 };
1971
1971
1972 var permNameSort = function(a, b, desc, field) {
1972 var permNameSort = function(a, b, desc, field) {
1973 var a_ = fromHTML(a.getData(field));
1973 var a_ = fromHTML(a.getData(field));
1974 var b_ = fromHTML(b.getData(field));
1974 var b_ = fromHTML(b.getData(field));
1975 // extract name from table
1975 // extract name from table
1976
1976
1977 a_ = a_.children[0].innerHTML;
1977 a_ = a_.children[0].innerHTML;
1978 b_ = b_.children[0].innerHTML;
1978 b_ = b_.children[0].innerHTML;
1979
1979
1980 var comp = YAHOO.util.Sort.compare;
1980 var comp = YAHOO.util.Sort.compare;
1981 var compState = comp(a_, b_, desc);
1981 var compState = comp(a_, b_, desc);
1982 return compState;
1982 return compState;
1983 };
1983 };
1984
1984
1985 var groupNameSort = function(a, b, desc, field) {
1985 var groupNameSort = function(a, b, desc, field) {
1986 var a_ = fromHTML(a.getData(field));
1986 var a_ = fromHTML(a.getData(field));
1987 var b_ = fromHTML(b.getData(field));
1987 var b_ = fromHTML(b.getData(field));
1988
1988
1989 // extract name from table
1989 // extract name from table
1990 a_ = get_group_name(a_)
1990 a_ = get_group_name(a_)
1991 b_ = get_group_name(b_)
1991 b_ = get_group_name(b_)
1992
1992
1993 var comp = YAHOO.util.Sort.compare;
1993 var comp = YAHOO.util.Sort.compare;
1994 var compState = comp(a_, b_, desc);
1994 var compState = comp(a_, b_, desc);
1995 return compState;
1995 return compState;
1996 };
1996 };
1997 var dateSort = function(a, b, desc, field) {
1997 var dateSort = function(a, b, desc, field) {
1998 var a_ = fromHTML(a.getData(field));
1998 var a_ = fromHTML(a.getData(field));
1999 var b_ = fromHTML(b.getData(field));
1999 var b_ = fromHTML(b.getData(field));
2000
2000
2001 // extract name from table
2001 // extract name from table
2002 a_ = get_date(a_)
2002 a_ = get_date(a_)
2003 b_ = get_date(b_)
2003 b_ = get_date(b_)
2004
2004
2005 var comp = YAHOO.util.Sort.compare;
2005 var comp = YAHOO.util.Sort.compare;
2006 var compState = comp(a_, b_, desc);
2006 var compState = comp(a_, b_, desc);
2007 return compState;
2007 return compState;
2008 };
2008 };
2009
2009
2010 var usernamelinkSort = function(a, b, desc, field) {
2010 var usernamelinkSort = function(a, b, desc, field) {
2011 var a_ = fromHTML(a.getData(field));
2011 var a_ = fromHTML(a.getData(field));
2012 var b_ = fromHTML(b.getData(field));
2012 var b_ = fromHTML(b.getData(field));
2013
2013
2014 // extract url text from string nodes
2014 // extract url text from string nodes
2015 a_ = get_link(a_)
2015 a_ = get_link(a_)
2016 b_ = get_link(b_)
2016 b_ = get_link(b_)
2017 var comp = YAHOO.util.Sort.compare;
2017 var comp = YAHOO.util.Sort.compare;
2018 var compState = comp(a_, b_, desc);
2018 var compState = comp(a_, b_, desc);
2019 return compState;
2019 return compState;
2020 }
2020 }
2021
2021
2022 var addPermAction = function(_html, users_list, groups_list){
2022 var addPermAction = function(_html, users_list, groups_list){
2023 var elmts = YUD.getElementsByClassName('last_new_member');
2023 var elmts = YUD.getElementsByClassName('last_new_member');
2024 var last_node = elmts[elmts.length-1];
2024 var last_node = elmts[elmts.length-1];
2025 if (last_node){
2025 if (last_node){
2026 var next_id = (YUD.getElementsByClassName('new_members')).length;
2026 var next_id = (YUD.getElementsByClassName('new_members')).length;
2027 _html = _html.format(next_id);
2027 _html = _html.format(next_id);
2028 last_node.innerHTML = _html;
2028 last_node.innerHTML = _html;
2029 YUD.setStyle(last_node, 'display', '');
2029 YUD.setStyle(last_node, 'display', '');
2030 YUD.removeClass(last_node, 'last_new_member');
2030 YUD.removeClass(last_node, 'last_new_member');
2031 MembersAutoComplete("perm_new_member_name_"+next_id,
2031 MembersAutoComplete("perm_new_member_name_"+next_id,
2032 "perm_container_"+next_id, users_list, groups_list);
2032 "perm_container_"+next_id, users_list, groups_list);
2033 //create new last NODE
2033 //create new last NODE
2034 var el = document.createElement('tr');
2034 var el = document.createElement('tr');
2035 el.id = 'add_perm_input';
2035 el.id = 'add_perm_input';
2036 YUD.addClass(el,'last_new_member');
2036 YUD.addClass(el,'last_new_member');
2037 YUD.addClass(el,'new_members');
2037 YUD.addClass(el,'new_members');
2038 YUD.insertAfter(el, last_node);
2038 YUD.insertAfter(el, last_node);
2039 }
2039 }
2040 }
2040 }
2041 function ajaxActionRevokePermission(url, obj_id, obj_type, field_id, extra_data) {
2041 function ajaxActionRevokePermission(url, obj_id, obj_type, field_id, extra_data) {
2042 var callback = {
2042 var callback = {
2043 success: function (o) {
2043 success: function (o) {
2044 var tr = YUD.get(String(field_id));
2044 var tr = YUD.get(String(field_id));
2045 tr.parentNode.removeChild(tr);
2045 tr.parentNode.removeChild(tr);
2046 },
2046 },
2047 failure: function (o) {
2047 failure: function (o) {
2048 alert(_TM['Failed to remoke permission'] + ": " + o.status);
2048 alert(_TM['Failed to remoke permission'] + ": " + o.status);
2049 },
2049 },
2050 };
2050 };
2051 query_params = {
2051 query_params = {
2052 '_method': 'delete'
2052 '_method': 'delete'
2053 }
2053 }
2054 // put extra data into POST
2054 // put extra data into POST
2055 if (extra_data !== undefined && (typeof extra_data === 'object')){
2055 if (extra_data !== undefined && (typeof extra_data === 'object')){
2056 for(k in extra_data){
2056 for(k in extra_data){
2057 query_params[k] = extra_data[k];
2057 query_params[k] = extra_data[k];
2058 }
2058 }
2059 }
2059 }
2060
2060
2061 if (obj_type=='user'){
2061 if (obj_type=='user'){
2062 query_params['user_id'] = obj_id;
2062 query_params['user_id'] = obj_id;
2063 query_params['obj_type'] = 'user';
2063 query_params['obj_type'] = 'user';
2064 }
2064 }
2065 else if (obj_type=='user_group'){
2065 else if (obj_type=='user_group'){
2066 query_params['user_group_id'] = obj_id;
2066 query_params['user_group_id'] = obj_id;
2067 query_params['obj_type'] = 'user_group';
2067 query_params['obj_type'] = 'user_group';
2068 }
2068 }
2069
2069
2070 var request = YAHOO.util.Connect.asyncRequest('POST', url, callback,
2070 var request = YAHOO.util.Connect.asyncRequest('POST', url, callback,
2071 toQueryString(query_params));
2071 toQueryString(query_params));
2072 };
2072 };
2073 /* Multi selectors */
2073 /* Multi selectors */
2074
2074
2075 var MultiSelectWidget = function(selected_id, available_id, form_id){
2075 var MultiSelectWidget = function(selected_id, available_id, form_id){
2076
2076
2077
2077
2078 //definition of containers ID's
2078 //definition of containers ID's
2079 var selected_container = selected_id;
2079 var selected_container = selected_id;
2080 var available_container = available_id;
2080 var available_container = available_id;
2081
2081
2082 //temp container for selected storage.
2082 //temp container for selected storage.
2083 var cache = new Array();
2083 var cache = new Array();
2084 var av_cache = new Array();
2084 var av_cache = new Array();
2085 var c = YUD.get(selected_container);
2085 var c = YUD.get(selected_container);
2086 var ac = YUD.get(available_container);
2086 var ac = YUD.get(available_container);
2087
2087
2088 //get only selected options for further fullfilment
2088 //get only selected options for further fullfilment
2089 for(var i = 0;node =c.options[i];i++){
2089 for(var i = 0;node =c.options[i];i++){
2090 if(node.selected){
2090 if(node.selected){
2091 //push selected to my temp storage left overs :)
2091 //push selected to my temp storage left overs :)
2092 cache.push(node);
2092 cache.push(node);
2093 }
2093 }
2094 }
2094 }
2095
2095
2096 //get all available options to cache
2096 //get all available options to cache
2097 for(var i = 0;node =ac.options[i];i++){
2097 for(var i = 0;node =ac.options[i];i++){
2098 //push selected to my temp storage left overs :)
2098 //push selected to my temp storage left overs :)
2099 av_cache.push(node);
2099 av_cache.push(node);
2100 }
2100 }
2101
2101
2102 //fill available only with those not in chosen
2102 //fill available only with those not in chosen
2103 ac.options.length=0;
2103 ac.options.length=0;
2104 tmp_cache = new Array();
2104 tmp_cache = new Array();
2105
2105
2106 for(var i = 0;node = av_cache[i];i++){
2106 for(var i = 0;node = av_cache[i];i++){
2107 var add = true;
2107 var add = true;
2108 for(var i2 = 0;node_2 = cache[i2];i2++){
2108 for(var i2 = 0;node_2 = cache[i2];i2++){
2109 if(node.value == node_2.value){
2109 if(node.value == node_2.value){
2110 add=false;
2110 add=false;
2111 break;
2111 break;
2112 }
2112 }
2113 }
2113 }
2114 if(add){
2114 if(add){
2115 tmp_cache.push(new Option(node.text, node.value, false, false));
2115 tmp_cache.push(new Option(node.text, node.value, false, false));
2116 }
2116 }
2117 }
2117 }
2118
2118
2119 for(var i = 0;node = tmp_cache[i];i++){
2119 for(var i = 0;node = tmp_cache[i];i++){
2120 ac.options[i] = node;
2120 ac.options[i] = node;
2121 }
2121 }
2122
2122
2123 function prompts_action_callback(e){
2123 function prompts_action_callback(e){
2124
2124
2125 var chosen = YUD.get(selected_container);
2125 var chosen = YUD.get(selected_container);
2126 var available = YUD.get(available_container);
2126 var available = YUD.get(available_container);
2127
2127
2128 //get checked and unchecked options from field
2128 //get checked and unchecked options from field
2129 function get_checked(from_field){
2129 function get_checked(from_field){
2130 //temp container for storage.
2130 //temp container for storage.
2131 var sel_cache = new Array();
2131 var sel_cache = new Array();
2132 var oth_cache = new Array();
2132 var oth_cache = new Array();
2133
2133
2134 for(var i = 0;node = from_field.options[i];i++){
2134 for(var i = 0;node = from_field.options[i];i++){
2135 if(node.selected){
2135 if(node.selected){
2136 //push selected fields :)
2136 //push selected fields :)
2137 sel_cache.push(node);
2137 sel_cache.push(node);
2138 }
2138 }
2139 else{
2139 else{
2140 oth_cache.push(node)
2140 oth_cache.push(node)
2141 }
2141 }
2142 }
2142 }
2143
2143
2144 return [sel_cache,oth_cache]
2144 return [sel_cache,oth_cache]
2145 }
2145 }
2146
2146
2147 //fill the field with given options
2147 //fill the field with given options
2148 function fill_with(field,options){
2148 function fill_with(field,options){
2149 //clear firtst
2149 //clear firtst
2150 field.options.length=0;
2150 field.options.length=0;
2151 for(var i = 0;node = options[i];i++){
2151 for(var i = 0;node = options[i];i++){
2152 field.options[i]=new Option(node.text, node.value,
2152 field.options[i]=new Option(node.text, node.value,
2153 false, false);
2153 false, false);
2154 }
2154 }
2155
2155
2156 }
2156 }
2157 //adds to current field
2157 //adds to current field
2158 function add_to(field,options){
2158 function add_to(field,options){
2159 for(var i = 0;node = options[i];i++){
2159 for(var i = 0;node = options[i];i++){
2160 field.appendChild(new Option(node.text, node.value,
2160 field.appendChild(new Option(node.text, node.value,
2161 false, false));
2161 false, false));
2162 }
2162 }
2163 }
2163 }
2164
2164
2165 // add action
2165 // add action
2166 if (this.id=='add_element'){
2166 if (this.id=='add_element'){
2167 var c = get_checked(available);
2167 var c = get_checked(available);
2168 add_to(chosen,c[0]);
2168 add_to(chosen,c[0]);
2169 fill_with(available,c[1]);
2169 fill_with(available,c[1]);
2170 }
2170 }
2171 // remove action
2171 // remove action
2172 if (this.id=='remove_element'){
2172 if (this.id=='remove_element'){
2173 var c = get_checked(chosen);
2173 var c = get_checked(chosen);
2174 add_to(available,c[0]);
2174 add_to(available,c[0]);
2175 fill_with(chosen,c[1]);
2175 fill_with(chosen,c[1]);
2176 }
2176 }
2177 // add all elements
2177 // add all elements
2178 if(this.id=='add_all_elements'){
2178 if(this.id=='add_all_elements'){
2179 for(var i=0; node = available.options[i];i++){
2179 for(var i=0; node = available.options[i];i++){
2180 chosen.appendChild(new Option(node.text,
2180 chosen.appendChild(new Option(node.text,
2181 node.value, false, false));
2181 node.value, false, false));
2182 }
2182 }
2183 available.options.length = 0;
2183 available.options.length = 0;
2184 }
2184 }
2185 //remove all elements
2185 //remove all elements
2186 if(this.id=='remove_all_elements'){
2186 if(this.id=='remove_all_elements'){
2187 for(var i=0; node = chosen.options[i];i++){
2187 for(var i=0; node = chosen.options[i];i++){
2188 available.appendChild(new Option(node.text,
2188 available.appendChild(new Option(node.text,
2189 node.value, false, false));
2189 node.value, false, false));
2190 }
2190 }
2191 chosen.options.length = 0;
2191 chosen.options.length = 0;
2192 }
2192 }
2193
2193
2194 }
2194 }
2195
2195
2196 YUE.addListener(['add_element','remove_element',
2196 YUE.addListener(['add_element','remove_element',
2197 'add_all_elements','remove_all_elements'],'click',
2197 'add_all_elements','remove_all_elements'],'click',
2198 prompts_action_callback)
2198 prompts_action_callback)
2199 if (form_id !== undefined) {
2199 if (form_id !== undefined) {
2200 YUE.addListener(form_id,'submit',function(){
2200 YUE.addListener(form_id,'submit',function(){
2201 var chosen = YUD.get(selected_container);
2201 var chosen = YUD.get(selected_container);
2202 for (var i = 0; i < chosen.options.length; i++) {
2202 for (var i = 0; i < chosen.options.length; i++) {
2203 chosen.options[i].selected = 'selected';
2203 chosen.options[i].selected = 'selected';
2204 }
2204 }
2205 });
2205 });
2206 }
2206 }
2207 }
2207 }
2208
2208
2209
2209
2210
2211
2212 var YUI_paginator = function(links_per_page, containers){
2213 // my custom paginator
2214 (function () {
2215
2216 var Paginator = YAHOO.widget.Paginator,
2217 l = YAHOO.lang,
2218 setId = YAHOO.util.Dom.generateId;
2219
2220 Paginator.ui.MyFirstPageLink = function (p) {
2221 this.paginator = p;
2222
2223 p.subscribe('recordOffsetChange',this.update,this,true);
2224 p.subscribe('rowsPerPageChange',this.update,this,true);
2225 p.subscribe('totalRecordsChange',this.update,this,true);
2226 p.subscribe('destroy',this.destroy,this,true);
2227
2228 // TODO: make this work
2229 p.subscribe('firstPageLinkLabelChange',this.update,this,true);
2230 p.subscribe('firstPageLinkClassChange',this.update,this,true);
2231 };
2232
2233 Paginator.ui.MyFirstPageLink.init = function (p) {
2234 p.setAttributeConfig('firstPageLinkLabel', {
2235 value : 1,
2236 validator : l.isString
2237 });
2238 p.setAttributeConfig('firstPageLinkClass', {
2239 value : 'yui-pg-first',
2240 validator : l.isString
2241 });
2242 p.setAttributeConfig('firstPageLinkTitle', {
2243 value : 'First Page',
2244 validator : l.isString
2245 });
2246 };
2247
2248 // Instance members and methods
2249 Paginator.ui.MyFirstPageLink.prototype = {
2250 current : null,
2251 leftmost_page: null,
2252 rightmost_page: null,
2253 link : null,
2254 span : null,
2255 dotdot : null,
2256 getPos : function(cur_page, max_page, items){
2257 var edge = parseInt(items / 2) + 1;
2258 if (cur_page <= edge){
2259 var radius = Math.max(parseInt(items / 2), items - cur_page);
2260 }
2261 else if ((max_page - cur_page) < edge) {
2262 var radius = (items - 1) - (max_page - cur_page);
2263 }
2264 else{
2265 var radius = parseInt(items / 2);
2266 }
2267
2268 var left = Math.max(1, (cur_page - (radius)))
2269 var right = Math.min(max_page, cur_page + (radius))
2270 return [left, cur_page, right]
2271 },
2272 render : function (id_base) {
2273 var p = this.paginator,
2274 c = p.get('firstPageLinkClass'),
2275 label = p.get('firstPageLinkLabel'),
2276 title = p.get('firstPageLinkTitle');
2277
2278 this.link = document.createElement('a');
2279 this.span = document.createElement();
2280
2281 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2282 this.leftmost_page = _pos[0];
2283 this.rightmost_page = _pos[2];
2284
2285 setId(this.link, id_base + '-first-link');
2286 this.link.href = '#';
2287 this.link.className = c;
2288 this.link.innerHTML = label;
2289 this.link.title = title;
2290 YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
2291
2292 setId(this.span, id_base + '-first-span');
2293 this.span.className = c;
2294 this.span.innerHTML = label;
2295
2296 this.current = p.getCurrentPage() > 1 ? this.link : this.span;
2297 return this.current;
2298 },
2299 update : function (e) {
2300 var p = this.paginator;
2301 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2302 this.leftmost_page = _pos[0];
2303 this.rightmost_page = _pos[2];
2304
2305 if (e && e.prevValue === e.newValue) {
2306 return;
2307 }
2308
2309 var par = this.current ? this.current.parentNode : null;
2310 if (this.leftmost_page > 1) {
2311 if (par && this.current === this.span) {
2312 par.replaceChild(this.link,this.current);
2313 this.current = this.link;
2314 }
2315 } else {
2316 if (par && this.current === this.link) {
2317 par.replaceChild(this.span,this.current);
2318 this.current = this.span;
2319 }
2320 }
2321 },
2322 destroy : function () {
2323 YAHOO.util.Event.purgeElement(this.link);
2324 this.current.parentNode.removeChild(this.current);
2325 this.link = this.span = null;
2326 },
2327 onClick : function (e) {
2328 YAHOO.util.Event.stopEvent(e);
2329 this.paginator.setPage(1);
2330 }
2331 };
2332
2333 })();
2334 (function () {
2335
2336 var Paginator = YAHOO.widget.Paginator,
2337 l = YAHOO.lang,
2338 setId = YAHOO.util.Dom.generateId;
2339
2340 Paginator.ui.MyLastPageLink = function (p) {
2341 this.paginator = p;
2342
2343 p.subscribe('recordOffsetChange',this.update,this,true);
2344 p.subscribe('rowsPerPageChange',this.update,this,true);
2345 p.subscribe('totalRecordsChange',this.update,this,true);
2346 p.subscribe('destroy',this.destroy,this,true);
2347
2348 // TODO: make this work
2349 p.subscribe('lastPageLinkLabelChange',this.update,this,true);
2350 p.subscribe('lastPageLinkClassChange', this.update,this,true);
2351 };
2352
2353 Paginator.ui.MyLastPageLink.init = function (p) {
2354 p.setAttributeConfig('lastPageLinkLabel', {
2355 value : -1,
2356 validator : l.isString
2357 });
2358 p.setAttributeConfig('lastPageLinkClass', {
2359 value : 'yui-pg-last',
2360 validator : l.isString
2361 });
2362 p.setAttributeConfig('lastPageLinkTitle', {
2363 value : 'Last Page',
2364 validator : l.isString
2365 });
2366
2367 };
2368
2369 Paginator.ui.MyLastPageLink.prototype = {
2370
2371 current : null,
2372 leftmost_page: null,
2373 rightmost_page: null,
2374 link : null,
2375 span : null,
2376 dotdot : null,
2377 na : null,
2378 getPos : function(cur_page, max_page, items){
2379 var edge = parseInt(items / 2) + 1;
2380 if (cur_page <= edge){
2381 var radius = Math.max(parseInt(items / 2), items - cur_page);
2382 }
2383 else if ((max_page - cur_page) < edge) {
2384 var radius = (items - 1) - (max_page - cur_page);
2385 }
2386 else{
2387 var radius = parseInt(items / 2);
2388 }
2389
2390 var left = Math.max(1, (cur_page - (radius)))
2391 var right = Math.min(max_page, cur_page + (radius))
2392 return [left, cur_page, right]
2393 },
2394 render : function (id_base) {
2395 var p = this.paginator,
2396 c = p.get('lastPageLinkClass'),
2397 label = p.get('lastPageLinkLabel'),
2398 last = p.getTotalPages(),
2399 title = p.get('lastPageLinkTitle');
2400
2401 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2402 this.leftmost_page = _pos[0];
2403 this.rightmost_page = _pos[2];
2404
2405 this.link = document.createElement('a');
2406 this.span = document.createElement();
2407 this.na = this.span.cloneNode(false);
2408
2409 setId(this.link, id_base + '-last-link');
2410 this.link.href = '#';
2411 this.link.className = c;
2412 this.link.innerHTML = label;
2413 this.link.title = title;
2414 YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
2415
2416 setId(this.span, id_base + '-last-span');
2417 this.span.className = c;
2418 this.span.innerHTML = label;
2419
2420 setId(this.na, id_base + '-last-na');
2421
2422 if (this.rightmost_page < p.getTotalPages()){
2423 this.current = this.link;
2424 }
2425 else{
2426 this.current = this.span;
2427 }
2428
2429 this.current.innerHTML = p.getTotalPages();
2430 return this.current;
2431 },
2432
2433 update : function (e) {
2434 var p = this.paginator;
2435
2436 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2437 this.leftmost_page = _pos[0];
2438 this.rightmost_page = _pos[2];
2439
2440 if (e && e.prevValue === e.newValue) {
2441 return;
2442 }
2443
2444 var par = this.current ? this.current.parentNode : null,
2445 after = this.link;
2446 if (par) {
2447
2448 // only show the last page if the rightmost one is
2449 // lower, so we don't have doubled entries at the end
2450 if (!(this.rightmost_page < p.getTotalPages())){
2451 after = this.span
2452 }
2453
2454 if (this.current !== after) {
2455 par.replaceChild(after,this.current);
2456 this.current = after;
2457 }
2458 }
2459 this.current.innerHTML = this.paginator.getTotalPages();
2460
2461 },
2462 destroy : function () {
2463 YAHOO.util.Event.purgeElement(this.link);
2464 this.current.parentNode.removeChild(this.current);
2465 this.link = this.span = null;
2466 },
2467 onClick : function (e) {
2468 YAHOO.util.Event.stopEvent(e);
2469 this.paginator.setPage(this.paginator.getTotalPages());
2470 }
2471 };
2472
2473 })();
2474
2475 var pagi = new YAHOO.widget.Paginator({
2476 rowsPerPage: links_per_page,
2477 alwaysVisible: false,
2478 template : "{PreviousPageLink} {MyFirstPageLink} {PageLinks} {MyLastPageLink} {NextPageLink}",
2479 pageLinks: 5,
2480 containerClass: 'pagination-wh',
2481 currentPageClass: 'pager_curpage',
2482 pageLinkClass: 'pager_link',
2483 nextPageLinkLabel: '&gt;',
2484 previousPageLinkLabel: '&lt;',
2485 containers:containers
2486 })
2487
2488 return pagi
2489 }
2490
2491
2492
2210 // global hooks after DOM is loaded
2493 // global hooks after DOM is loaded
2211
2494
2212 YUE.onDOMReady(function(){
2495 YUE.onDOMReady(function(){
2213 YUE.on(YUQ('.diff-collapse-button'), 'click', function(e){
2496 YUE.on(YUQ('.diff-collapse-button'), 'click', function(e){
2214 var button = e.currentTarget;
2497 var button = e.currentTarget;
2215 var t = YUD.get(button).getAttribute('target');
2498 var t = YUD.get(button).getAttribute('target');
2216 console.log(t);
2499 console.log(t);
2217 if(YUD.hasClass(t, 'hidden')){
2500 if(YUD.hasClass(t, 'hidden')){
2218 YUD.removeClass(t, 'hidden');
2501 YUD.removeClass(t, 'hidden');
2219 YUD.get(button).innerHTML = "&uarr; {0} &uarr;".format(_TM['Collapse diff']);
2502 YUD.get(button).innerHTML = "&uarr; {0} &uarr;".format(_TM['Collapse diff']);
2220 }
2503 }
2221 else if(!YUD.hasClass(t, 'hidden')){
2504 else if(!YUD.hasClass(t, 'hidden')){
2222 YUD.addClass(t, 'hidden');
2505 YUD.addClass(t, 'hidden');
2223 YUD.get(button).innerHTML = "&darr; {0} &darr;".format(_TM['Expand diff']);
2506 YUD.get(button).innerHTML = "&darr; {0} &darr;".format(_TM['Expand diff']);
2224 }
2507 }
2225 });
2508 });
2226
2509
2227
2510
2228
2511
2229 });
2512 });
@@ -1,141 +1,128 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Repositories administration')} &middot; ${c.rhodecode_name}
5 ${_('Repositories administration')} &middot; ${c.rhodecode_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; <span id="repo_count">0</span> ${_('repositories')}
9 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; <span id="repo_count">0</span> ${_('repositories')}
10 </%def>
10 </%def>
11 <%def name="page_nav()">
11 <%def name="page_nav()">
12 ${self.menu('admin')}
12 ${self.menu('admin')}
13 </%def>
13 </%def>
14 <%def name="main()">
14 <%def name="main()">
15 <div class="box">
15 <div class="box">
16
16
17 <div class="title">
17 <div class="title">
18 ${self.breadcrumbs()}
18 ${self.breadcrumbs()}
19 <ul class="links">
19 <ul class="links">
20 <li>
20 <li>
21 <span>${h.link_to(_(u'Add repository'),h.url('new_repo'))}</span>
21 <span>${h.link_to(_(u'Add repository'),h.url('new_repo'))}</span>
22 </li>
22 </li>
23 </ul>
23 </ul>
24 </div>
24 </div>
25 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
25 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
26 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
26 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
27
27
28
28
29 </div>
29 </div>
30 <script>
30 <script>
31 var url = "${h.url('formatted_users', format='json')}";
31 var url = "${h.url('formatted_users', format='json')}";
32 var data = ${c.data|n};
32 var data = ${c.data|n};
33 var myDataSource = new YAHOO.util.DataSource(data);
33 var myDataSource = new YAHOO.util.DataSource(data);
34 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
34 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
35
35
36 myDataSource.responseSchema = {
36 myDataSource.responseSchema = {
37 resultsList: "records",
37 resultsList: "records",
38 fields: [
38 fields: [
39 {key:"menu"},
39 {key:"menu"},
40 {key:"raw_name"},
40 {key:"raw_name"},
41 {key:"name"},
41 {key:"name"},
42 {key:"desc"},
42 {key:"desc"},
43 {key:"last_changeset"},
43 {key:"last_changeset"},
44 {key:"owner"},
44 {key:"owner"},
45 {key:"action"},
45 {key:"action"},
46 ]
46 ]
47 };
47 };
48 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
48 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
49 // This is the filter function
49 // This is the filter function
50 var data = res.results || [],
50 var data = res.results || [],
51 filtered = [],
51 filtered = [],
52 i,l;
52 i,l;
53
53
54 if (req) {
54 if (req) {
55 req = req.toLowerCase();
55 req = req.toLowerCase();
56 for (i = 0; i<data.length; i++) {
56 for (i = 0; i<data.length; i++) {
57 var pos = data[i].raw_name.toLowerCase().indexOf(req)
57 var pos = data[i].raw_name.toLowerCase().indexOf(req)
58 if (pos != -1) {
58 if (pos != -1) {
59 filtered.push(data[i]);
59 filtered.push(data[i]);
60 }
60 }
61 }
61 }
62 res.results = filtered;
62 res.results = filtered;
63 }
63 }
64 YUD.get('repo_count').innerHTML = res.results.length;
64 YUD.get('repo_count').innerHTML = res.results.length;
65 return res;
65 return res;
66 }
66 }
67
67
68 // main table sorting
68 // main table sorting
69 var myColumnDefs = [
69 var myColumnDefs = [
70 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
70 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
71 {key:"name",label:"${_('Name')}",sortable:true,
71 {key:"name",label:"${_('Name')}",sortable:true,
72 sortOptions: { sortFunction: nameSort }},
72 sortOptions: { sortFunction: nameSort }},
73 {key:"desc",label:"${_('Description')}",sortable:true},
73 {key:"desc",label:"${_('Description')}",sortable:true},
74 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
74 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
75 sortOptions: { sortFunction: revisionSort }},
75 sortOptions: { sortFunction: revisionSort }},
76 {key:"owner",label:"${_('Owner')}",sortable:true},
76 {key:"owner",label:"${_('Owner')}",sortable:true},
77 {key:"action",label:"${_('Action')}",sortable:false},
77 {key:"action",label:"${_('Action')}",sortable:false},
78 ];
78 ];
79
79
80 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
80 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
81 sortedBy:{key:"name",dir:"asc"},
81 sortedBy:{key:"name",dir:"asc"},
82 paginator: new YAHOO.widget.Paginator({
82 paginator: YUI_paginator(25, ['user-paginator']),
83 rowsPerPage: 25,
84 alwaysVisible: false,
85 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
86 pageLinks: 5,
87 containerClass: 'pagination-wh',
88 currentPageClass: 'pager_curpage',
89 pageLinkClass: 'pager_link',
90 nextPageLinkLabel: '&gt;',
91 previousPageLinkLabel: '&lt;',
92 firstPageLinkLabel: '&lt;&lt;',
93 lastPageLinkLabel: '&gt;&gt;',
94 containers:['user-paginator']
95 }),
96
83
97 MSG_SORTASC:"${_('Click to sort ascending')}",
84 MSG_SORTASC:"${_('Click to sort ascending')}",
98 MSG_SORTDESC:"${_('Click to sort descending')}",
85 MSG_SORTDESC:"${_('Click to sort descending')}",
99 MSG_EMPTY:"${_('No records found.')}",
86 MSG_EMPTY:"${_('No records found.')}",
100 MSG_ERROR:"${_('Data error.')}",
87 MSG_ERROR:"${_('Data error.')}",
101 MSG_LOADING:"${_('Loading...')}",
88 MSG_LOADING:"${_('Loading...')}",
102 }
89 }
103 );
90 );
104 myDataTable.subscribe('postRenderEvent',function(oArgs) {
91 myDataTable.subscribe('postRenderEvent',function(oArgs) {
105 tooltip_activate();
92 tooltip_activate();
106 quick_repo_menu();
93 quick_repo_menu();
107 });
94 });
108
95
109 var filterTimeout = null;
96 var filterTimeout = null;
110
97
111 updateFilter = function () {
98 updateFilter = function () {
112 // Reset timeout
99 // Reset timeout
113 filterTimeout = null;
100 filterTimeout = null;
114
101
115 // Reset sort
102 // Reset sort
116 var state = myDataTable.getState();
103 var state = myDataTable.getState();
117 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
104 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
118
105
119 // Get filtered data
106 // Get filtered data
120 myDataSource.sendRequest(YUD.get('q_filter').value,{
107 myDataSource.sendRequest(YUD.get('q_filter').value,{
121 success : myDataTable.onDataReturnInitializeTable,
108 success : myDataTable.onDataReturnInitializeTable,
122 failure : myDataTable.onDataReturnInitializeTable,
109 failure : myDataTable.onDataReturnInitializeTable,
123 scope : myDataTable,
110 scope : myDataTable,
124 argument: state
111 argument: state
125 });
112 });
126
113
127 };
114 };
128 YUE.on('q_filter','click',function(){
115 YUE.on('q_filter','click',function(){
129 if(!YUD.hasClass('q_filter', 'loaded')){
116 if(!YUD.hasClass('q_filter', 'loaded')){
130 //TODO: load here full list later to do search within groups
117 //TODO: load here full list later to do search within groups
131 YUD.addClass('q_filter', 'loaded');
118 YUD.addClass('q_filter', 'loaded');
132 }
119 }
133 });
120 });
134
121
135 YUE.on('q_filter','keyup',function (e) {
122 YUE.on('q_filter','keyup',function (e) {
136 clearTimeout(filterTimeout);
123 clearTimeout(filterTimeout);
137 filterTimeout = setTimeout(updateFilter,600);
124 filterTimeout = setTimeout(updateFilter,600);
138 });
125 });
139 </script>
126 </script>
140
127
141 </%def>
128 </%def>
@@ -1,241 +1,228 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('My account')} ${c.rhodecode_user.username} &middot; ${c.rhodecode_name}
5 ${_('My account')} ${c.rhodecode_user.username} &middot; ${c.rhodecode_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${_('My Account')}
9 ${_('My Account')}
10 </%def>
10 </%def>
11
11
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 </%def>
14 </%def>
15
15
16 <%def name="main()">
16 <%def name="main()">
17
17
18 <div class="box box-left">
18 <div class="box box-left">
19 <!-- box / title -->
19 <!-- box / title -->
20 <div class="title">
20 <div class="title">
21 ${self.breadcrumbs()}
21 ${self.breadcrumbs()}
22 </div>
22 </div>
23 <!-- end box / title -->
23 <!-- end box / title -->
24 ${c.form|n}
24 ${c.form|n}
25 </div>
25 </div>
26
26
27 <div class="box box-right">
27 <div class="box box-right">
28 <!-- box / title -->
28 <!-- box / title -->
29 <div class="title">
29 <div class="title">
30 <h5>
30 <h5>
31 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value="" style="display: none"/>
31 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value="" style="display: none"/>
32 </h5>
32 </h5>
33 <ul class="links" style="color:#DADADA">
33 <ul class="links" style="color:#DADADA">
34 <li>
34 <li>
35 <span><a id="show_perms" class="link-white current" href="#perms">${_('My permissions')}</a> </span>
35 <span><a id="show_perms" class="link-white current" href="#perms">${_('My permissions')}</a> </span>
36 </li>
36 </li>
37 <li>
37 <li>
38 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
38 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
39 </li>
39 </li>
40 <li>
40 <li>
41 <span><a id="show_pullrequests" class="link-white" href="#pullrequests">${_('My pull requests')}</a> </span>
41 <span><a id="show_pullrequests" class="link-white" href="#pullrequests">${_('My pull requests')}</a> </span>
42 </li>
42 </li>
43 </ul>
43 </ul>
44 </div>
44 </div>
45 <!-- end box / title -->
45 <!-- end box / title -->
46 ## permissions overview
46 ## permissions overview
47 <div id="perms_container">
47 <div id="perms_container">
48 <%namespace name="p" file="/base/perms_summary.html"/>
48 <%namespace name="p" file="/base/perms_summary.html"/>
49 ${p.perms_summary(c.perm_user.permissions)}
49 ${p.perms_summary(c.perm_user.permissions)}
50 </div>
50 </div>
51
51
52 <div id="my_container" style="display:none">
52 <div id="my_container" style="display:none">
53 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
53 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
54 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
54 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
55 </div>
55 </div>
56 <div id="pullrequests_container" class="table" style="display:none">
56 <div id="pullrequests_container" class="table" style="display:none">
57 ## loaded via AJAX
57 ## loaded via AJAX
58 ${_('Loading...')}
58 ${_('Loading...')}
59 </div>
59 </div>
60 </div>
60 </div>
61
61
62 <script type="text/javascript">
62 <script type="text/javascript">
63 pyroutes.register('admin_settings_my_pullrequests', "${url('admin_settings_my_pullrequests')}", []);
63 pyroutes.register('admin_settings_my_pullrequests', "${url('admin_settings_my_pullrequests')}", []);
64
64
65 var show_perms = function(e){
65 var show_perms = function(e){
66 YUD.addClass('show_perms', 'current');
66 YUD.addClass('show_perms', 'current');
67 YUD.removeClass('show_my','current');
67 YUD.removeClass('show_my','current');
68 YUD.removeClass('show_pullrequests','current');
68 YUD.removeClass('show_pullrequests','current');
69
69
70 YUD.setStyle('my_container','display','none');
70 YUD.setStyle('my_container','display','none');
71 YUD.setStyle('pullrequests_container','display','none');
71 YUD.setStyle('pullrequests_container','display','none');
72 YUD.setStyle('perms_container','display','');
72 YUD.setStyle('perms_container','display','');
73 YUD.setStyle('q_filter','display','none');
73 YUD.setStyle('q_filter','display','none');
74 }
74 }
75 YUE.on('show_perms','click',function(e){
75 YUE.on('show_perms','click',function(e){
76 show_perms();
76 show_perms();
77 })
77 })
78
78
79 var show_my = function(e){
79 var show_my = function(e){
80 YUD.addClass('show_my', 'current');
80 YUD.addClass('show_my', 'current');
81 YUD.removeClass('show_perms','current');
81 YUD.removeClass('show_perms','current');
82 YUD.removeClass('show_pullrequests','current');
82 YUD.removeClass('show_pullrequests','current');
83
83
84 YUD.setStyle('perms_container','display','none');
84 YUD.setStyle('perms_container','display','none');
85 YUD.setStyle('pullrequests_container','display','none');
85 YUD.setStyle('pullrequests_container','display','none');
86 YUD.setStyle('my_container','display','');
86 YUD.setStyle('my_container','display','');
87 YUD.setStyle('q_filter','display','');
87 YUD.setStyle('q_filter','display','');
88 if(!YUD.hasClass('show_my', 'loaded')){
88 if(!YUD.hasClass('show_my', 'loaded')){
89 table_renderer(${c.data |n});
89 table_renderer(${c.data |n});
90 YUD.addClass('show_my', 'loaded');
90 YUD.addClass('show_my', 'loaded');
91 }
91 }
92 }
92 }
93 YUE.on('show_my','click',function(e){
93 YUE.on('show_my','click',function(e){
94 show_my(e);
94 show_my(e);
95 })
95 })
96
96
97 var show_pullrequests = function(e){
97 var show_pullrequests = function(e){
98 YUD.addClass('show_pullrequests', 'current');
98 YUD.addClass('show_pullrequests', 'current');
99 YUD.removeClass('show_my','current');
99 YUD.removeClass('show_my','current');
100 YUD.removeClass('show_perms','current');
100 YUD.removeClass('show_perms','current');
101
101
102 YUD.setStyle('my_container','display','none');
102 YUD.setStyle('my_container','display','none');
103 YUD.setStyle('perms_container','display','none');
103 YUD.setStyle('perms_container','display','none');
104 YUD.setStyle('pullrequests_container','display','');
104 YUD.setStyle('pullrequests_container','display','');
105 YUD.setStyle('q_filter','display','none');
105 YUD.setStyle('q_filter','display','none');
106
106
107 var url = pyroutes.url('admin_settings_my_pullrequests');
107 var url = pyroutes.url('admin_settings_my_pullrequests');
108 if(YUD.get('show_closed') && YUD.get('show_closed').checked) {
108 if(YUD.get('show_closed') && YUD.get('show_closed').checked) {
109 var url = pyroutes.url('admin_settings_my_pullrequests', {'pr_show_closed': '1'});
109 var url = pyroutes.url('admin_settings_my_pullrequests', {'pr_show_closed': '1'});
110 }
110 }
111 ypjax(url, 'pullrequests_container', function(){
111 ypjax(url, 'pullrequests_container', function(){
112 YUE.on('show_closed','change',function (e) {
112 YUE.on('show_closed','change',function (e) {
113 show_pullrequests(e);
113 show_pullrequests(e);
114 });
114 });
115 });
115 });
116 }
116 }
117 YUE.on('show_pullrequests','click',function(e){
117 YUE.on('show_pullrequests','click',function(e){
118 show_pullrequests(e)
118 show_pullrequests(e)
119 })
119 })
120
120
121 var tabs = {
121 var tabs = {
122 'perms': show_perms,
122 'perms': show_perms,
123 'my': show_my,
123 'my': show_my,
124 'pullrequests': show_pullrequests
124 'pullrequests': show_pullrequests
125 }
125 }
126 var url = location.href.split('#');
126 var url = location.href.split('#');
127 if (url[1]) {
127 if (url[1]) {
128 //We have a hash
128 //We have a hash
129 var tabHash = url[1];
129 var tabHash = url[1];
130 var func = tabs[tabHash]
130 var func = tabs[tabHash]
131 if (func){
131 if (func){
132 func();
132 func();
133 }
133 }
134 }
134 }
135
135
136 function table_renderer(data){
136 function table_renderer(data){
137 var myDataSource = new YAHOO.util.DataSource(data);
137 var myDataSource = new YAHOO.util.DataSource(data);
138 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
138 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
139
139
140 myDataSource.responseSchema = {
140 myDataSource.responseSchema = {
141 resultsList: "records",
141 resultsList: "records",
142 fields: [
142 fields: [
143 {key:"menu"},
143 {key:"menu"},
144 {key:"raw_name"},
144 {key:"raw_name"},
145 {key:"name"},
145 {key:"name"},
146 {key:"last_changeset"},
146 {key:"last_changeset"},
147 {key:"action"},
147 {key:"action"},
148 ]
148 ]
149 };
149 };
150 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
150 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
151 // This is the filter function
151 // This is the filter function
152 var data = res.results || [],
152 var data = res.results || [],
153 filtered = [],
153 filtered = [],
154 i,l;
154 i,l;
155
155
156 if (req) {
156 if (req) {
157 req = req.toLowerCase();
157 req = req.toLowerCase();
158 for (i = 0; i<data.length; i++) {
158 for (i = 0; i<data.length; i++) {
159 var pos = data[i].raw_name.toLowerCase().indexOf(req)
159 var pos = data[i].raw_name.toLowerCase().indexOf(req)
160 if (pos != -1) {
160 if (pos != -1) {
161 filtered.push(data[i]);
161 filtered.push(data[i]);
162 }
162 }
163 }
163 }
164 res.results = filtered;
164 res.results = filtered;
165 }
165 }
166 return res;
166 return res;
167 }
167 }
168
168
169 // main table sorting
169 // main table sorting
170 var myColumnDefs = [
170 var myColumnDefs = [
171 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
171 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
172 {key:"name",label:"${_('Name')}",sortable:true,
172 {key:"name",label:"${_('Name')}",sortable:true,
173 sortOptions: { sortFunction: nameSort }},
173 sortOptions: { sortFunction: nameSort }},
174 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
174 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
175 sortOptions: { sortFunction: revisionSort }},
175 sortOptions: { sortFunction: revisionSort }},
176 {key:"action",label:"${_('Action')}",sortable:false},
176 {key:"action",label:"${_('Action')}",sortable:false},
177 ];
177 ];
178
178
179 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
179 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
180 sortedBy:{key:"name",dir:"asc"},
180 sortedBy:{key:"name",dir:"asc"},
181 paginator: new YAHOO.widget.Paginator({
181 paginator: YUI_paginator(50, ['user-paginator']),
182 rowsPerPage: 50,
183 alwaysVisible: false,
184 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
185 pageLinks: 5,
186 containerClass: 'pagination-wh',
187 currentPageClass: 'pager_curpage',
188 pageLinkClass: 'pager_link',
189 nextPageLinkLabel: '&gt;',
190 previousPageLinkLabel: '&lt;',
191 firstPageLinkLabel: '&lt;&lt;',
192 lastPageLinkLabel: '&gt;&gt;',
193 containers:['user-paginator']
194 }),
195
182
196 MSG_SORTASC:"${_('Click to sort ascending')}",
183 MSG_SORTASC:"${_('Click to sort ascending')}",
197 MSG_SORTDESC:"${_('Click to sort descending')}",
184 MSG_SORTDESC:"${_('Click to sort descending')}",
198 MSG_EMPTY:"${_('No records found.')}",
185 MSG_EMPTY:"${_('No records found.')}",
199 MSG_ERROR:"${_('Data error.')}",
186 MSG_ERROR:"${_('Data error.')}",
200 MSG_LOADING:"${_('Loading...')}",
187 MSG_LOADING:"${_('Loading...')}",
201 }
188 }
202 );
189 );
203 myDataTable.subscribe('postRenderEvent',function(oArgs) {
190 myDataTable.subscribe('postRenderEvent',function(oArgs) {
204 tooltip_activate();
191 tooltip_activate();
205 quick_repo_menu();
192 quick_repo_menu();
206 });
193 });
207
194
208 var filterTimeout = null;
195 var filterTimeout = null;
209
196
210 updateFilter = function() {
197 updateFilter = function() {
211 // Reset timeout
198 // Reset timeout
212 filterTimeout = null;
199 filterTimeout = null;
213
200
214 // Reset sort
201 // Reset sort
215 var state = myDataTable.getState();
202 var state = myDataTable.getState();
216 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
203 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
217
204
218 // Get filtered data
205 // Get filtered data
219 myDataSource.sendRequest(YUD.get('q_filter').value,{
206 myDataSource.sendRequest(YUD.get('q_filter').value,{
220 success : myDataTable.onDataReturnInitializeTable,
207 success : myDataTable.onDataReturnInitializeTable,
221 failure : myDataTable.onDataReturnInitializeTable,
208 failure : myDataTable.onDataReturnInitializeTable,
222 scope : myDataTable,
209 scope : myDataTable,
223 argument: state
210 argument: state
224 });
211 });
225
212
226 };
213 };
227 YUE.on('q_filter','click',function(){
214 YUE.on('q_filter','click',function(){
228 if(!YUD.hasClass('q_filter', 'loaded')){
215 if(!YUD.hasClass('q_filter', 'loaded')){
229 //TODO: load here full list later to do search within groups
216 //TODO: load here full list later to do search within groups
230 YUD.addClass('q_filter', 'loaded');
217 YUD.addClass('q_filter', 'loaded');
231 }
218 }
232 });
219 });
233
220
234 YUE.on('q_filter','keyup',function (e) {
221 YUE.on('q_filter','keyup',function (e) {
235 clearTimeout(filterTimeout);
222 clearTimeout(filterTimeout);
236 filterTimeout = setTimeout(updateFilter,600);
223 filterTimeout = setTimeout(updateFilter,600);
237 });
224 });
238
225
239 }
226 }
240 </script>
227 </script>
241 </%def>
228 </%def>
@@ -1,191 +1,178 b''
1 <%page args="parent" />
1 <%page args="parent" />
2 <div class="box">
2 <div class="box">
3 <!-- box / title -->
3 <!-- box / title -->
4 <div class="title">
4 <div class="title">
5 <h5>
5 <h5>
6 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')}
6 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')}
7 </h5>
7 </h5>
8 %if c.rhodecode_user.username != 'default':
8 %if c.rhodecode_user.username != 'default':
9 <ul class="links">
9 <ul class="links">
10 %if h.HasPermissionAny('hg.admin','hg.create.repository')() or h.HasReposGroupPermissionAny('group.write', 'group.admin')(c.group.group_name if c.group else None):
10 %if h.HasPermissionAny('hg.admin','hg.create.repository')() or h.HasReposGroupPermissionAny('group.write', 'group.admin')(c.group.group_name if c.group else None):
11 <li>
11 <li>
12 %if c.group:
12 %if c.group:
13 <span>${h.link_to(_('Add repository'),h.url('new_repo',parent_group=c.group.group_id))}</span>
13 <span>${h.link_to(_('Add repository'),h.url('new_repo',parent_group=c.group.group_id))}</span>
14 %if h.HasPermissionAny('hg.admin')() or h.HasReposGroupPermissionAny('group.admin')(c.group.group_name):
14 %if h.HasPermissionAny('hg.admin')() or h.HasReposGroupPermissionAny('group.admin')(c.group.group_name):
15 <span>${h.link_to(_(u'Add group'),h.url('new_repos_group', parent_group=c.group.group_id))}</span>
15 <span>${h.link_to(_(u'Add group'),h.url('new_repos_group', parent_group=c.group.group_id))}</span>
16 %endif
16 %endif
17 %else:
17 %else:
18 <span>${h.link_to(_('Add repository'),h.url('new_repo'))}</span>
18 <span>${h.link_to(_('Add repository'),h.url('new_repo'))}</span>
19 %if h.HasPermissionAny('hg.admin')():
19 %if h.HasPermissionAny('hg.admin')():
20 <span>${h.link_to(_(u'Add group'),h.url('new_repos_group'))}</span>
20 <span>${h.link_to(_(u'Add group'),h.url('new_repos_group'))}</span>
21 %endif
21 %endif
22 %endif
22 %endif
23 </li>
23 </li>
24 %endif
24 %endif
25 %if c.group and h.HasReposGroupPermissionAny('group.admin')(c.group.group_name):
25 %if c.group and h.HasReposGroupPermissionAny('group.admin')(c.group.group_name):
26 <li>
26 <li>
27 <span>${h.link_to(_('Edit group'),h.url('edit_repos_group',group_name=c.group.group_name), title=_('You have admin right to this group, and can edit it'))}</span>
27 <span>${h.link_to(_('Edit group'),h.url('edit_repos_group',group_name=c.group.group_name), title=_('You have admin right to this group, and can edit it'))}</span>
28 </li>
28 </li>
29 %endif
29 %endif
30 </ul>
30 </ul>
31 %endif
31 %endif
32 </div>
32 </div>
33 <!-- end box / title -->
33 <!-- end box / title -->
34 <div class="table">
34 <div class="table">
35 % if c.groups:
35 % if c.groups:
36 <div id='groups_list_wrap' class="yui-skin-sam">
36 <div id='groups_list_wrap' class="yui-skin-sam">
37 <table id="groups_list">
37 <table id="groups_list">
38 <thead>
38 <thead>
39 <tr>
39 <tr>
40 <th class="left"><a href="#">${_('Group name')}</a></th>
40 <th class="left"><a href="#">${_('Group name')}</a></th>
41 <th class="left"><a href="#">${_('Description')}</a></th>
41 <th class="left"><a href="#">${_('Description')}</a></th>
42 ##<th class="left"><a href="#">${_('Number of repositories')}</a></th>
42 ##<th class="left"><a href="#">${_('Number of repositories')}</a></th>
43 </tr>
43 </tr>
44 </thead>
44 </thead>
45
45
46 ## REPO GROUPS
46 ## REPO GROUPS
47 % for gr in c.groups:
47 % for gr in c.groups:
48 <tr>
48 <tr>
49 <td>
49 <td>
50 <div style="white-space: nowrap">
50 <div style="white-space: nowrap">
51 <img class="icon" alt="${_('Repository group')}" src="${h.url('/images/icons/database_link.png')}"/>
51 <img class="icon" alt="${_('Repository group')}" src="${h.url('/images/icons/database_link.png')}"/>
52 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
52 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
53 </div>
53 </div>
54 </td>
54 </td>
55 %if c.visual.stylify_metatags:
55 %if c.visual.stylify_metatags:
56 <td>${h.urlify_text(h.desc_stylize(gr.group_description))}</td>
56 <td>${h.urlify_text(h.desc_stylize(gr.group_description))}</td>
57 %else:
57 %else:
58 <td>${gr.group_description}</td>
58 <td>${gr.group_description}</td>
59 %endif
59 %endif
60 ## this is commented out since for multi nested repos can be HEAVY!
60 ## this is commented out since for multi nested repos can be HEAVY!
61 ## in number of executed queries during traversing uncomment at will
61 ## in number of executed queries during traversing uncomment at will
62 ##<td><b>${gr.repositories_recursive_count}</b></td>
62 ##<td><b>${gr.repositories_recursive_count}</b></td>
63 </tr>
63 </tr>
64 % endfor
64 % endfor
65 </table>
65 </table>
66 </div>
66 </div>
67 <div id="group-user-paginator" style="padding: 0px 0px 0px 0px"></div>
67 <div id="group-user-paginator" style="padding: 0px 0px 0px 0px"></div>
68 <div style="height: 20px"></div>
68 <div style="height: 20px"></div>
69 % endif
69 % endif
70 <div id="welcome" style="display:none;text-align:center">
70 <div id="welcome" style="display:none;text-align:center">
71 <h1><a href="${h.url('home')}">${c.rhodecode_name} ${c.rhodecode_version}</a></h1>
71 <h1><a href="${h.url('home')}">${c.rhodecode_name} ${c.rhodecode_version}</a></h1>
72 </div>
72 </div>
73 <%cnt=0%>
73 <%cnt=0%>
74 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
74 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
75 <div class="yui-skin-sam" id="repos_list_wrap"></div>
75 <div class="yui-skin-sam" id="repos_list_wrap"></div>
76 <div id="user-paginator" style="padding: 0px 0px 0px 0px"></div>
76 <div id="user-paginator" style="padding: 0px 0px 0px 0px"></div>
77 </div>
77 </div>
78 </div>
78 </div>
79
79
80 <script>
80 <script>
81 var data = ${c.data|n};
81 var data = ${c.data|n};
82 var myDataSource = new YAHOO.util.DataSource(data);
82 var myDataSource = new YAHOO.util.DataSource(data);
83 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
83 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
84
84
85 myDataSource.responseSchema = {
85 myDataSource.responseSchema = {
86 resultsList: "records",
86 resultsList: "records",
87 fields: [
87 fields: [
88 {key:"menu"},
88 {key:"menu"},
89 {key:"raw_name"},
89 {key:"raw_name"},
90 {key:"name"},
90 {key:"name"},
91 {key:"desc"},
91 {key:"desc"},
92 {key:"last_change"},
92 {key:"last_change"},
93 {key:"last_changeset"},
93 {key:"last_changeset"},
94 {key:"owner"},
94 {key:"owner"},
95 {key:"atom"},
95 {key:"atom"},
96 ]
96 ]
97 };
97 };
98 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
98 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
99 // This is the filter function
99 // This is the filter function
100 var data = res.results || [],
100 var data = res.results || [],
101 filtered = [],
101 filtered = [],
102 i,l;
102 i,l;
103
103
104 if (req) {
104 if (req) {
105 req = req.toLowerCase();
105 req = req.toLowerCase();
106 for (i = 0; i<data.length; i++) {
106 for (i = 0; i<data.length; i++) {
107 var pos = data[i].raw_name.toLowerCase().indexOf(req)
107 var pos = data[i].raw_name.toLowerCase().indexOf(req)
108 if (pos != -1) {
108 if (pos != -1) {
109 filtered.push(data[i]);
109 filtered.push(data[i]);
110 }
110 }
111 }
111 }
112 res.results = filtered;
112 res.results = filtered;
113 }
113 }
114 YUD.get('repo_count').innerHTML = res.results.length;
114 YUD.get('repo_count').innerHTML = res.results.length;
115 return res;
115 return res;
116 }
116 }
117
117
118 // main table sorting
118 // main table sorting
119 var myColumnDefs = [
119 var myColumnDefs = [
120 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
120 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
121 {key:"name",label:"${_('Name')}",sortable:true,
121 {key:"name",label:"${_('Name')}",sortable:true,
122 sortOptions: { sortFunction: nameSort }},
122 sortOptions: { sortFunction: nameSort }},
123 {key:"desc",label:"${_('Description')}",sortable:true},
123 {key:"desc",label:"${_('Description')}",sortable:true},
124 {key:"last_change",label:"${_('Last Change')}",sortable:true,
124 {key:"last_change",label:"${_('Last Change')}",sortable:true,
125 sortOptions: { sortFunction: ageSort }},
125 sortOptions: { sortFunction: ageSort }},
126 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
126 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
127 sortOptions: { sortFunction: revisionSort }},
127 sortOptions: { sortFunction: revisionSort }},
128 {key:"owner",label:"${_('Owner')}",sortable:true},
128 {key:"owner",label:"${_('Owner')}",sortable:true},
129 {key:"atom",label:"",sortable:false},
129 {key:"atom",label:"",sortable:false},
130 ];
130 ];
131
131
132 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
132 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
133 sortedBy:{key:"name",dir:"asc"},
133 sortedBy:{key:"name",dir:"asc"},
134 paginator: new YAHOO.widget.Paginator({
134 paginator: YUI_paginator(${c.visual.dashboard_items},['user-paginator']),
135 rowsPerPage: ${c.visual.dashboard_items},
136 alwaysVisible: false,
137 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
138 pageLinks: 5,
139 containerClass: 'pagination-wh',
140 currentPageClass: 'pager_curpage',
141 pageLinkClass: 'pager_link',
142 nextPageLinkLabel: '&gt;',
143 previousPageLinkLabel: '&lt;',
144 firstPageLinkLabel: '&lt;&lt;',
145 lastPageLinkLabel: '&gt;&gt;',
146 containers:['user-paginator']
147 }),
148
135
149 MSG_SORTASC:"${_('Click to sort ascending')}",
136 MSG_SORTASC:"${_('Click to sort ascending')}",
150 MSG_SORTDESC:"${_('Click to sort descending')}",
137 MSG_SORTDESC:"${_('Click to sort descending')}",
151 MSG_EMPTY:"${_('No repositories found.')}",
138 MSG_EMPTY:"${_('No repositories found.')}",
152 MSG_ERROR:"${_('Data error.')}",
139 MSG_ERROR:"${_('Data error.')}",
153 MSG_LOADING:"${_('Loading...')}",
140 MSG_LOADING:"${_('Loading...')}",
154 }
141 }
155 );
142 );
156 myDataTable.subscribe('postRenderEvent',function(oArgs) {
143 myDataTable.subscribe('postRenderEvent',function(oArgs) {
157 tooltip_activate();
144 tooltip_activate();
158 quick_repo_menu();
145 quick_repo_menu();
159 });
146 });
160
147
161 var filterTimeout = null;
148 var filterTimeout = null;
162
149
163 updateFilter = function () {
150 updateFilter = function () {
164 // Reset timeout
151 // Reset timeout
165 filterTimeout = null;
152 filterTimeout = null;
166
153
167 // Reset sort
154 // Reset sort
168 var state = myDataTable.getState();
155 var state = myDataTable.getState();
169 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
156 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
170
157
171 // Get filtered data
158 // Get filtered data
172 myDataSource.sendRequest(YUD.get('q_filter').value,{
159 myDataSource.sendRequest(YUD.get('q_filter').value,{
173 success : myDataTable.onDataReturnInitializeTable,
160 success : myDataTable.onDataReturnInitializeTable,
174 failure : myDataTable.onDataReturnInitializeTable,
161 failure : myDataTable.onDataReturnInitializeTable,
175 scope : myDataTable,
162 scope : myDataTable,
176 argument: state
163 argument: state
177 });
164 });
178
165
179 };
166 };
180 YUE.on('q_filter','click',function(){
167 YUE.on('q_filter','click',function(){
181 if(!YUD.hasClass('q_filter', 'loaded')){
168 if(!YUD.hasClass('q_filter', 'loaded')){
182 //TODO: load here full list later to do search within groups
169 //TODO: load here full list later to do search within groups
183 YUD.addClass('q_filter', 'loaded');
170 YUD.addClass('q_filter', 'loaded');
184 }
171 }
185 });
172 });
186
173
187 YUE.on('q_filter','keyup',function (e) {
174 YUE.on('q_filter','keyup',function (e) {
188 clearTimeout(filterTimeout);
175 clearTimeout(filterTimeout);
189 filterTimeout = setTimeout(updateFilter,600);
176 filterTimeout = setTimeout(updateFilter,600);
190 });
177 });
191 </script>
178 </script>
@@ -1,365 +1,339 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3 <%def name="title()">
3 <%def name="title()">
4 ${_('Journal')} &middot; ${c.rhodecode_name}
4 ${_('Journal')} &middot; ${c.rhodecode_name}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 <h5>
7 <h5>
8 <form id="filter_form">
8 <form id="filter_form">
9 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or _('quick filter...')}"/>
9 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or _('quick filter...')}"/>
10 <span class="tooltip" title="${h.tooltip(h.journal_filter_help())}">?</span>
10 <span class="tooltip" title="${h.tooltip(h.journal_filter_help())}">?</span>
11 <input type='submit' value="${_('filter')}" class="ui-btn" style="padding:0px 2px 0px 2px;margin:0px"/>
11 <input type='submit' value="${_('filter')}" class="ui-btn" style="padding:0px 2px 0px 2px;margin:0px"/>
12 ${_('journal')} - ${ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)}
12 ${_('journal')} - ${ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)}
13 </form>
13 </form>
14 ${h.end_form()}
14 ${h.end_form()}
15 </h5>
15 </h5>
16 </%def>
16 </%def>
17 <%def name="page_nav()">
17 <%def name="page_nav()">
18 ${self.menu('journal')}
18 ${self.menu('journal')}
19 </%def>
19 </%def>
20 <%def name="head_extra()">
20 <%def name="head_extra()">
21 <link href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('ATOM journal feed')}" type="application/atom+xml" />
21 <link href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('ATOM journal feed')}" type="application/atom+xml" />
22 <link href="${h.url('journal_rss', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('RSS journal feed')}" type="application/rss+xml" />
22 <link href="${h.url('journal_rss', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('RSS journal feed')}" type="application/rss+xml" />
23 </%def>
23 </%def>
24 <%def name="main()">
24 <%def name="main()">
25
25
26 <div class="box box-left">
26 <div class="box box-left">
27 <!-- box / title -->
27 <!-- box / title -->
28 <div class="title">
28 <div class="title">
29 ${self.breadcrumbs()}
29 ${self.breadcrumbs()}
30 <ul class="links">
30 <ul class="links">
31 <li>
31 <li>
32 <span><a id="refresh" href="${h.url('journal')}"><img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/></a></span>
32 <span><a id="refresh" href="${h.url('journal')}"><img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/></a></span>
33 </li>
33 </li>
34 <li>
34 <li>
35 <span><a href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
35 <span><a href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
36 </li>
36 </li>
37 </ul>
37 </ul>
38 </div>
38 </div>
39 <div id="journal">${c.journal_data}</div>
39 <div id="journal">${c.journal_data}</div>
40 </div>
40 </div>
41 <div class="box box-right">
41 <div class="box box-right">
42 <!-- box / title -->
42 <!-- box / title -->
43
43
44 <div class="title">
44 <div class="title">
45 <h5>
45 <h5>
46 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value="" style="display: none"/>
46 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value="" style="display: none"/>
47 <input class="q_filter_box" id="q_filter_watched" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value="" style="display: none"/>
47 <input class="q_filter_box" id="q_filter_watched" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value="" style="display: none"/>
48 </h5>
48 </h5>
49 <ul class="links" style="color:#DADADA">
49 <ul class="links" style="color:#DADADA">
50 <li>
50 <li>
51 <span><a id="show_watched" class="link-white current" href="#watched">${_('Watched')}</a> </span>
51 <span><a id="show_watched" class="link-white current" href="#watched">${_('Watched')}</a> </span>
52 </li>
52 </li>
53 <li>
53 <li>
54 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
54 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
55 </li>
55 </li>
56 </ul>
56 </ul>
57 </div>
57 </div>
58
58
59 <!-- end box / title -->
59 <!-- end box / title -->
60 <div id="my_container" style="display:none">
60 <div id="my_container" style="display:none">
61 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
61 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
62 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
62 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
63 </div>
63 </div>
64
64
65 <div id="watched_container">
65 <div id="watched_container">
66 <div class="table yui-skin-sam" id="watched_repos_list_wrap"></div>
66 <div class="table yui-skin-sam" id="watched_repos_list_wrap"></div>
67 <div id="watched-user-paginator" style="padding: 0px 0px 0px 20px"></div>
67 <div id="watched-user-paginator" style="padding: 0px 0px 0px 20px"></div>
68 </div>
68 </div>
69 </div>
69 </div>
70
70
71 <script type="text/javascript">
71 <script type="text/javascript">
72
72
73 YUE.on('j_filter','click',function(){
73 YUE.on('j_filter','click',function(){
74 var jfilter = YUD.get('j_filter');
74 var jfilter = YUD.get('j_filter');
75 if(YUD.hasClass(jfilter, 'initial')){
75 if(YUD.hasClass(jfilter, 'initial')){
76 jfilter.value = '';
76 jfilter.value = '';
77 }
77 }
78 });
78 });
79 var fix_j_filter_width = function(len){
79 var fix_j_filter_width = function(len){
80 YUD.setStyle(YUD.get('j_filter'),'width',Math.max(80, len*6.50)+'px');
80 YUD.setStyle(YUD.get('j_filter'),'width',Math.max(80, len*6.50)+'px');
81 }
81 }
82 YUE.on('j_filter','keyup',function(){
82 YUE.on('j_filter','keyup',function(){
83 fix_j_filter_width(YUD.get('j_filter').value.length);
83 fix_j_filter_width(YUD.get('j_filter').value.length);
84 });
84 });
85 YUE.on('filter_form','submit',function(e){
85 YUE.on('filter_form','submit',function(e){
86 YUE.preventDefault(e)
86 YUE.preventDefault(e)
87 var val = YUD.get('j_filter').value;
87 var val = YUD.get('j_filter').value;
88 window.location = "${url.current(filter='__FILTER__')}".replace('__FILTER__',val);
88 window.location = "${url.current(filter='__FILTER__')}".replace('__FILTER__',val);
89 });
89 });
90 fix_j_filter_width(YUD.get('j_filter').value.length);
90 fix_j_filter_width(YUD.get('j_filter').value.length);
91
91
92 YUE.on('refresh','click',function(e){
92 YUE.on('refresh','click',function(e){
93 ypjax("${h.url.current(filter=c.search_term)}","journal",function(){
93 ypjax("${h.url.current(filter=c.search_term)}","journal",function(){
94 show_more_event();
94 show_more_event();
95 tooltip_activate();
95 tooltip_activate();
96 show_changeset_tooltip();
96 show_changeset_tooltip();
97 });
97 });
98 YUE.preventDefault(e);
98 YUE.preventDefault(e);
99 });
99 });
100
100
101 var show_my = function(e){
101 var show_my = function(e){
102 YUD.setStyle('watched_container','display','none');
102 YUD.setStyle('watched_container','display','none');
103 YUD.setStyle('my_container','display','');
103 YUD.setStyle('my_container','display','');
104 YUD.setStyle('q_filter','display','');
104 YUD.setStyle('q_filter','display','');
105 YUD.setStyle('q_filter_watched','display','none');
105 YUD.setStyle('q_filter_watched','display','none');
106
106
107 YUD.addClass('show_my', 'current');
107 YUD.addClass('show_my', 'current');
108 YUD.removeClass('show_watched','current');
108 YUD.removeClass('show_watched','current');
109
109
110 if(!YUD.hasClass('show_my', 'loaded')){
110 if(!YUD.hasClass('show_my', 'loaded')){
111 table_renderer(${c.data |n});
111 table_renderer(${c.data |n});
112 YUD.addClass('show_my', 'loaded');
112 YUD.addClass('show_my', 'loaded');
113 }
113 }
114 }
114 }
115 YUE.on('show_my','click',function(e){
115 YUE.on('show_my','click',function(e){
116 show_my(e);
116 show_my(e);
117 })
117 })
118 var show_watched = function(e){
118 var show_watched = function(e){
119 YUD.setStyle('my_container','display','none');
119 YUD.setStyle('my_container','display','none');
120 YUD.setStyle('watched_container','display','');
120 YUD.setStyle('watched_container','display','');
121 YUD.setStyle('q_filter_watched','display','');
121 YUD.setStyle('q_filter_watched','display','');
122 YUD.setStyle('q_filter','display','none');
122 YUD.setStyle('q_filter','display','none');
123
123
124 YUD.addClass('show_watched', 'current');
124 YUD.addClass('show_watched', 'current');
125 YUD.removeClass('show_my','current');
125 YUD.removeClass('show_my','current');
126 if(!YUD.hasClass('show_watched', 'loaded')){
126 if(!YUD.hasClass('show_watched', 'loaded')){
127 watched_renderer(${c.watched_data |n});
127 watched_renderer(${c.watched_data |n});
128 YUD.addClass('show_watched', 'loaded');
128 YUD.addClass('show_watched', 'loaded');
129 }
129 }
130
130
131 return
131 return
132 var nodes = YUQ('#watched_container .watched_repo a');
132 var nodes = YUQ('#watched_container .watched_repo a');
133 var target = 'q_filter';
133 var target = 'q_filter';
134 var func = function(node){
134 var func = function(node){
135 return node.parentNode.parentNode;
135 return node.parentNode.parentNode;
136 }
136 }
137 q_filter(target,nodes,func);
137 q_filter(target,nodes,func);
138 }
138 }
139 YUE.on('show_watched','click',function(e){
139 YUE.on('show_watched','click',function(e){
140 show_watched(e);
140 show_watched(e);
141 })
141 })
142 //init watched
142 //init watched
143 show_watched();
143 show_watched();
144
144
145 var tabs = {
145 var tabs = {
146 'watched': show_watched,
146 'watched': show_watched,
147 'my': show_my,
147 'my': show_my,
148 }
148 }
149 var url = location.href.split('#');
149 var url = location.href.split('#');
150 if (url[1]) {
150 if (url[1]) {
151 //We have a hash
151 //We have a hash
152 var tabHash = url[1];
152 var tabHash = url[1];
153 var func = tabs[tabHash]
153 var func = tabs[tabHash]
154 if (func){
154 if (func){
155 func();
155 func();
156 }
156 }
157 }
157 }
158 function watched_renderer(data){
158 function watched_renderer(data){
159 var myDataSource = new YAHOO.util.DataSource(data);
159 var myDataSource = new YAHOO.util.DataSource(data);
160 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
160 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
161
161
162 myDataSource.responseSchema = {
162 myDataSource.responseSchema = {
163 resultsList: "records",
163 resultsList: "records",
164 fields: [
164 fields: [
165 {key:"menu"},
165 {key:"menu"},
166 {key:"raw_name"},
166 {key:"raw_name"},
167 {key:"name"},
167 {key:"name"},
168 {key:"last_changeset"},
168 {key:"last_changeset"},
169 {key:"action"},
169 {key:"action"},
170 ]
170 ]
171 };
171 };
172 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
172 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
173 // This is the filter function
173 // This is the filter function
174 var data = res.results || [],
174 var data = res.results || [],
175 filtered = [],
175 filtered = [],
176 i,l;
176 i,l;
177
177
178 if (req) {
178 if (req) {
179 req = req.toLowerCase();
179 req = req.toLowerCase();
180 for (i = 0; i<data.length; i++) {
180 for (i = 0; i<data.length; i++) {
181 var pos = data[i].raw_name.toLowerCase().indexOf(req)
181 var pos = data[i].raw_name.toLowerCase().indexOf(req)
182 if (pos != -1) {
182 if (pos != -1) {
183 filtered.push(data[i]);
183 filtered.push(data[i]);
184 }
184 }
185 }
185 }
186 res.results = filtered;
186 res.results = filtered;
187 }
187 }
188 return res;
188 return res;
189 }
189 }
190 // main table sorting
190 // main table sorting
191 var myColumnDefs = [
191 var myColumnDefs = [
192 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
192 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
193 {key:"name",label:"${_('Name')}",sortable:true,
193 {key:"name",label:"${_('Name')}",sortable:true,
194 sortOptions: { sortFunction: nameSort }},
194 sortOptions: { sortFunction: nameSort }},
195 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
195 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
196 sortOptions: { sortFunction: revisionSort }},
196 sortOptions: { sortFunction: revisionSort }},
197 {key:"action",label:"${_('Action')}",sortable:false},
197 {key:"action",label:"${_('Action')}",sortable:false},
198 ];
198 ];
199
199
200 var myDataTable = new YAHOO.widget.DataTable("watched_repos_list_wrap", myColumnDefs, myDataSource,{
200 var myDataTable = new YAHOO.widget.DataTable("watched_repos_list_wrap", myColumnDefs, myDataSource,{
201 sortedBy:{key:"name",dir:"asc"},
201 sortedBy:{key:"name",dir:"asc"},
202 paginator: new YAHOO.widget.Paginator({
202 paginator: YUI_paginator(25, ['watched-user-paginator']),
203 rowsPerPage: 25,
204 alwaysVisible: false,
205 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
206 pageLinks: 5,
207 containerClass: 'pagination-wh',
208 currentPageClass: 'pager_curpage',
209 pageLinkClass: 'pager_link',
210 nextPageLinkLabel: '&gt;',
211 previousPageLinkLabel: '&lt;',
212 firstPageLinkLabel: '&lt;&lt;',
213 lastPageLinkLabel: '&gt;&gt;',
214 containers:['watched-user-paginator']
215 }),
216
203
217 MSG_SORTASC:"${_('Click to sort ascending')}",
204 MSG_SORTASC:"${_('Click to sort ascending')}",
218 MSG_SORTDESC:"${_('Click to sort descending')}",
205 MSG_SORTDESC:"${_('Click to sort descending')}",
219 MSG_EMPTY:"${_('No records found.')}",
206 MSG_EMPTY:"${_('No records found.')}",
220 MSG_ERROR:"${_('Data error.')}",
207 MSG_ERROR:"${_('Data error.')}",
221 MSG_LOADING:"${_('Loading...')}",
208 MSG_LOADING:"${_('Loading...')}",
222 }
209 }
223 );
210 );
224 myDataTable.subscribe('postRenderEvent',function(oArgs) {
211 myDataTable.subscribe('postRenderEvent',function(oArgs) {
225 tooltip_activate();
212 tooltip_activate();
226 quick_repo_menu();
213 quick_repo_menu();
227 });
214 });
228
215
229 var filterTimeout = null;
216 var filterTimeout = null;
230
217
231 updateFilter = function () {
218 updateFilter = function () {
232 // Reset timeout
219 // Reset timeout
233 filterTimeout = null;
220 filterTimeout = null;
234
221
235 // Reset sort
222 // Reset sort
236 var state = myDataTable.getState();
223 var state = myDataTable.getState();
237 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
224 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
238
225
239 // Get filtered data
226 // Get filtered data
240 myDataSource.sendRequest(YUD.get('q_filter_watched').value,{
227 myDataSource.sendRequest(YUD.get('q_filter_watched').value,{
241 success : myDataTable.onDataReturnInitializeTable,
228 success : myDataTable.onDataReturnInitializeTable,
242 failure : myDataTable.onDataReturnInitializeTable,
229 failure : myDataTable.onDataReturnInitializeTable,
243 scope : myDataTable,
230 scope : myDataTable,
244 argument: state
231 argument: state
245 });
232 });
246
233
247 };
234 };
248 YUE.on('q_filter_watched','click',function(){
235 YUE.on('q_filter_watched','click',function(){
249 if(!YUD.hasClass('q_filter_watched', 'loaded')){
236 if(!YUD.hasClass('q_filter_watched', 'loaded')){
250 //TODO: load here full list later to do search within groups
237 //TODO: load here full list later to do search within groups
251 YUD.addClass('q_filter_watched', 'loaded');
238 YUD.addClass('q_filter_watched', 'loaded');
252 }
239 }
253 });
240 });
254
241
255 YUE.on('q_filter_watched','keyup',function (e) {
242 YUE.on('q_filter_watched','keyup',function (e) {
256 clearTimeout(filterTimeout);
243 clearTimeout(filterTimeout);
257 filterTimeout = setTimeout(updateFilter,600);
244 filterTimeout = setTimeout(updateFilter,600);
258 });
245 });
259 }
246 }
260
247
261 function table_renderer(data){
248 function table_renderer(data){
262 var myDataSource = new YAHOO.util.DataSource(data);
249 var myDataSource = new YAHOO.util.DataSource(data);
263 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
250 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
264
251
265 myDataSource.responseSchema = {
252 myDataSource.responseSchema = {
266 resultsList: "records",
253 resultsList: "records",
267 fields: [
254 fields: [
268 {key:"menu"},
255 {key:"menu"},
269 {key:"raw_name"},
256 {key:"raw_name"},
270 {key:"name"},
257 {key:"name"},
271 {key:"last_changeset"},
258 {key:"last_changeset"},
272 {key:"action"},
259 {key:"action"},
273 ]
260 ]
274 };
261 };
275 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
262 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
276 // This is the filter function
263 // This is the filter function
277 var data = res.results || [],
264 var data = res.results || [],
278 filtered = [],
265 filtered = [],
279 i,l;
266 i,l;
280
267
281 if (req) {
268 if (req) {
282 req = req.toLowerCase();
269 req = req.toLowerCase();
283 for (i = 0; i<data.length; i++) {
270 for (i = 0; i<data.length; i++) {
284 var pos = data[i].raw_name.toLowerCase().indexOf(req)
271 var pos = data[i].raw_name.toLowerCase().indexOf(req)
285 if (pos != -1) {
272 if (pos != -1) {
286 filtered.push(data[i]);
273 filtered.push(data[i]);
287 }
274 }
288 }
275 }
289 res.results = filtered;
276 res.results = filtered;
290 }
277 }
291 return res;
278 return res;
292 }
279 }
293 // main table sorting
280 // main table sorting
294 var myColumnDefs = [
281 var myColumnDefs = [
295 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
282 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
296 {key:"name",label:"${_('Name')}",sortable:true,
283 {key:"name",label:"${_('Name')}",sortable:true,
297 sortOptions: { sortFunction: nameSort }},
284 sortOptions: { sortFunction: nameSort }},
298 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
285 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
299 sortOptions: { sortFunction: revisionSort }},
286 sortOptions: { sortFunction: revisionSort }},
300 {key:"action",label:"${_('Action')}",sortable:false},
287 {key:"action",label:"${_('Action')}",sortable:false},
301 ];
288 ];
302
289
303 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
290 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
304 sortedBy:{key:"name",dir:"asc"},
291 sortedBy:{key:"name",dir:"asc"},
305 paginator: new YAHOO.widget.Paginator({
292 paginator: YUI_paginator(25, ['user-paginator']),
306 rowsPerPage: 25,
307 alwaysVisible: false,
308 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
309 pageLinks: 5,
310 containerClass: 'pagination-wh',
311 currentPageClass: 'pager_curpage',
312 pageLinkClass: 'pager_link',
313 nextPageLinkLabel: '&gt;',
314 previousPageLinkLabel: '&lt;',
315 firstPageLinkLabel: '&lt;&lt;',
316 lastPageLinkLabel: '&gt;&gt;',
317 containers:['user-paginator']
318 }),
319
293
320 MSG_SORTASC:"${_('Click to sort ascending')}",
294 MSG_SORTASC:"${_('Click to sort ascending')}",
321 MSG_SORTDESC:"${_('Click to sort descending')}",
295 MSG_SORTDESC:"${_('Click to sort descending')}",
322 MSG_EMPTY:"${_('No records found.')}",
296 MSG_EMPTY:"${_('No records found.')}",
323 MSG_ERROR:"${_('Data error.')}",
297 MSG_ERROR:"${_('Data error.')}",
324 MSG_LOADING:"${_('Loading...')}",
298 MSG_LOADING:"${_('Loading...')}",
325 }
299 }
326 );
300 );
327 myDataTable.subscribe('postRenderEvent',function(oArgs) {
301 myDataTable.subscribe('postRenderEvent',function(oArgs) {
328 tooltip_activate();
302 tooltip_activate();
329 quick_repo_menu();
303 quick_repo_menu();
330 });
304 });
331
305
332 var filterTimeout = null;
306 var filterTimeout = null;
333
307
334 updateFilter = function () {
308 updateFilter = function () {
335 // Reset timeout
309 // Reset timeout
336 filterTimeout = null;
310 filterTimeout = null;
337
311
338 // Reset sort
312 // Reset sort
339 var state = myDataTable.getState();
313 var state = myDataTable.getState();
340 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
314 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
341
315
342 // Get filtered data
316 // Get filtered data
343 myDataSource.sendRequest(YUD.get('q_filter').value,{
317 myDataSource.sendRequest(YUD.get('q_filter').value,{
344 success : myDataTable.onDataReturnInitializeTable,
318 success : myDataTable.onDataReturnInitializeTable,
345 failure : myDataTable.onDataReturnInitializeTable,
319 failure : myDataTable.onDataReturnInitializeTable,
346 scope : myDataTable,
320 scope : myDataTable,
347 argument: state
321 argument: state
348 });
322 });
349
323
350 };
324 };
351 YUE.on('q_filter','click',function(){
325 YUE.on('q_filter','click',function(){
352 if(!YUD.hasClass('q_filter', 'loaded')){
326 if(!YUD.hasClass('q_filter', 'loaded')){
353 //TODO: load here full list later to do search within groups
327 //TODO: load here full list later to do search within groups
354 YUD.addClass('q_filter', 'loaded');
328 YUD.addClass('q_filter', 'loaded');
355 }
329 }
356 });
330 });
357
331
358 YUE.on('q_filter','keyup',function (e) {
332 YUE.on('q_filter','keyup',function (e) {
359 clearTimeout(filterTimeout);
333 clearTimeout(filterTimeout);
360 filterTimeout = setTimeout(updateFilter,600);
334 filterTimeout = setTimeout(updateFilter,600);
361 });
335 });
362 }
336 }
363
337
364 </script>
338 </script>
365 </%def>
339 </%def>
@@ -1,57 +1,57 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 %if c.journal_day_aggreagate:
3 %if c.journal_day_aggreagate:
4 %for day,items in c.journal_day_aggreagate:
4 %for day,items in c.journal_day_aggreagate:
5 <div class="journal_day">${day}</div>
5 <div class="journal_day">${day}</div>
6 % for user,entries in items:
6 % for user,entries in items:
7 <div class="journal_container">
7 <div class="journal_container">
8 <div class="gravatar">
8 <div class="gravatar">
9 <img alt="gravatar" src="${h.gravatar_url(user.email if user else 'anonymous@rhodecode.org',24)}"/>
9 <img alt="gravatar" src="${h.gravatar_url(user.email if user else 'anonymous@rhodecode.org',24)}"/>
10 </div>
10 </div>
11 %if user:
11 %if user:
12 <div class="journal_user">${user.name} ${user.lastname}</div>
12 <div class="journal_user">${user.name} ${user.lastname}</div>
13 %else:
13 %else:
14 <div class="journal_user deleted">${entries[0].username}</div>
14 <div class="journal_user deleted">${entries[0].username}</div>
15 %endif
15 %endif
16 <div class="journal_action_container">
16 <div class="journal_action_container">
17 % for entry in entries:
17 % for entry in entries:
18 <div class="journal_icon"> ${h.action_parser(entry)[2]()}</div>
18 <div class="journal_icon"> ${h.action_parser(entry)[2]()}</div>
19 <div class="journal_action">${h.action_parser(entry)[0]()}</div>
19 <div class="journal_action">${h.action_parser(entry)[0]()}</div>
20 <div class="journal_repo">
20 <div class="journal_repo">
21 <span class="journal_repo_name">
21 <span class="journal_repo_name">
22 %if entry.repository is not None:
22 %if entry.repository is not None:
23 ${h.link_to(entry.repository.repo_name,
23 ${h.link_to(entry.repository.repo_name,
24 h.url('summary_home',repo_name=entry.repository.repo_name))}
24 h.url('summary_home',repo_name=entry.repository.repo_name))}
25 %else:
25 %else:
26 ${entry.repository_name}
26 ${entry.repository_name}
27 %endif
27 %endif
28 </span>
28 </span>
29 </div>
29 </div>
30 <div class="journal_action_params">${h.literal(h.action_parser(entry)[1]())}</div>
30 <div class="journal_action_params">${h.literal(h.action_parser(entry)[1]())}</div>
31 <div class="date"><span class="tooltip" title="${h.tooltip(h.fmt_date(entry.action_date))}">${h.age(entry.action_date)}</span></div>
31 <div class="date"><span class="tooltip" title="${h.tooltip(h.fmt_date(entry.action_date))}">${h.age(entry.action_date)}</span></div>
32 %endfor
32 %endfor
33 </div>
33 </div>
34 </div>
34 </div>
35 %endfor
35 %endfor
36 %endfor
36 %endfor
37
37
38 <div class="pagination-wh pagination-left" style="padding: 0px 0px 0px 10px;">
38 <div class="pagination-wh pagination-left" style="padding: 0px 0px 0px 10px;">
39 ${c.journal_pager.pager('$link_previous ~2~ $link_next')}
39 ${c.journal_pager.pager('$link_previous ~2~ $link_next')}
40 </div>
40 </div>
41 <script type="text/javascript">
41 <script type="text/javascript">
42 YUE.onDOMReady(function(){
42 YUE.onDOMReady(function(){
43 YUE.delegate("journal","click",function(e, matchedEl, container){
43 YUE.delegate("journal","click",function(e, matchedEl, container){
44 ypjax(e.target.href,"journal",function(){
44 ypjax(e.target.href,"journal",function(){
45 show_more_event();
45 show_more_event();
46 tooltip_activate();
46 tooltip_activate();
47 show_changeset_tooltip();
47 show_changeset_tooltip();
48 });
48 });
49 YUE.preventDefault(e);
49 YUE.preventDefault(e);
50 },'.pager_link');
50 },'.pager_link');
51 });
51 });
52 </script>
52 </script>
53 %else:
53 %else:
54 <div style="padding:5px 0px 10px 10px;">
54 <div style="padding:5px 0px 10px 10px;">
55 ${_('No entries yet')}
55 ${_('No entries yet')}
56 </div>
56 </div>
57 %endif
57 %endif
General Comments 0
You need to be logged in to leave comments. Login now