Changeset - 87c97fcea029
[Not reviewed]
rhodecode/lib/base.py
Show inline comments
 
"""The base Controller API
 

	
 
Provides the BaseController class for subclassing.
 
"""
 
import logging
 
import time
 
import traceback
 

	
 
from paste.auth.basic import AuthBasicAuthenticator
 
from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden
 
from paste.httpheaders import WWW_AUTHENTICATE, AUTHORIZATION
 

	
 
from pylons import config, tmpl_context as c, request, session, url
 
from pylons.controllers import WSGIController
 
from pylons.controllers.util import redirect
 
from pylons.templating import render_mako as render
 

	
 
from rhodecode import __version__, BACKENDS
 

	
 
from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
 
    safe_str, safe_int
 
from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
 
    HasPermissionAnyMiddleware, CookieStoreWrapper
 
from rhodecode.lib.utils import get_repo_slug, invalidate_cache
 
from rhodecode.model import meta
 

	
 
from rhodecode.model.db import Repository, RhodeCodeUi, User, RhodeCodeSetting
 
from rhodecode.model.notification import NotificationModel
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.meta import Session
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def _get_ip_addr(environ):
 
    proxy_key = 'HTTP_X_REAL_IP'
 
    proxy_key2 = 'HTTP_X_FORWARDED_FOR'
 
    def_key = 'REMOTE_ADDR'
 

	
 
    ip = environ.get(proxy_key)
 
    if ip:
 
        return ip
 

	
 
    ip = environ.get(proxy_key2)
 
    if ip:
 
        # HTTP_X_FORWARDED_FOR can have mutliple ips inside
 
        # the left-most being the original client, and each successive proxy
 
        # that passed the request adding the IP address where it received the
 
        # request from.
 
        if ',' in ip:
 
            ip = ip.split(',')[0].strip()
 
        return ip
 

	
 
    ip = environ.get(def_key, '0.0.0.0')
 
    return ip
 

	
 

	
 
def _get_access_path(environ):
 
    path = environ.get('PATH_INFO')
 
    org_req = environ.get('pylons.original_request')
 
    if org_req:
 
        path = org_req.environ.get('PATH_INFO')
 
    return path
 

	
 

	
 
class BasicAuth(AuthBasicAuthenticator):
 

	
 
    def __init__(self, realm, authfunc, auth_http_code=None):
 
        self.realm = realm
 
        self.authfunc = authfunc
 
        self._rc_auth_http_code = auth_http_code
 

	
 
    def build_authentication(self):
 
        head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
 
        if self._rc_auth_http_code and self._rc_auth_http_code == '403':
 
            # return 403 if alternative http return code is specified in
 
            # RhodeCode config
 
            return HTTPForbidden(headers=head)
 
        return HTTPUnauthorized(headers=head)
 

	
 
    def authenticate(self, environ):
 
        authorization = AUTHORIZATION(environ)
 
        if not authorization:
 
            return self.build_authentication()
 
        (authmeth, auth) = authorization.split(' ', 1)
 
        if 'basic' != authmeth.lower():
 
            return self.build_authentication()
 
        auth = auth.strip().decode('base64')
 
        _parts = auth.split(':', 1)
 
        if len(_parts) == 2:
 
            username, password = _parts
 
            if self.authfunc(environ, username, password):
 
                return username
 
        return self.build_authentication()
 

	
 
    __call__ = authenticate
 

	
 

	
 
class BaseVCSController(object):
 

	
 
    def __init__(self, application, config):
 
        self.application = application
 
        self.config = config
 
        # base path of repo locations
 
        self.basepath = self.config['base_path']
 
        #authenticate this mercurial request using authfunc
 
        self.authenticate = BasicAuth('', authfunc,
 
                                      config.get('auth_ret_code'))
 
        self.ip_addr = '0.0.0.0'
 

	
 
    def _handle_request(self, environ, start_response):
 
        raise NotImplementedError()
 

	
 
    def _get_by_id(self, repo_name):
 
        """
 
        Get's a special pattern _<ID> from clone url and tries to replace it
 
        with a repository_name for support of _<ID> non changable urls
 

	
 
        :param repo_name:
 
        """
 
        try:
 
            data = repo_name.split('/')
 
            if len(data) >= 2:
 
                by_id = data[1].split('_')
 
                if len(by_id) == 2 and by_id[1].isdigit():
 
                    _repo_name = Repository.get(by_id[1]).repo_name
 
                    data[1] = _repo_name
 
        except:
 
            log.debug('Failed to extract repo_name from id %s' % (
 
                      traceback.format_exc()
 
                      )
 
            )
 

	
 
        return '/'.join(data)
 

	
 
    def _invalidate_cache(self, repo_name):
 
        """
 
        Set's cache for this repository for invalidation on next access
 

	
 
        :param repo_name: full repo name, also a cache key
 
        """
 
        invalidate_cache('get_repo_cached_%s' % repo_name)
 

	
 
    def _check_permission(self, action, user, repo_name, ip_addr=None):
 
        """
 
        Checks permissions using action (push/pull) user and repository
 
        name
 

	
 
        :param action: push or pull action
 
        :param user: user instance
 
        :param repo_name: repository name
 
        """
 
        #check IP
 
        authuser = AuthUser(user_id=user.user_id, ip_addr=ip_addr)
 
        if not authuser.ip_allowed:
 
            return False
 
        else:
 
            log.info('Access for IP:%s allowed' % (ip_addr))
 
        if action == 'push':
 
            if not HasPermissionAnyMiddleware('repository.write',
 
                                              'repository.admin')(user,
 
                                                                  repo_name):
 
                return False
 

	
 
        else:
 
            #any other action need at least read permission
 
            if not HasPermissionAnyMiddleware('repository.read',
 
                                              'repository.write',
 
                                              'repository.admin')(user,
 
                                                                  repo_name):
 
                return False
 

	
 
        return True
 

	
 
    def _get_ip_addr(self, environ):
 
        return _get_ip_addr(environ)
 

	
 
    def _check_ssl(self, environ, start_response):
 
        """
 
        Checks the SSL check flag and returns False if SSL is not present
 
        and required True otherwise
 
        """
 
        org_proto = environ['wsgi._org_proto']
 
        #check if we have SSL required  ! if not it's a bad request !
 
        require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value)
 
        if require_ssl and org_proto == 'http':
 
            log.debug('proto is %s and SSL is required BAD REQUEST !'
 
                      % org_proto)
 
            return False
 
        return True
 

	
 
    def _check_locking_state(self, environ, action, repo, user_id):
 
        """
 
        Checks locking on this repository, if locking is enabled and lock is
 
        present returns a tuple of make_lock, locked, locked_by.
 
        make_lock can have 3 states None (do nothing) True, make lock
 
        False release lock, This value is later propagated to hooks, which
 
        do the locking. Think about this as signals passed to hooks what to do.
 

	
 
        """
 
        locked = False  # defines that locked error should be thrown to user
 
        make_lock = None
 
        repo = Repository.get_by_repo_name(repo)
 
        user = User.get(user_id)
 

	
 
        # this is kind of hacky, but due to how mercurial handles client-server
 
        # server see all operation on changeset; bookmarks, phases and
 
        # obsolescence marker in different transaction, we don't want to check
 
        # locking on those
 
        obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',]
 
        locked_by = repo.locked
 
        if repo and repo.enable_locking and not obsolete_call:
 
            if action == 'push':
 
                #check if it's already locked !, if it is compare users
 
                user_id, _date = repo.locked
 
                if user.user_id == user_id:
 
                    log.debug('Got push from user %s, now unlocking' % (user))
 
                    # unlock if we have push from user who locked
 
                    make_lock = False
 
                else:
 
                    # we're not the same user who locked, ban with 423 !
 
                    locked = True
 
            if action == 'pull':
 
                if repo.locked[0] and repo.locked[1]:
 
                    locked = True
 
                else:
 
                    log.debug('Setting lock on repo %s by %s' % (repo, user))
 
                    make_lock = True
 

	
 
        else:
 
            log.debug('Repository %s do not have locking enabled' % (repo))
 
        log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s'
 
                  % (make_lock, locked, locked_by))
 
        return make_lock, locked, locked_by
 

	
 
    def __call__(self, environ, start_response):
 
        start = time.time()
 
        try:
 
            return self._handle_request(environ, start_response)
 
        finally:
 
            log = logging.getLogger('rhodecode.' + self.__class__.__name__)
 
            log.debug('Request time: %.3fs' % (time.time() - start))
 
            meta.Session.remove()
 

	
 

	
 
class BaseController(WSGIController):
 

	
 
    def __before__(self):
 
        """
 
        __before__ is called before controller methods and after __call__
 
        """
 
        c.rhodecode_version = __version__
 
        c.rhodecode_instanceid = config.get('instance_id')
 
        c.rhodecode_name = config.get('rhodecode_title')
 
        c.use_gravatar = str2bool(config.get('use_gravatar'))
 
        c.ga_code = config.get('rhodecode_ga_code')
 
        # Visual options
 
        c.visual = AttributeDict({})
 
        rc_config = RhodeCodeSetting.get_app_settings()
 

	
 
        c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
 
        c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
 
        c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
 
        c.visual.lightweight_dashboard = str2bool(rc_config.get('rhodecode_lightweight_dashboard'))
 
        c.visual.lightweight_dashboard_items = safe_int(config.get('dashboard_items', 100))
 
        c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
 

	
 
        c.repo_name = get_repo_slug(request)
 
        c.backends = BACKENDS.keys()
 
        c.unread_notifications = NotificationModel()\
 
                        .get_unread_cnt_for_user(c.rhodecode_user.user_id)
 
        self.cut_off_limit = int(config.get('cut_off_limit'))
 

	
 
        self.sa = meta.Session
 
        self.scm_model = ScmModel(self.sa)
 

	
 
    def __call__(self, environ, start_response):
 
        """Invoke the Controller"""
 
        # WSGIController.__call__ dispatches to the Controller method
 
        # the request is routed to. This routing information is
 
        # available in environ['pylons.routes_dict']
 
        start = time.time()
 
        try:
 
            self.ip_addr = _get_ip_addr(environ)
 
            # make sure that we update permissions each time we call controller
 
            api_key = request.GET.get('api_key')
 
            cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
 
            user_id = cookie_store.get('user_id', None)
 
            username = get_container_username(environ, config)
 
            auth_user = AuthUser(user_id, api_key, username, self.ip_addr)
 
            request.user = auth_user
 
            self.rhodecode_user = c.rhodecode_user = auth_user
 
            if not self.rhodecode_user.is_authenticated and \
 
                       self.rhodecode_user.user_id is not None:
 
                self.rhodecode_user.set_authenticated(
 
                    cookie_store.get('is_authenticated')
 
                )
 
            log.info('IP: %s User: %s accessed %s' % (
 
               self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
 
            )
 
            return WSGIController.__call__(self, environ, start_response)
 
        finally:
 
            log.info('IP: %s Request to %s time: %.3fs' % (
 
                _get_ip_addr(environ),
 
                safe_unicode(_get_access_path(environ)), time.time() - start)
 
            )
 
            meta.Session.remove()
 

	
 

	
 
class BaseRepoController(BaseController):
 
    """
 
    Base class for controllers responsible for loading all needed data for
 
    repository loaded items are
 

	
 
    c.rhodecode_repo: instance of scm repository
 
    c.rhodecode_db_repo: instance of db
 
    c.repository_followers: number of followers
 
    c.repository_forks: number of forks
 
    c.repository_following: weather the current user is following the current repo
 

	
 
    """
 

	
 
    def __before__(self):
 
        super(BaseRepoController, self).__before__()
 
        if c.repo_name:
 

	
 
            dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
 
            c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
 
            # update last change according to VCS data
 
            dbr.update_changeset_cache(dbr.get_changeset())
 
            if c.rhodecode_repo is None:
 
                log.error('%s this repository is present in database but it '
 
                          'cannot be created as an scm instance', c.repo_name)
 

	
 
                redirect(url('home'))
 

	
 
            # some globals counter for menu
 
            c.repository_followers = self.scm_model.get_followers(dbr)
 
            c.repository_forks = self.scm_model.get_forks(dbr)
 
            c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
 
            c.repository_following = self.scm_model.is_following_repo(c.repo_name,
 
                                                self.rhodecode_user.user_id)
rhodecode/lib/helpers.py
Show inline comments
 
@@ -524,666 +524,666 @@ def action_parser(user_log, feed=False, 
 
        def lnk(rev, repo_name):
 
            if isinstance(rev, BaseChangeset) or isinstance(rev, AttributeDict):
 
                lazy_cs = True
 
                if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
 
                    lazy_cs = False
 
                    lbl = '?'
 
                    if rev.op == 'delete_branch':
 
                        lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
 
                        title = ''
 
                    elif rev.op == 'tag':
 
                        lbl = '%s' % _('Created tag: %s') % rev.ref_name
 
                        title = ''
 
                    _url = '#'
 

	
 
                else:
 
                    lbl = '%s' % (rev.short_id[:8])
 
                    _url = url('changeset_home', repo_name=repo_name,
 
                               revision=rev.raw_id)
 
                    title = tooltip(rev.message)
 
            else:
 
                ## changeset cannot be found/striped/removed etc.
 
                lbl = ('%s' % rev)[:12]
 
                _url = '#'
 
                title = _('Changeset not found')
 
            if parse_cs:
 
                return link_to(lbl, _url, title=title, class_='tooltip')
 
            return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
 
                           class_='lazy-cs' if lazy_cs else '')
 

	
 
        revs = []
 
        if len(filter(lambda v: v != '', revs_ids)) > 0:
 
            repo = None
 
            for rev in revs_ids[:revs_top_limit]:
 
                _op = _name = None
 
                if len(rev.split('=>')) == 2:
 
                    _op, _name = rev.split('=>')
 

	
 
                # we want parsed changesets, or new log store format is bad
 
                if parse_cs:
 
                    try:
 
                        if repo is None:
 
                            repo = user_log.repository.scm_instance
 
                        _rev = repo.get_changeset(rev)
 
                        revs.append(_rev)
 
                    except ChangesetDoesNotExistError:
 
                        log.error('cannot find revision %s in this repo' % rev)
 
                        revs.append(rev)
 
                        continue
 
                else:
 
                    _rev = AttributeDict({
 
                        'short_id': rev[:12],
 
                        'raw_id': rev,
 
                        'message': '',
 
                        'op': _op,
 
                        'ref_name': _name
 
                    })
 
                    revs.append(_rev)
 
        cs_links = []
 
        cs_links.append(" " + ', '.join(
 
            [lnk(rev, repo_name) for rev in revs[:revs_limit]]
 
            )
 
        )
 

	
 
        compare_view = (
 
            ' <div class="compare_view tooltip" title="%s">'
 
            '<a href="%s">%s</a> </div>' % (
 
                _('Show all combined changesets %s->%s') % (
 
                    revs_ids[0][:12], revs_ids[-1][:12]
 
                ),
 
                url('changeset_home', repo_name=repo_name,
 
                    revision='%s...%s' % (revs_ids[0], revs_ids[-1])
 
                ),
 
                _('compare view')
 
            )
 
        )
 

	
 
        # if we have exactly one more than normally displayed
 
        # just display it, takes less space than displaying
 
        # "and 1 more revisions"
 
        if len(revs_ids) == revs_limit + 1:
 
            rev = revs[revs_limit]
 
            cs_links.append(", " + lnk(rev, repo_name))
 

	
 
        # hidden-by-default ones
 
        if len(revs_ids) > revs_limit + 1:
 
            uniq_id = revs_ids[0]
 
            html_tmpl = (
 
                '<span> %s <a class="show_more" id="_%s" '
 
                'href="#more">%s</a> %s</span>'
 
            )
 
            if not feed:
 
                cs_links.append(html_tmpl % (
 
                      _('and'),
 
                      uniq_id, _('%s more') % (len(revs_ids) - revs_limit),
 
                      _('revisions')
 
                    )
 
                )
 

	
 
            if not feed:
 
                html_tmpl = '<span id="%s" style="display:none">, %s </span>'
 
            else:
 
                html_tmpl = '<span id="%s"> %s </span>'
 

	
 
            morelinks = ', '.join(
 
              [lnk(rev, repo_name) for rev in revs[revs_limit:]]
 
            )
 

	
 
            if len(revs_ids) > revs_top_limit:
 
                morelinks += ', ...'
 

	
 
            cs_links.append(html_tmpl % (uniq_id, morelinks))
 
        if len(revs) > 1:
 
            cs_links.append(compare_view)
 
        return ''.join(cs_links)
 

	
 
    def get_fork_name():
 
        repo_name = action_params
 
        _url = url('summary_home', repo_name=repo_name)
 
        return _('fork name %s') % link_to(action_params, _url)
 

	
 
    def get_user_name():
 
        user_name = action_params
 
        return user_name
 

	
 
    def get_users_group():
 
        group_name = action_params
 
        return group_name
 

	
 
    def get_pull_request():
 
        pull_request_id = action_params
 
        deleted = user_log.repository is None
 
        if deleted:
 
            repo_name = user_log.repository_name
 
        else:
 
            repo_name = user_log.repository.repo_name
 
        return link_to(_('Pull request #%s') % pull_request_id,
 
                    url('pullrequest_show', repo_name=repo_name,
 
                    pull_request_id=pull_request_id))
 

	
 
    # action : translated str, callback(extractor), icon
 
    action_map = {
 
    'user_deleted_repo':           (_('[deleted] repository'),
 
                                    None, 'database_delete.png'),
 
    'user_created_repo':           (_('[created] repository'),
 
                                    None, 'database_add.png'),
 
    'user_created_fork':           (_('[created] repository as fork'),
 
                                    None, 'arrow_divide.png'),
 
    'user_forked_repo':            (_('[forked] repository'),
 
                                    get_fork_name, 'arrow_divide.png'),
 
    'user_updated_repo':           (_('[updated] repository'),
 
                                    None, 'database_edit.png'),
 
    'admin_deleted_repo':          (_('[delete] repository'),
 
                                    None, 'database_delete.png'),
 
    'admin_created_repo':          (_('[created] repository'),
 
                                    None, 'database_add.png'),
 
    'admin_forked_repo':           (_('[forked] repository'),
 
                                    None, 'arrow_divide.png'),
 
    'admin_updated_repo':          (_('[updated] repository'),
 
                                    None, 'database_edit.png'),
 
    'admin_created_user':          (_('[created] user'),
 
                                    get_user_name, 'user_add.png'),
 
    'admin_updated_user':          (_('[updated] user'),
 
                                    get_user_name, 'user_edit.png'),
 
    'admin_created_users_group':   (_('[created] users group'),
 
                                    get_users_group, 'group_add.png'),
 
    'admin_updated_users_group':   (_('[updated] users group'),
 
                                    get_users_group, 'group_edit.png'),
 
    'user_commented_revision':     (_('[commented] on revision in repository'),
 
                                    get_cs_links, 'comment_add.png'),
 
    'user_commented_pull_request': (_('[commented] on pull request for'),
 
                                    get_pull_request, 'comment_add.png'),
 
    'user_closed_pull_request':    (_('[closed] pull request for'),
 
                                    get_pull_request, 'tick.png'),
 
    'push':                        (_('[pushed] into'),
 
                                    get_cs_links, 'script_add.png'),
 
    'push_local':                  (_('[committed via RhodeCode] into repository'),
 
                                    get_cs_links, 'script_edit.png'),
 
    'push_remote':                 (_('[pulled from remote] into repository'),
 
                                    get_cs_links, 'connect.png'),
 
    'pull':                        (_('[pulled] from'),
 
                                    None, 'down_16.png'),
 
    'started_following_repo':      (_('[started following] repository'),
 
                                    None, 'heart_add.png'),
 
    'stopped_following_repo':      (_('[stopped following] repository'),
 
                                    None, 'heart_delete.png'),
 
    }
 

	
 
    action_str = action_map.get(action, action)
 
    if feed:
 
        action = action_str[0].replace('[', '').replace(']', '')
 
    else:
 
        action = action_str[0]\
 
            .replace('[', '<span class="journal_highlight">')\
 
            .replace(']', '</span>')
 

	
 
    action_params_func = lambda: ""
 

	
 
    if callable(action_str[1]):
 
        action_params_func = action_str[1]
 

	
 
    def action_parser_icon():
 
        action = user_log.action
 
        action_params = None
 
        x = action.split(':')
 

	
 
        if len(x) > 1:
 
            action, action_params = x
 

	
 
        tmpl = """<img src="%s%s" alt="%s"/>"""
 
        ico = action_map.get(action, ['', '', ''])[2]
 
        return literal(tmpl % ((url('/images/icons/')), ico, action))
 

	
 
    # returned callbacks we need to call to get
 
    return [lambda: literal(action), action_params_func, action_parser_icon]
 

	
 

	
 

	
 
#==============================================================================
 
# PERMS
 
#==============================================================================
 
from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
 
HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \
 
HasReposGroupPermissionAny
 

	
 

	
 
#==============================================================================
 
# GRAVATAR URL
 
#==============================================================================
 

	
 
def gravatar_url(email_address, size=30):
 
    from pylons import url  # doh, we need to re-import url to mock it later
 
    _def = 'anonymous@rhodecode.org'
 
    use_gravatar = str2bool(config['app_conf'].get('use_gravatar'))
 
    email_address = email_address or _def
 
    if (not use_gravatar or not email_address or email_address == _def):
 
        f = lambda a, l: min(l, key=lambda x: abs(x - a))
 
        return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30]))
 

	
 
    if use_gravatar and config['app_conf'].get('alternative_gravatar_url'):
 
        tmpl = config['app_conf'].get('alternative_gravatar_url', '')
 
        parsed_url = urlparse.urlparse(url.current(qualified=True))
 
        tmpl = tmpl.replace('{email}', email_address)\
 
                   .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \
 
                   .replace('{netloc}', parsed_url.netloc)\
 
                   .replace('{scheme}', parsed_url.scheme)\
 
                   .replace('{size}', str(size))
 
        return tmpl
 

	
 
    ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
 
    default = 'identicon'
 
    baseurl_nossl = "http://www.gravatar.com/avatar/"
 
    baseurl_ssl = "https://secure.gravatar.com/avatar/"
 
    baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
 

	
 
    if isinstance(email_address, unicode):
 
        #hashlib crashes on unicode items
 
        email_address = safe_str(email_address)
 
    # construct the url
 
    gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
 
    gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
 

	
 
    return gravatar_url
 

	
 

	
 
#==============================================================================
 
# REPO PAGER, PAGER FOR REPOSITORY
 
#==============================================================================
 
class RepoPage(Page):
 

	
 
    def __init__(self, collection, page=1, items_per_page=20,
 
                 item_count=None, url=None, **kwargs):
 

	
 
        """Create a "RepoPage" instance. special pager for paging
 
        repository
 
        """
 
        self._url_generator = url
 

	
 
        # Safe the kwargs class-wide so they can be used in the pager() method
 
        self.kwargs = kwargs
 

	
 
        # Save a reference to the collection
 
        self.original_collection = collection
 

	
 
        self.collection = collection
 

	
 
        # The self.page is the number of the current page.
 
        # The first page has the number 1!
 
        try:
 
            self.page = int(page)  # make it int() if we get it as a string
 
        except (ValueError, TypeError):
 
            self.page = 1
 

	
 
        self.items_per_page = items_per_page
 

	
 
        # Unless the user tells us how many items the collections has
 
        # we calculate that ourselves.
 
        if item_count is not None:
 
            self.item_count = item_count
 
        else:
 
            self.item_count = len(self.collection)
 

	
 
        # Compute the number of the first and last available page
 
        if self.item_count > 0:
 
            self.first_page = 1
 
            self.page_count = int(math.ceil(float(self.item_count) /
 
                                            self.items_per_page))
 
            self.last_page = self.first_page + self.page_count - 1
 

	
 
            # Make sure that the requested page number is the range of
 
            # valid pages
 
            if self.page > self.last_page:
 
                self.page = self.last_page
 
            elif self.page < self.first_page:
 
                self.page = self.first_page
 

	
 
            # Note: the number of items on this page can be less than
 
            #       items_per_page if the last page is not full
 
            self.first_item = max(0, (self.item_count) - (self.page *
 
                                                          items_per_page))
 
            self.last_item = ((self.item_count - 1) - items_per_page *
 
                              (self.page - 1))
 

	
 
            self.items = list(self.collection[self.first_item:self.last_item + 1])
 

	
 
            # Links to previous and next page
 
            if self.page > self.first_page:
 
                self.previous_page = self.page - 1
 
            else:
 
                self.previous_page = None
 

	
 
            if self.page < self.last_page:
 
                self.next_page = self.page + 1
 
            else:
 
                self.next_page = None
 

	
 
        # No items available
 
        else:
 
            self.first_page = None
 
            self.page_count = 0
 
            self.last_page = None
 
            self.first_item = None
 
            self.last_item = None
 
            self.previous_page = None
 
            self.next_page = None
 
            self.items = []
 

	
 
        # This is a subclass of the 'list' type. Initialise the list now.
 
        list.__init__(self, reversed(self.items))
 

	
 

	
 
def changed_tooltip(nodes):
 
    """
 
    Generates a html string for changed nodes in changeset page.
 
    It limits the output to 30 entries
 

	
 
    :param nodes: LazyNodesGenerator
 
    """
 
    if nodes:
 
        pref = ': <br/> '
 
        suf = ''
 
        if len(nodes) > 30:
 
            suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
 
        return literal(pref + '<br/> '.join([safe_unicode(x.path)
 
                                             for x in nodes[:30]]) + suf)
 
    else:
 
        return ': ' + _('No Files')
 

	
 

	
 
def repo_link(groups_and_repos, last_url=None):
 
    """
 
    Makes a breadcrumbs link to repo within a group
 
    joins &raquo; on each group to create a fancy link
 

	
 
    ex::
 
        group >> subgroup >> repo
 

	
 
    :param groups_and_repos:
 
    :param last_url:
 
    """
 
    groups, repo_name = groups_and_repos
 
    last_link = link_to(repo_name, last_url) if last_url else repo_name
 

	
 
    if not groups:
 
        if last_url:
 
            return last_link
 
        return repo_name
 
            return literal('<span>%s</span>' % last_link)
 
        return literal('<span>%s</span>' % repo_name)
 
    else:
 
        def make_link(group):
 
            return link_to(group.name,
 
                           url('repos_group_home', group_name=group.group_name))
 
        return literal(' &raquo; '.join(map(make_link, groups) + [last_link]))
 
        return literal(' &raquo; '.join(map(make_link, groups) + ['<span>' + last_link + '</span>']))
 

	
 

	
 
def fancy_file_stats(stats):
 
    """
 
    Displays a fancy two colored bar for number of added/deleted
 
    lines of code on file
 

	
 
    :param stats: two element list of added/deleted lines of code
 
    """
 
    def cgen(l_type, a_v, d_v):
 
        mapping = {'tr': 'top-right-rounded-corner-mid',
 
                   'tl': 'top-left-rounded-corner-mid',
 
                   'br': 'bottom-right-rounded-corner-mid',
 
                   'bl': 'bottom-left-rounded-corner-mid'}
 
        map_getter = lambda x: mapping[x]
 

	
 
        if l_type == 'a' and d_v:
 
            #case when added and deleted are present
 
            return ' '.join(map(map_getter, ['tl', 'bl']))
 

	
 
        if l_type == 'a' and not d_v:
 
            return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
 

	
 
        if l_type == 'd' and a_v:
 
            return ' '.join(map(map_getter, ['tr', 'br']))
 

	
 
        if l_type == 'd' and not a_v:
 
            return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
 

	
 
    a, d = stats[0], stats[1]
 
    width = 100
 

	
 
    if a == 'b':
 
        #binary mode
 
        b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
 
        b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
 
        return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
 

	
 
    t = stats[0] + stats[1]
 
    unit = float(width) / (t or 1)
 

	
 
    # needs > 9% of width to be visible or 0 to be hidden
 
    a_p = max(9, unit * a) if a > 0 else 0
 
    d_p = max(9, unit * d) if d > 0 else 0
 
    p_sum = a_p + d_p
 

	
 
    if p_sum > width:
 
        #adjust the percentage to be == 100% since we adjusted to 9
 
        if a_p > d_p:
 
            a_p = a_p - (p_sum - width)
 
        else:
 
            d_p = d_p - (p_sum - width)
 

	
 
    a_v = a if a > 0 else ''
 
    d_v = d if d > 0 else ''
 

	
 
    d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
 
        cgen('a', a_v, d_v), a_p, a_v
 
    )
 
    d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
 
        cgen('d', a_v, d_v), d_p, d_v
 
    )
 
    return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
 

	
 

	
 
def urlify_text(text_):
 
    """
 
    Extrac urls from text and make html links out of them
 

	
 
    :param text_:
 
    """
 

	
 
    url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
 
                         '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
 

	
 
    def url_func(match_obj):
 
        url_full = match_obj.groups()[0]
 
        return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
 

	
 
    return literal(url_pat.sub(url_func, text_))
 

	
 

	
 
def urlify_changesets(text_, repository):
 
    """
 
    Extract revision ids from changeset and make link from them
 

	
 
    :param text_:
 
    :param repository: repo name to build the URL with
 
    """
 
    from pylons import url  # doh, we need to re-import url to mock it later
 
    URL_PAT = re.compile(r'(?:^|\s)([0-9a-fA-F]{12,40})(?:$|\s)')
 

	
 
    def url_func(match_obj):
 
        rev = match_obj.groups()[0]
 
        pref = ''
 
        suf = ''
 
        if match_obj.group().startswith(' '):
 
            pref = ' '
 
        if match_obj.group().endswith(' '):
 
            suf = ' '
 
        tmpl = (
 
        '%(pref)s<a class="%(cls)s" href="%(url)s">'
 
        '%(rev)s'
 
        '</a>'
 
        '%(suf)s'
 
        )
 
        return tmpl % {
 
         'pref': pref,
 
         'cls': 'revision-link',
 
         'url': url('changeset_home', repo_name=repository, revision=rev),
 
         'rev': rev,
 
         'suf': suf
 
        }
 

	
 
    newtext = URL_PAT.sub(url_func, text_)
 

	
 
    return newtext
 

	
 

	
 
def urlify_commit(text_, repository=None, link_=None):
 
    """
 
    Parses given text message and makes proper links.
 
    issues are linked to given issue-server, and rest is a changeset link
 
    if link_ is given, in other case it's a plain text
 

	
 
    :param text_:
 
    :param repository:
 
    :param link_: changeset link
 
    """
 
    import traceback
 
    from pylons import url  # doh, we need to re-import url to mock it later
 

	
 
    def escaper(string):
 
        return string.replace('<', '&lt;').replace('>', '&gt;')
 

	
 
    def linkify_others(t, l):
 
        urls = re.compile(r'(\<a.*?\<\/a\>)',)
 
        links = []
 
        for e in urls.split(t):
 
            if not urls.match(e):
 
                links.append('<a class="message-link" href="%s">%s</a>' % (l, e))
 
            else:
 
                links.append(e)
 

	
 
        return ''.join(links)
 

	
 
    # urlify changesets - extrac revisions and make link out of them
 
    newtext = urlify_changesets(escaper(text_), repository)
 

	
 
    # extract http/https links and make them real urls
 
    newtext = urlify_text(newtext)
 

	
 
    try:
 
        from rhodecode import CONFIG
 
        conf = CONFIG
 

	
 
        # allow multiple issue servers to be used
 
        valid_indices = [
 
            x.group(1)
 
            for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys())
 
            if x and 'issue_server_link%s' % x.group(1) in conf
 
            and 'issue_prefix%s' % x.group(1) in conf
 
        ]
 

	
 
        log.debug('found issue server suffixes `%s` during valuation of: %s'
 
                  % (','.join(valid_indices), newtext))
 

	
 
        for pattern_index in valid_indices:
 
            ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index)
 
            ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index)
 
            ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index)
 

	
 
            log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s'
 
                      % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK,
 
                         ISSUE_PREFIX))
 

	
 
            URL_PAT = re.compile(r'%s' % ISSUE_PATTERN)
 

	
 
            def url_func(match_obj):
 
                pref = ''
 
                if match_obj.group().startswith(' '):
 
                    pref = ' '
 

	
 
                issue_id = ''.join(match_obj.groups())
 
                tmpl = (
 
                '%(pref)s<a class="%(cls)s" href="%(url)s">'
 
                '%(issue-prefix)s%(id-repr)s'
 
                '</a>'
 
                )
 
                url = ISSUE_SERVER_LNK.replace('{id}', issue_id)
 
                if repository:
 
                    url = url.replace('{repo}', repository)
 
                    repo_name = repository.split(URL_SEP)[-1]
 
                    url = url.replace('{repo_name}', repo_name)
 

	
 
                return tmpl % {
 
                     'pref': pref,
 
                     'cls': 'issue-tracker-link',
 
                     'url': url,
 
                     'id-repr': issue_id,
 
                     'issue-prefix': ISSUE_PREFIX,
 
                     'serv': ISSUE_SERVER_LNK,
 
                }
 
            newtext = URL_PAT.sub(url_func, newtext)
 
            log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext))
 

	
 
        # if we actually did something above
 
        if link_:
 
            # wrap not links into final link => link_
 
            newtext = linkify_others(newtext, link_)
 
    except:
 
        log.error(traceback.format_exc())
 
        pass
 

	
 
    return literal(newtext)
 

	
 

	
 
def rst(source):
 
    return literal('<div class="rst-block">%s</div>' %
 
                   MarkupRenderer.rst(source))
 

	
 

	
 
def rst_w_mentions(source):
 
    """
 
    Wrapped rst renderer with @mention highlighting
 

	
 
    :param source:
 
    """
 
    return literal('<div class="rst-block">%s</div>' %
 
                   MarkupRenderer.rst_with_mentions(source))
 

	
 

	
 
def changeset_status(repo, revision):
 
    return ChangesetStatusModel().get_status(repo, revision)
 

	
 

	
 
def changeset_status_lbl(changeset_status):
 
    return dict(ChangesetStatus.STATUSES).get(changeset_status)
 

	
 

	
 
def get_permission_name(key):
 
    return dict(Permission.PERMS).get(key)
 

	
 

	
 
def journal_filter_help():
 
    return _(textwrap.dedent('''
 
        Example filter terms:
 
            repository:vcs
 
            username:marcin
 
            action:*push*
 
            ip:127.0.0.1
 
            date:20120101
 
            date:[20120101100000 TO 20120102]
 

	
 
        Generate wildcards using '*' character:
 
            "repositroy:vcs*" - search everything starting with 'vcs'
 
            "repository:*vcs*" - search for repository containing 'vcs'
 

	
 
        Optional AND / OR operators in queries
 
            "repository:vcs OR repository:test"
 
            "username:test AND repository:test*"
 
    '''))
 

	
 

	
 
def not_mapped_error(repo_name):
 
    flash(_('%s repository is not mapped to db perhaps'
 
            ' it was created or renamed from the filesystem'
 
            ' please run the application again'
 
            ' in order to rescan repositories') % repo_name, category='error')
 

	
 

	
 
def ip_range(ip_addr):
 
    from rhodecode.model.db import UserIpMap
 
    s, e = UserIpMap._get_ip_range(ip_addr)
 
    return '%s - %s' % (s, e)
rhodecode/public/css/contextbar.css
Show inline comments
 
new file 100644
 
/**
 
 * Stylesheets for the context bar
 
 */
 

	
 
#context-bar button.follow 		{ background-image: url("../images/icons/heart.png"); }
 
#context-bar button.following	{ background-image: url("../images/icons/heart_delete.png"); }
 
#context-bar a.fork 			{ background-image: url("../images/icons/arrow_divide.png"); }
 
#context-bar a.summary 			{ background-image: url("../images/icons/clipboard_16.png"); }
 
#context-bar a.changelogs 		{ background-image: url("../images/icons/time.png"); }
 
#context-bar a.files 			{ background-image: url("../images/icons/file.png"); }
 
#context-bar a.switch-to 		{ background-image: url("../images/icons/arrow_switch.png"); }
 
#context-bar a.options 			{ background-image: url("../images/icons/table_gear.png"); }
 
#context-bar a.pull-request 	{ background-image: url("../images/icons/arrow_join.png"); }
 
#context-bar a.branches 		{ background-image: url("../images/icons/arrow_branch.png"); }
 
#context-bar a.tags 			{ background-image: url("../images/icons/tag_blue.png"); }
 
#context-bar a.bookmarks		{ background-image: url("../images/icons/tag_green.png"); }
 
#context-bar a.settings 		{ background-image: url("../images/icons/cog.png"); }
 
#context-bar a.shortlog 		{ background-image: url("../images/icons/time.png"); }
 
#context-bar a.search 			{ background-image: url("../images/icons/search_16.png"); }
 
#context-bar a.admin 			{ background-image: url("../images/icons/cog_edit.png"); }
 

	
 
#context-bar a.journal			{ background-image: url("../images/icons/book.png"); }
 
#context-bar a.repos 			{ background-image: url("../images/icons/database_edit.png"); }
 
#context-bar a.repos_groups		{ background-image: url("../images/icons/database_link.png"); }
 
#context-bar a.users			{ background-image: url("../images/icons/user_edit.png"); }
 
#context-bar a.groups 			{ background-image: url("../images/icons/group_edit.png"); }
 
#context-bar a.permissions  	{ background-image: url("../images/icons/key.png"); }
 
#context-bar a.ldap 			{ background-image: url("../images/icons/server_key.png"); }
 
#context-bar a.defaults			{ background-image: url("../images/icons/wrench.png"); }
 
#context-bar a.settings			{ background-image: url("../images/icons/cog_edit.png"); }
 

	
 
#content #context-bar {
 
	position: relative;
 
	background-color: #003B76 !important;
 
	padding: 0px;
 
	overflow: visible;
 
}
 

	
 
#content #context-bar,
 
#content #context-bar a,
 
#content #context-bar button {
 
 	color: #FFFFFF;
 
}
 

	
 
#content #context-bar a:hover,
 
#content #context-bar button:hover {
 
 	text-decoration: none;
 
 	color: #bfe3ff;
 
}
 

	
 
#content #context-bar .icon {
 
	display: inline-block;
 
	width: 16px;
 
	height: 16px;
 
	vertical-align: text-bottom;
 
}
 

	
 
ul.horizontal-list {
 
	display: block;
 
/*	overflow: hidden;*/
 
}
 
ul.horizontal-list > li {
 
	float: left;
 
	padding-right: 5px;
 
	position: relative;
 
}
 

	
 
ul.horizontal-list > li ul {
 
	position: absolute;
 
	display: none;
 
	right: 0;
 
}
 

	
 
ul.horizontal-list li:hover > ul {
 
	display: block;
 
}
 

	
 
ul.horizontal-list ul li {
 
	position: relative;
 
	border-bottom: 1px solid rgba(0,0,0,0.1);
 
	border-top: 1px solid rgba(255,255,255,0.1);
 
}
 

	
 
ul.horizontal-list > li ul ul {
 
	position: absolute;
 
	right: 100%;
 
	top: -1px;
 
	min-width: 200px;
 
	max-height: 400px;
 
	overflow-x:hidden;
 
	overflow-y:auto;
 
}
 

	
 
ul.horizontal-list > li a {
 
	white-space: nowrap;
 
}
 

	
 
#breadcrumbs {
 
	float:left;
 
	padding: 12px 0;
 
	font-weight: bold;
 
}
 

	
 
#breadcrumbs span{
 
	font-weight: bold;
 
	font-size: 2em;
 
}
 

	
 
#context-top {
 
	position: relative;
 
	overflow: hidden;
 
	border-bottom: 1px solid #003162;
 
	padding: 10px;
 
}
 

	
 
#revision-changer,
 
#context-pages,
 
#context-pages ul,
 
ul#context-actions {
 
	background: #3b6998; /* Old browsers */
 
	background: -moz-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* FF3.6+ */
 
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4574a2), color-stop(100%,#2f5d8b)); /* Chrome,Safari4+ */
 
	background: -webkit-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* Chrome10+,Safari5.1+ */
 
	background: -o-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* Opera 11.10+ */
 
	background: -ms-linear-gradient(top, #4574a2 0%, #2f5d8b 100%); /* IE10+ */
 
	background: linear-gradient(to bottom, #4574a2 0%, #2f5d8b 100%); /* W3C */
 
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4574a2', endColorstr='#2f5d8b',GradientType=0 ); /* IE6-9 */
 
}
 

	
 
#context-actions a,
 
#context-pages a {
 
	background-repeat: no-repeat;
 
	background-position: 10px 50%;
 
	padding-left: 30px;
 
}
 

	
 
#context-pages ul ul a{
 
	padding-left: 10px;
 
}
 

	
 
ul#context-actions {
 
	display: inline-block;
 
	float: right;
 
	border-radius: 4px;
 
	background-color:#3b6998;
 
	background-image: linear-gradient(top, #4574a2 0%, #2f5d8b 100%);
 
	padding: 5px;
 
}
 

	
 
#content ul#context-actions li {
 
	padding: 0px;
 
	border-right: 1px solid rgba(0,0,0,0.1);
 
	border-left: 1px solid rgba(255,255,255,0.1);
 
}
 

	
 
#context-actions button,
 
#context-actions a {
 
	display: block;
 
	cursor: pointer;
 
	background: none;
 
	border: none;
 
	margin: 0px;
 
	height: 13px;
 
	padding: 3px 7px;
 
	background-repeat: no-repeat;
 
	background-position: 50% 3px;
 
	padding-top: 24px;
 
}
 

	
 
#context-actions button{
 
	padding-top: 22px;
 
	height: 40px;
 
}
 

	
 
#revision-changer:hover,
 
#context-pages li:hover,
 
#context-actions li:hover,
 
#content #context-actions li:hover {
 
	/*background: rgba(255,255,255,0.2);*/
 
	background: #6388ad; /* Old browsers */
 
	background: -moz-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* FF3.6+ */
 
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
 
	background: -webkit-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
 
	background: -o-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* Opera 11.10+ */
 
	background: -ms-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* IE10+ */
 
	background: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%); /* W3C */
 
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#88bfe8', endColorstr='#70b0e0',GradientType=0 ); /* IE6-9 */
 

	
 
	background-image: -webkit-gradient(linear, left top, left bottom, rgb(255,255,255) 0%, rgb(255,255,255) 100%);
 
	
 
	/*border-radius: 4px;*/
 
}
 

	
 

	
 
#content #context-actions li:first-child {
 
	border-left: none;
 
	border-radius:4px 0 0px 4px; 
 
}
 

	
 
#content #context-actions li:last-child {
 
	border-right: none;
 
	border-radius:0 4px 4px 0; 
 
}
 

	
 
#content  #context-actions .icon{
 
	margin: auto;
 
	margin-bottom: 5px;
 
	display: block;
 
	clear: both;
 
	float: none;
 
}
 

	
 
#content  #context-actions button.follow,
 
#content  #context-actions button.following{
 
	width: auto;
 
	float: none;
 
}
 

	
 
#content  #context-actions button .show-following,
 
#content  #context-actions button .show-follow {
 
	display: none;
 
}
 

	
 
#content #context-bar #context-actions button.follow .show-follow {
 
	display: block;
 
}
 

	
 
#content #context-bar #context-actions button.following .show-following {
 
	display: block;
 
}
 

	
 
#context-state {
 
	background-color: #336699;
 
	border-top: 1px solid #517da8;
 
/*	overflow: hidden;*/
 
}
 

	
 
#context-pages {
 
	float: right;
 
	border-left: 1px solid rgba(0,0,0,0.1);
 
/*	overflow: hidden;*/
 
}
 

	
 
#context-pages li.current{
 
	background: #535353; /* Old browsers */
 
	background: -moz-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* FF3.6+ */
 
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#5d5d5d), color-stop(100%,#484848)); /* Chrome,Safari4+ */
 
	background: -webkit-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* Chrome10+,Safari5.1+ */
 
	background: -o-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* Opera 11.10+ */
 
	background: -ms-linear-gradient(top, #5d5d5d 0%, #484848 100%); /* IE10+ */
 
	background: linear-gradient(to bottom, #5d5d5d 0%, #484848 100%); /* W3C */
 
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#5d5d5d', endColorstr='#484848',GradientType=0 ); /* IE6-9 */
 
}
 

	
 
#content #context-pages .icon {
 
	margin-right:5px;
 
}
 

	
 
#content #context-pages li {
 
	border-right: 1px solid rgba(0,0,0,0.1);
 
	border-left: 1px solid rgba(255,255,255,0.1);
 
	padding: 0;
 
}
 

	
 
#content #context-pages li:last-child {
 
	border-right:none;
 
}
 

	
 
#context-pages a, 
 
#context-pages .admin_menu a{
 
	display: block;
 
	padding: 0px 10px;
 
	padding-left: 30px;
 
	line-height: 35px;
 
}
 

	
 
#revision-changer:before,
 
#context-pages a.childs:after,
 
#context-pages a.dropdown:after {
 
	content: ' \25BE';
 
}
 
#context-pages a.childs:after{
 
	float: right;
 
	padding-left: 5px;
 
}
 

	
 
#revision-changer:before {
 
	position: absolute;
 
	top: 0px;
 
	right: 0px;
 
	border-right: 1px solid rgba(0,0,0,0.1);
 
	height: 25px;
 
	padding-top: 10px;
 
	padding-right: 10px;
 
}
 

	
 
#context-pages li:last-child a {
 
	padding-right: 10px;
 
}
 

	
 
#context-bar #revision-changer {
 
	position: relative;
 
	cursor: pointer;
 
	border: none;
 
	padding: 0;
 
	margin: 0;
 
	color: #FFFFFF;
 
	font-size: 0.85em;
 
	padding: 2px 15px;
 
	padding-bottom: 3px;
 
	padding-right: 30px;
 
	border-right: 1px solid rgba(255,255,255,0.1);
 
}
 

	
 
#revision-changer .branch-name,
 
#revision-changer .revision {
 
	display: block;
 
	text-align: center;
 
	line-height: 1.5em;
 
}
 

	
 
#revision-changer .branch-name {
 
	font-weight: bold;
 
}
 

	
 
#revision-changer .revision{
 
	text-transform: uppercase;
 
}
 

	
 

	
rhodecode/public/css/style.css
Show inline comments
 
@@ -3120,769 +3120,769 @@ table.code-browser .submodule-dir {
 
}
 

	
 
.ac .yui-ac-shadow {
 
    position: absolute;
 
    width: 100%;
 
    background: #000;
 
    -moz-opacity: 0.1px;
 
    opacity: .10;
 
    filter: alpha(opacity = 10);
 
    z-index: 9049;
 
    margin: .3em;
 
}
 

	
 
.ac .yui-ac-content ul {
 
    width: 100%;
 
    margin: 0;
 
    padding: 0;
 
    z-index: 9050;
 
}
 

	
 
.ac .yui-ac-content li {
 
    cursor: default;
 
    white-space: nowrap;
 
    margin: 0;
 
    padding: 2px 5px;
 
    height: 18px;
 
    z-index: 9050;
 
    display: block;
 
    width: auto !important;
 
}
 

	
 
.ac .yui-ac-content li .ac-container-wrap {
 
    width: auto;
 
}
 

	
 
.ac .yui-ac-content li.yui-ac-prehighlight {
 
    background: #B3D4FF;
 
    z-index: 9050;
 
}
 

	
 
.ac .yui-ac-content li.yui-ac-highlight {
 
    background: #556CB5;
 
    color: #FFF;
 
    z-index: 9050;
 
}
 
.ac .yui-ac-bd {
 
    z-index: 9050;
 
}
 

	
 
.follow {
 
    background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
 
    height: 16px;
 
    width: 20px;
 
    cursor: pointer;
 
    display: block;
 
    float: right;
 
    margin-top: 2px;
 
}
 

	
 
.following {
 
    background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
 
    height: 16px;
 
    width: 20px;
 
    cursor: pointer;
 
    display: block;
 
    float: right;
 
    margin-top: 2px;
 
}
 

	
 
.reposize {
 
    background: url("../images/icons/server.png") no-repeat scroll 3px;
 
    height: 16px;
 
    width: 20px;
 
    cursor: pointer;
 
    display: block;
 
    float: right;
 
    margin-top: 2px;
 
}
 

	
 
#repo_size {
 
    display: block;
 
    margin-top: 4px;
 
    color: #666;
 
    float:right;
 
}
 

	
 
.locking_locked {
 
    background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px;
 
    height: 16px;
 
    width: 20px;
 
    cursor: pointer;
 
    display: block;
 
    float: right;
 
    margin-top: 2px;
 
}
 

	
 
.locking_unlocked {
 
    background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px;
 
    height: 16px;
 
    width: 20px;
 
    cursor: pointer;
 
    display: block;
 
    float: right;
 
    margin-top: 2px;
 
}
 

	
 
.currently_following {
 
    padding-left: 10px;
 
    padding-bottom: 5px;
 
}
 

	
 
.add_icon {
 
    background: url("../images/icons/add.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 0px;
 
    text-align: left;
 
}
 

	
 
.accept_icon {
 
    background: url("../images/icons/accept.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 0px;
 
    text-align: left;
 
}
 

	
 
.edit_icon {
 
    background: url("../images/icons/application_form_edit.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 0px;
 
    text-align: left;
 
}
 

	
 
.delete_icon {
 
    background: url("../images/icons/delete.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 0px;
 
    text-align: left;
 
}
 

	
 
.refresh_icon {
 
    background: url("../images/icons/arrow_refresh.png") no-repeat scroll
 
        3px;
 
    padding-left: 20px;
 
    padding-top: 0px;
 
    text-align: left;
 
}
 

	
 
.pull_icon {
 
    background: url("../images/icons/connect.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 0px;
 
    text-align: left;
 
}
 

	
 
.rss_icon {
 
    background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 4px;
 
    text-align: left;
 
    font-size: 8px
 
}
 

	
 
.atom_icon {
 
    background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    padding-top: 4px;
 
    text-align: left;
 
    font-size: 8px
 
}
 

	
 
.archive_icon {
 
    background: url("../images/icons/compress.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    text-align: left;
 
    padding-top: 1px;
 
}
 

	
 
.start_following_icon {
 
    background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    text-align: left;
 
    padding-top: 0px;
 
}
 

	
 
.stop_following_icon {
 
    background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
 
    padding-left: 20px;
 
    text-align: left;
 
    padding-top: 0px;
 
}
 

	
 
.action_button {
 
    border: 0;
 
    display: inline;
 
}
 

	
 
.action_button:hover {
 
    border: 0;
 
    text-decoration: underline;
 
    cursor: pointer;
 
}
 

	
 
#switch_repos {
 
    position: absolute;
 
    height: 25px;
 
    z-index: 1;
 
}
 

	
 
#switch_repos select {
 
    min-width: 150px;
 
    max-height: 250px;
 
    z-index: 1;
 
}
 

	
 
.breadcrumbs {
 
    border: medium none;
 
    color: #FFF;
 
    float: left;
 
    font-weight: 700;
 
    font-size: 14px;
 
    margin: 0;
 
    padding: 11px 0 11px 10px;
 
}
 

	
 
.breadcrumbs .hash {
 
    text-transform: none;
 
    color: #fff;
 
}
 

	
 
.breadcrumbs a {
 
    color: #FFF;
 
}
 

	
 
.flash_msg {
 
}
 

	
 
.flash_msg ul {
 
}
 

	
 
.error_red {
 
    color:red;
 
}
 

	
 
.error_msg {
 
    background-color: #c43c35;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35) );
 
    background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) );
 
    background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: linear-gradient(top, #ee5f5b, #c43c35);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 );
 
    border-color: #c43c35 #c43c35 #882a25;
 
}
 

	
 
.warning_msg {
 
    color: #404040 !important;
 
    background-color: #eedc94;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94) );
 
    background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
 
    background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) );
 
    background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
 
    background-image: -o-linear-gradient(top, #fceec1, #eedc94);
 
    background-image: linear-gradient(top, #fceec1, #eedc94);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 );
 
    border-color: #eedc94 #eedc94 #e4c652;
 
}
 

	
 
.success_msg {
 
    background-color: #57a957;
 
    background-repeat: repeat-x !important;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957) );
 
    background-image: -moz-linear-gradient(top, #62c462, #57a957);
 
    background-image: -ms-linear-gradient(top, #62c462, #57a957);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) );
 
    background-image: -webkit-linear-gradient(top, #62c462, #57a957);
 
    background-image: -o-linear-gradient(top, #62c462, #57a957);
 
    background-image: linear-gradient(top, #62c462, #57a957);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 );
 
    border-color: #57a957 #57a957 #3d773d;
 
}
 

	
 
.notice_msg {
 
    background-color: #339bb9;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9) );
 
    background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) );
 
    background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: linear-gradient(top, #5bc0de, #339bb9);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 );
 
    border-color: #339bb9 #339bb9 #22697d;
 
}
 

	
 
.success_msg, .error_msg, .notice_msg, .warning_msg {
 
    font-size: 12px;
 
    font-weight: 700;
 
    min-height: 14px;
 
    line-height: 14px;
 
    margin-bottom: 10px;
 
    margin-top: 0;
 
    display: block;
 
    overflow: auto;
 
    padding: 6px 10px 6px 10px;
 
    border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
 
    position: relative;
 
    color: #FFF;
 
    border-width: 1px;
 
    border-style: solid;
 
    -webkit-border-radius: 4px;
 
    -moz-border-radius: 4px;
 
    border-radius: 4px;
 
    -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
 
    -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
 
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
 
}
 

	
 
#msg_close {
 
    background: transparent url("../icons/cross_grey_small.png") no-repeat scroll 0 0;
 
    cursor: pointer;
 
    height: 16px;
 
    position: absolute;
 
    right: 5px;
 
    top: 5px;
 
    width: 16px;
 
}
 
div#legend_data {
 
    padding-left:10px;
 
}
 
div#legend_container table {
 
    border: none !important;
 
}
 
div#legend_container table, div#legend_choices table {
 
    width: auto !important;
 
}
 

	
 
table#permissions_manage {
 
    width: 0 !important;
 
}
 

	
 
table#permissions_manage span.private_repo_msg {
 
    font-size: 0.8em;
 
    opacity: 0.6px;
 
}
 

	
 
table#permissions_manage td.private_repo_msg {
 
    font-size: 0.8em;
 
}
 

	
 
table#permissions_manage tr#add_perm_input td {
 
    vertical-align: middle;
 
}
 

	
 
div.gravatar {
 
    background-color: #FFF;
 
    float: left;
 
    margin-right: 0.7em;
 
    padding: 1px 1px 1px 1px;
 
    line-height:0;
 
    -webkit-border-radius: 3px;
 
    -khtml-border-radius: 3px;
 
    -moz-border-radius: 3px;
 
    border-radius: 3px;
 
}
 

	
 
div.gravatar img {
 
    -webkit-border-radius: 2px;
 
    -khtml-border-radius: 2px;
 
    -moz-border-radius: 2px;
 
    border-radius: 2px;
 
}
 

	
 
#header, #content, #footer {
 
    min-width: 978px;
 
}
 

	
 
#content {
 
    clear: both;
 
    overflow: hidden;
 
    /*overflow: hidden;*/
 
    padding: 10px 10px 14px 10px;
 
}
 

	
 
#content.hover {
 
    padding: 55px 10px 14px 10px !important;
 
}
 

	
 
#content div.box div.title div.search {
 
    border-left: 1px solid #316293;
 
}
 

	
 
#content div.box div.title div.search div.input input {
 
    border: 1px solid #316293;
 
}
 

	
 
.ui-btn {
 
    color: #515151;
 
    background-color: #DADADA;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#F4F4F4),to(#DADADA) );
 
    background-image: -moz-linear-gradient(top, #F4F4F4, #DADADA);
 
    background-image: -ms-linear-gradient(top, #F4F4F4, #DADADA);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) );
 
    background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) );
 
    background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) );
 
    background-image: linear-gradient(top, #F4F4F4, #DADADA);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0);
 

	
 
    border-top: 1px solid #DDD;
 
    border-left: 1px solid #c6c6c6;
 
    border-right: 1px solid #DDD;
 
    border-bottom: 1px solid #c6c6c6;
 
    color: #515151;
 
    outline: none;
 
    margin: 0px 3px 3px 0px;
 
    -webkit-border-radius: 4px 4px 4px 4px !important;
 
    -khtml-border-radius: 4px 4px 4px 4px !important;
 
    -moz-border-radius: 4px 4px 4px 4px !important;
 
    border-radius: 4px 4px 4px 4px !important;
 
    cursor: pointer !important;
 
    padding: 3px 3px 3px 3px;
 
    background-position: 0 -15px;
 

	
 
}
 

	
 
.ui-btn.disabled {
 
    color: #999;
 
}
 

	
 
.ui-btn.xsmall {
 
    padding: 1px 2px 1px 1px;
 
}
 

	
 
.ui-btn.large {
 
    padding: 6px 12px;
 
}
 

	
 
.ui-btn.clone {
 
    padding: 5px 2px 6px 1px;
 
    margin: 0px 0px 3px -4px;
 
    -webkit-border-radius: 0px 4px 4px 0px !important;
 
    -khtml-border-radius: 0px 4px 4px 0px !important;
 
    -moz-border-radius: 0px 4px 4px 0px !important;
 
    border-radius: 0px 4px 4px 0px !important;
 
    width: 100px;
 
    text-align: center;
 
    display: inline-block;
 
    position: relative;
 
    top: -2px;
 
}
 
.ui-btn:focus {
 
    outline: none;
 
}
 
.ui-btn:hover {
 
    background-position: 0 -15px;
 
    text-decoration: none;
 
    color: #515151;
 
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 3px #FFFFFF !important;
 
}
 

	
 
.ui-btn.disabled:hover {
 
    background-position:none;
 
    color: #999;
 
    text-decoration: none;
 
    box-shadow: none !important;
 
}
 

	
 
.ui-btn.red {
 
    color:#fff;
 
    background-color: #c43c35;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
 
    background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));
 
    background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
 
    background-image: linear-gradient(top, #ee5f5b, #c43c35);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
 
    border-color: #c43c35 #c43c35 #882a25;
 
    border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
 
}
 

	
 

	
 
.ui-btn.blue {
 
    color:#fff;
 
    background-color: #339bb9;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));
 
    background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));
 
    background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
 
    background-image: linear-gradient(top, #5bc0de, #339bb9);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
 
    border-color: #339bb9 #339bb9 #22697d;
 
    border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
 
}
 

	
 
.ui-btn.green {
 
    background-color: #57a957;
 
    background-repeat: repeat-x;
 
    background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));
 
    background-image: -moz-linear-gradient(top, #62c462, #57a957);
 
    background-image: -ms-linear-gradient(top, #62c462, #57a957);
 
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));
 
    background-image: -webkit-linear-gradient(top, #62c462, #57a957);
 
    background-image: -o-linear-gradient(top, #62c462, #57a957);
 
    background-image: linear-gradient(top, #62c462, #57a957);
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
 
    border-color: #57a957 #57a957 #3d773d;
 
    border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
 
}
 

	
 
.ui-btn.blue.hidden {
 
    display: none;
 
}
 

	
 
.ui-btn.active {
 
    font-weight: bold;
 
}
 

	
 
ins, div.options a:hover {
 
    text-decoration: none;
 
}
 

	
 
img,
 
#header #header-inner #quick li a:hover span.normal,
 
#header #header-inner #quick li ul li.last,
 
#content div.box div.form div.fields div.field div.textarea table td table td a,
 
#clone_url,
 
#clone_url_id
 
{
 
    border: none;
 
}
 

	
 
img.icon, .right .merge img {
 
    vertical-align: bottom;
 
}
 

	
 
#header ul#logged-user, #content div.box div.title ul.links,
 
#content div.box div.message div.dismiss,
 
#content div.box div.traffic div.legend ul {
 
    float: right;
 
    margin: 0;
 
    padding: 0;
 
}
 

	
 
#header #header-inner #home, #header #header-inner #logo,
 
#content div.box ul.left, #content div.box ol.left,
 
#content div.box div.pagination-left, div#commit_history,
 
div#legend_data, div#legend_container, div#legend_choices {
 
    float: left;
 
}
 

	
 
#header #header-inner #quick li #quick_login,
 
#header #header-inner #quick li:hover ul ul,
 
#header #header-inner #quick li:hover ul ul ul,
 
#header #header-inner #quick li:hover ul ul ul ul,
 
#content #left #menu ul.closed, #content #left #menu li ul.collapsed, .yui-tt-shadow {
 
    display: none;
 
}
 

	
 
#header #header-inner #quick li:hover #quick_login,
 
#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 {
 
    display: block;
 
}
 

	
 
#content div.graph {
 
    padding: 0 10px 10px;
 
}
 

	
 
#content div.box div.title ul.links li a:hover, #content div.box div.title ul.links li.ui-tabs-selected a {
 
    color: #bfe3ff;
 
}
 

	
 
#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 {
 
    margin: 10px 24px 10px 44px;
 
}
 

	
 
#content div.box div.form, #content div.box div.table, #content div.box div.traffic {
 
    clear: both;
 
    overflow: hidden;
 
    margin: 0;
 
    padding: 0 20px 10px;
 
}
 

	
 
#content div.box div.form div.fields, #login div.form, #login div.form div.fields, #register div.form, #register div.form div.fields {
 
    clear: both;
 
    overflow: hidden;
 
    margin: 0;
 
    padding: 0;
 
}
 

	
 
#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 {
 
    height: 1%;
 
    display: block;
 
    color: #363636;
 
    margin: 0;
 
    padding: 2px 0 0;
 
}
 

	
 
#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 {
 
    background: #FBE3E4;
 
    border-top: 1px solid #e1b2b3;
 
    border-left: 1px solid #e1b2b3;
 
    border-right: 1px solid #FBC2C4;
 
    border-bottom: 1px solid #FBC2C4;
 
}
 

	
 
#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 {
 
    background: #E6EFC2;
 
    border-top: 1px solid #cebb98;
 
    border-left: 1px solid #cebb98;
 
    border-right: 1px solid #c6d880;
 
    border-bottom: 1px solid #c6d880;
 
}
 

	
 
#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 {
 
    margin: 0;
 
}
 

	
 
#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 {
 
    margin: 0 0 0 0px !important;
 
    padding: 0;
 
}
 

	
 
#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 {
 
    margin: 0 0 0 200px;
 
    padding: 0;
 
}
 

	
 
#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 {
 
    color: #000;
 
    text-decoration: none;
 
}
 

	
 
#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus, #content div.box div.action a.ui-selectmenu-focus {
 
    border: 1px solid #666;
 
}
 

	
 
#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 {
 
    clear: both;
 
    overflow: hidden;
 
    margin: 0;
 
    padding: 8px 0 2px;
 
}
 

	
 
#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 {
 
    float: left;
 
    margin: 0;
 
}
 

	
 
#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 {
 
    height: 1%;
 
    display: block;
 
    float: left;
 
    margin: 2px 0 0 4px;
 
}
 

	
 
div.form div.fields div.field div.button input,
 
#content div.box div.form div.fields div.buttons input
 
div.form div.fields div.buttons input,
 
#content div.box div.action div.button input {
 
    /*color: #000;*/
 
    font-size: 11px;
 
    font-weight: 700;
 
    margin: 0;
 
}
 

	
 
input.ui-button {
 
    background: #e5e3e3 url("../images/button.png") repeat-x;
 
    border-top: 1px solid #DDD;
 
    border-left: 1px solid #c6c6c6;
 
    border-right: 1px solid #DDD;
 
    border-bottom: 1px solid #c6c6c6;
 
    color: #515151 !important;
 
    outline: none;
 
    margin: 0;
 
    padding: 6px 12px;
 
    -webkit-border-radius: 4px 4px 4px 4px;
 
    -khtml-border-radius: 4px 4px 4px 4px;
 
    -moz-border-radius: 4px 4px 4px 4px;
 
    border-radius: 4px 4px 4px 4px;
 
    box-shadow: 0 1px 0 #ececec;
 
    cursor: pointer;
 
}
 

	
 
input.ui-button:hover {
 
    background: #b4b4b4 url("../images/button_selected.png") repeat-x;
 
    border-top: 1px solid #ccc;
 
    border-left: 1px solid #bebebe;
 
    border-right: 1px solid #b1b1b1;
 
    border-bottom: 1px solid #afafaf;
 
}
 

	
 
div.form div.fields div.field div.highlight, #content div.box div.form div.fields div.buttons div.highlight {
 
    display: inline;
 
}
 

	
 
#content div.box div.form div.fields div.buttons, div.form div.fields div.buttons {
 
    margin: 10px 0 0 200px;
 
    padding: 0;
 
}
 

	
 
#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 {
 
    margin: 10px 0 0;
 
}
 

	
 
#content div.box table td.user, #content div.box table td.address {
 
    width: 10%;
 
    text-align: center;
 
}
 

	
 
#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 {
 
    text-align: right;
 
    margin: 6px 0 0;
 
    padding: 0;
 
}
 

	
 
#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 {
 
    background: #b4b4b4 url("../images/button_selected.png") repeat-x;
 
    border-top: 1px solid #ccc;
 
    border-left: 1px solid #bebebe;
 
    border-right: 1px solid #b1b1b1;
 
    border-bottom: 1px solid #afafaf;
 
    color: #515151;
 
    margin: 0;
 
    padding: 6px 12px;
 
}
 

	
 
#content div.box div.pagination div.results, #content div.box div.pagination-wh div.results {
 
    text-align: left;
 
    float: left;
 
    margin: 0;
 
    padding: 0;
 
}
 

	
 
#content div.box div.pagination div.results span, #content div.box div.pagination-wh div.results span {
 
    height: 1%;
 
    display: block;
 
    float: left;
 
    background: #ebebeb url("../images/pager.png") repeat-x;
 
    border-top: 1px solid #dedede;
 
    border-left: 1px solid #cfcfcf;
 
    border-right: 1px solid #c4c4c4;
 
    border-bottom: 1px solid #c4c4c4;
 
    color: #4A4A4A;
 
    font-weight: 700;
 
    margin: 0;
 
    padding: 6px 8px;
 
}
 

	
 
#content div.box div.pagination ul.pager li.disabled, #content div.box div.pagination-wh a.disabled {
 
    color: #B4B4B4;
 
    padding: 6px;
 
}
 

	
 
#login, #register {
 
    width: 520px;
 
    margin: 10% auto 0;
 
    padding: 0;
 
}
rhodecode/public/js/rhodecode.js
Show inline comments
 
@@ -128,835 +128,836 @@ ColorGenerator.prototype = {
 
    		return this.cacheColorMap[key];
 
    	}
 
    },
 
    _hsvToRgb:function(h,s,v){
 
        if (s == 0.0)
 
            return [v, v, v];
 
        i = parseInt(h * 6.0)
 
        f = (h * 6.0) - i
 
        p = v * (1.0 - s)
 
        q = v * (1.0 - s * f)
 
        t = v * (1.0 - s * (1.0 - f))
 
        i = i % 6
 
        if (i == 0) 
 
            return [v, t, p]
 
        if (i == 1) 
 
            return [q, v, p]
 
        if (i == 2) 
 
            return [p, v, t]
 
        if (i == 3)
 
            return [p, q, v]
 
        if (i == 4) 
 
            return [t, p, v]
 
        if (i == 5)
 
            return [v, p, q]            	
 
    },
 
    generateColor:function(){
 
        this.CURRENT_RATIO = this.CURRENT_RATIO+this.GOLDEN_RATIO;
 
        this.CURRENT_RATIO = this.CURRENT_RATIO %= 1;
 
        HSV_tuple = [this.CURRENT_RATIO, this.HSV_1, this.HSV_2]
 
        RGB_tuple = this._hsvToRgb(HSV_tuple[0],HSV_tuple[1],HSV_tuple[2]);
 
        function toRgb(v){
 
        	return ""+parseInt(v*256)
 
        }
 
        return [toRgb(RGB_tuple[0]),toRgb(RGB_tuple[1]),toRgb(RGB_tuple[2])];
 
        
 
    }
 
}
 

	
 
/**
 
 * PyRoutesJS
 
 * 
 
 * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id>
 
 */
 
var pyroutes = (function() {
 
	// access global map defined in special file pyroutes
 
    var matchlist = PROUTES_MAP;
 
    var sprintf = (function() {
 
        function get_type(variable) {
 
            return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
 
        }
 
        function str_repeat(input, multiplier) {
 
            for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
 
            return output.join('');
 
        }
 

	
 
        var str_format = function() {
 
            if (!str_format.cache.hasOwnProperty(arguments[0])) {
 
                str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
 
            }
 
            return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
 
        };
 

	
 
        str_format.format = function(parse_tree, argv) {
 
            var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
 
            for (i = 0; i < tree_length; i++) {
 
                node_type = get_type(parse_tree[i]);
 
                if (node_type === 'string') {
 
                    output.push(parse_tree[i]);
 
                }
 
                else if (node_type === 'array') {
 
                    match = parse_tree[i]; // convenience purposes only
 
                    if (match[2]) { // keyword argument
 
                        arg = argv[cursor];
 
                        for (k = 0; k < match[2].length; k++) {
 
                            if (!arg.hasOwnProperty(match[2][k])) {
 
                                throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
 
                            }
 
                            arg = arg[match[2][k]];
 
                        }
 
                    }
 
                    else if (match[1]) { // positional argument (explicit)
 
                        arg = argv[match[1]];
 
                    }
 
                    else { // positional argument (implicit)
 
                        arg = argv[cursor++];
 
                    }
 

	
 
                    if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
 
                        throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
 
                    }
 
                    switch (match[8]) {
 
                        case 'b': arg = arg.toString(2); break;
 
                        case 'c': arg = String.fromCharCode(arg); break;
 
                        case 'd': arg = parseInt(arg, 10); break;
 
                        case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
 
                        case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
 
                        case 'o': arg = arg.toString(8); break;
 
                        case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
 
                        case 'u': arg = Math.abs(arg); break;
 
                        case 'x': arg = arg.toString(16); break;
 
                        case 'X': arg = arg.toString(16).toUpperCase(); break;
 
                    }
 
                    arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
 
                    pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
 
                    pad_length = match[6] - String(arg).length;
 
                    pad = match[6] ? str_repeat(pad_character, pad_length) : '';
 
                    output.push(match[5] ? arg + pad : pad + arg);
 
                }
 
            }
 
            return output.join('');
 
        };
 

	
 
        str_format.cache = {};
 

	
 
        str_format.parse = function(fmt) {
 
            var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
 
            while (_fmt) {
 
                if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
 
                    parse_tree.push(match[0]);
 
                }
 
                else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
 
                    parse_tree.push('%');
 
                }
 
                else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
 
                    if (match[2]) {
 
                        arg_names |= 1;
 
                        var field_list = [], replacement_field = match[2], field_match = [];
 
                        if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
 
                            field_list.push(field_match[1]);
 
                            while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
 
                                if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
 
                                    field_list.push(field_match[1]);
 
                                }
 
                                else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
 
                                    field_list.push(field_match[1]);
 
                                }
 
                                else {
 
                                    throw('[sprintf] huh?');
 
                                }
 
                            }
 
                        }
 
                        else {
 
                            throw('[sprintf] huh?');
 
                        }
 
                        match[2] = field_list;
 
                    }
 
                    else {
 
                        arg_names |= 2;
 
                    }
 
                    if (arg_names === 3) {
 
                        throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
 
                    }
 
                    parse_tree.push(match);
 
                }
 
                else {
 
                    throw('[sprintf] huh?');
 
                }
 
                _fmt = _fmt.substring(match[0].length);
 
            }
 
            return parse_tree;
 
        };
 

	
 
        return str_format;
 
    })();
 

	
 
    var vsprintf = function(fmt, argv) {
 
        argv.unshift(fmt);
 
        return sprintf.apply(null, argv);
 
    };
 
    return {
 
        'url': function(route_name, params) {
 
            var result = route_name;
 
            if (typeof(params) != 'object'){
 
            	params = {};
 
            }
 
            if (matchlist.hasOwnProperty(route_name)) {
 
                var route = matchlist[route_name];
 
                for(var i=0; i < route[1].length; i++) {
 

	
 
                   if (!params.hasOwnProperty(route[1][i]))
 
                        throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation');
 
                }
 
                result = sprintf(route[0], params);
 
            }
 

	
 
            return result;
 
        },
 
    	'register': function(route_name, route_tmpl, req_params) {
 
    		if (typeof(req_params) != 'object') {
 
    			req_params = [];
 
    		}
 
    		//fix escape
 
    		route_tmpl = unescape(route_tmpl);
 
    		keys = [];
 
    		for (o in req_params){
 
    			keys.push(req_params[o])
 
    		}
 
    		matchlist[route_name] = [
 
    		    route_tmpl,
 
    		    keys
 
    		]
 
    	},
 
    	'_routes': function(){
 
    		return matchlist;
 
    	}
 
    }
 
})();
 

	
 

	
 

	
 
/**
 
 * GLOBAL YUI Shortcuts
 
 */
 
var YUC = YAHOO.util.Connect;
 
var YUD = YAHOO.util.Dom;
 
var YUE = YAHOO.util.Event;
 
var YUQ = YAHOO.util.Selector.query;
 

	
 
// defines if push state is enabled for this browser ?
 
var push_state_enabled = Boolean(
 
		window.history && window.history.pushState && window.history.replaceState
 
		&& !(   /* disable for versions of iOS before version 4.3 (8F190) */
 
				(/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent)
 
				/* disable for the mercury iOS browser, or at least older versions of the webkit engine */
 
				|| (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent)
 
		)
 
);
 

	
 
var _run_callbacks = function(callbacks){
 
	if (callbacks !== undefined){
 
		var _l = callbacks.length;
 
	    for (var i=0;i<_l;i++){
 
	    	var func = callbacks[i];
 
	    	if(typeof(func)=='function'){
 
	            try{
 
	          	    func();
 
	            }catch (err){};            		
 
	    	}
 
	    }
 
	}		
 
}
 

	
 
/**
 
 * Partial Ajax Implementation
 
 * 
 
 * @param url: defines url to make partial request
 
 * @param container: defines id of container to input partial result
 
 * @param s_call: success callback function that takes o as arg
 
 *  o.tId
 
 *  o.status
 
 *  o.statusText
 
 *  o.getResponseHeader[ ]
 
 *  o.getAllResponseHeaders
 
 *  o.responseText
 
 *  o.responseXML
 
 *  o.argument
 
 * @param f_call: failure callback
 
 * @param args arguments 
 
 */
 
function ypjax(url,container,s_call,f_call,args){
 
	var method='GET';
 
	if(args===undefined){
 
		args=null;
 
	}
 
	
 
	// Set special header for partial ajax == HTTP_X_PARTIAL_XHR
 
	YUC.initHeader('X-PARTIAL-XHR',true);
 
	
 
	// wrapper of passed callback
 
	var s_wrapper = (function(o){
 
		return function(o){
 
			YUD.get(container).innerHTML=o.responseText;
 
			YUD.setStyle(container,'opacity','1.0');
 
    		//execute the given original callback
 
    		if (s_call !== undefined){
 
    			s_call(o);
 
    		}
 
		}
 
	})()	
 
	YUD.setStyle(container,'opacity','0.3');
 
	YUC.asyncRequest(method,url,{
 
		success:s_wrapper,
 
		failure:function(o){
 
			console.log(o);
 
			YUD.get(container).innerHTML='<span class="error_red">ERROR: {0}</span>'.format(o.status);
 
			YUD.setStyle(container,'opacity','1.0');
 
		},
 
		cache:false
 
	},args);
 
	
 
};
 

	
 
var ajaxGET = function(url,success) {
 
	// Set special header for ajax == HTTP_X_PARTIAL_XHR
 
	YUC.initHeader('X-PARTIAL-XHR',true);
 

	
 
    var sUrl = url;
 
    var callback = {
 
        success: success,
 
        failure: function (o) {
 
            alert("error");
 
        },
 
    };
 

	
 
    var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
 
    return request;
 
};
 

	
 

	
 

	
 
var ajaxPOST = function(url,postData,success) {
 
	// Set special header for ajax == HTTP_X_PARTIAL_XHR
 
	YUC.initHeader('X-PARTIAL-XHR',true);
 
	
 
	var toQueryString = function(o) {
 
	    if(typeof o !== 'object') {
 
	        return false;
 
	    }
 
	    var _p, _qs = [];
 
	    for(_p in o) {
 
	        _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
 
	    }
 
	    return _qs.join('&');
 
	};
 
	
 
    var sUrl = url;
 
    var callback = {
 
        success: success,
 
        failure: function (o) {
 
            alert("error");
 
        },
 
    };
 
    var postData = toQueryString(postData);
 
    var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
 
    return request;
 
};
 

	
 

	
 
/**
 
 * tooltip activate
 
 */
 
var tooltip_activate = function(){
 
	yt = YAHOO.yuitip.main;
 
	YUE.onDOMReady(yt.init);
 
};
 

	
 
/**
 
 * show more
 
 */
 
var show_more_event = function(){
 
    YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
 
        var el = e.target;
 
        YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
 
        YUD.setStyle(el.parentNode,'display','none');
 
    });
 
};
 

	
 
/**
 
 * show changeset tooltip
 
 */
 
var show_changeset_tooltip = function(){
 
	YUE.on(YUD.getElementsByClassName('lazy-cs'), 'mouseover', function(e){
 
		var target = e.currentTarget;
 
		var rid = YUD.getAttribute(target,'raw_id');
 
		var repo_name = YUD.getAttribute(target,'repo_name');
 
		var ttid = 'tt-'+rid;
 
		var success = function(o){
 
			var json = JSON.parse(o.responseText);
 
			YUD.addClass(target,'tooltip')
 
			YUD.setAttribute(target, 'title',json['message']);
 
			YAHOO.yuitip.main.show_yuitip(e, target);
 
		}
 
		if(rid && !YUD.hasClass(target, 'tooltip')){
 
			YUD.setAttribute(target,'id',ttid);
 
			YUD.setAttribute(target, 'title',_TM['loading...']);
 
			YAHOO.yuitip.main.set_listeners(target);
 
			YAHOO.yuitip.main.show_yuitip(e, target);
 
			var url = pyroutes.url('changeset_info', {"repo_name":repo_name, "revision": rid});
 
			ajaxGET(url, success)
 
		}
 
	});
 
};
 

	
 
var onSuccessFollow = function(target){
 
    var f = YUD.get(target.id);
 
    var f = YUD.get(target);
 
    var f_cnt = YUD.get('current_followers_count');
 

	
 
    if(YUD.hasClass(f, 'follow')){
 
        f.setAttribute('class','following');
 
        f.setAttribute('title',_TM['Stop following this repository']);
 

	
 
        if(f_cnt){
 
            var cnt = Number(f_cnt.innerHTML)+1;
 
            f_cnt.innerHTML = cnt;
 
        }
 
    }
 
    else{
 
        f.setAttribute('class','follow');
 
        f.setAttribute('title',_TM['Start following this repository']);
 
        if(f_cnt){
 
            var cnt = Number(f_cnt.innerHTML)-1;
 
            f_cnt.innerHTML = cnt;
 
        }
 
    }
 
}
 

	
 
var toggleFollowingUser = function(target,fallows_user_id,token,user_id){
 
    args = 'follows_user_id='+fallows_user_id;
 
    args+= '&amp;auth_token='+token;
 
    if(user_id != undefined){
 
        args+="&amp;user_id="+user_id;
 
    }
 
    YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
 
        success:function(o){
 
        	onSuccessFollow(target);
 
        }
 
    },args);
 
    return false;
 
}
 

	
 
var toggleFollowingRepo = function(target,fallows_repo_id,token,user_id){
 

	
 
    args = 'follows_repo_id='+fallows_repo_id;
 
    args+= '&amp;auth_token='+token;
 
    if(user_id != undefined){
 
        args+="&amp;user_id="+user_id;
 
    }
 
    YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
 
        success:function(o){
 
        	onSuccessFollow(target);
 
        }
 
    },args);
 
    return false;
 
}
 

	
 
var showRepoSize = function(target, repo_name, token){
 
    var args= 'auth_token='+token;
 
    
 
    if(!YUD.hasClass(target, 'loaded')){
 
        YUD.get(target).innerHTML = _TM['loading...'];
 
        var url = pyroutes.url('repo_size', {"repo_name":repo_name});
 
        YUC.asyncRequest('POST',url,{
 
            success:function(o){
 
            	YUD.get(target).innerHTML = JSON.parse(o.responseText);
 
            	YUD.addClass(target, 'loaded');
 
            }
 
        },args);    	
 
    }
 
    return false;	
 
}
 

	
 

	
 
/**
 
 * TOOLTIP IMPL.
 
 */
 
YAHOO.namespace('yuitip');
 
YAHOO.yuitip.main = {
 

	
 
	$:			YAHOO.util.Dom.get,
 

	
 
	bgColor:	'#000',
 
	speed:		0.3,
 
	opacity:	0.9,
 
	offset:		[15,15],
 
	useAnim:	false,
 
	maxWidth:	600,
 
	add_links:	false,
 
	yuitips:    [],
 

	
 
	set_listeners: function(tt){
 
		YUE.on(tt, 'mouseover', yt.show_yuitip,  tt);
 
		YUE.on(tt, 'mousemove', yt.move_yuitip,  tt);
 
		YUE.on(tt, 'mouseout',  yt.close_yuitip, tt);		
 
	},
 

	
 
	init: function(){
 
		yt.tipBox = yt.$('tip-box');
 
		if(!yt.tipBox){
 
			yt.tipBox = document.createElement('div');
 
			document.body.appendChild(yt.tipBox);
 
			yt.tipBox.id = 'tip-box';
 
		}
 

	
 
		YUD.setStyle(yt.tipBox, 'display', 'none');
 
		YUD.setStyle(yt.tipBox, 'position', 'absolute');
 
		if(yt.maxWidth !== null){
 
			YUD.setStyle(yt.tipBox, 'max-width', yt.maxWidth+'px');
 
		}
 

	
 
		var yuitips = YUD.getElementsByClassName('tooltip');
 

	
 
		if(yt.add_links === true){
 
			var links = document.getElementsByTagName('a');
 
			var linkLen = links.length;
 
			for(i=0;i<linkLen;i++){
 
				yuitips.push(links[i]);
 
			}
 
		}
 

	
 
		var yuiLen = yuitips.length;
 

	
 
		for(i=0;i<yuiLen;i++){
 
			yt.set_listeners(yuitips[i]);
 
		}
 
	},
 

	
 
	show_yuitip: function(e, el){
 
		YUE.stopEvent(e);
 
		if(el.tagName.toLowerCase() === 'img'){
 
			yt.tipText = el.alt ? el.alt : '';
 
		} else {
 
			yt.tipText = el.title ? el.title : '';
 
		}
 

	
 
		if(yt.tipText !== ''){
 
			// save org title
 
			YUD.setAttribute(el, 'tt_title', yt.tipText);
 
			// reset title to not show org tooltips
 
			YUD.setAttribute(el, 'title', '');
 

	
 
			yt.tipBox.innerHTML = yt.tipText;
 
			YUD.setStyle(yt.tipBox, 'display', 'block');
 
			if(yt.useAnim === true){
 
				YUD.setStyle(yt.tipBox, 'opacity', '0');
 
				var newAnim = new YAHOO.util.Anim(yt.tipBox,
 
					{
 
						opacity: { to: yt.opacity }
 
					}, yt.speed, YAHOO.util.Easing.easeOut
 
				);
 
				newAnim.animate();
 
			}
 
		}
 
	},
 

	
 
	move_yuitip: function(e, el){
 
		YUE.stopEvent(e);
 
		var movePos = YUE.getXY(e);
 
		YUD.setStyle(yt.tipBox, 'top', (movePos[1] + yt.offset[1]) + 'px');
 
		YUD.setStyle(yt.tipBox, 'left', (movePos[0] + yt.offset[0]) + 'px');
 
	},
 

	
 
	close_yuitip: function(e, el){
 
		YUE.stopEvent(e);
 
	
 
		if(yt.useAnim === true){
 
			var newAnim = new YAHOO.util.Anim(yt.tipBox,
 
				{
 
					opacity: { to: 0 }
 
				}, yt.speed, YAHOO.util.Easing.easeOut
 
			);
 
			newAnim.animate();
 
		} else {
 
			YUD.setStyle(yt.tipBox, 'display', 'none');
 
		}
 
		YUD.setAttribute(el,'title', YUD.getAttribute(el, 'tt_title'));
 
	}
 
}
 

	
 
/**
 
 * Quick filter widget
 
 * 
 
 * @param target: filter input target
 
 * @param nodes: list of nodes in html we want to filter.
 
 * @param display_element function that takes current node from nodes and
 
 *    does hide or show based on the node
 
 * 
 
 */
 
var q_filter = function(target,nodes,display_element){
 
	
 
	var nodes = nodes;
 
	var q_filter_field = YUD.get(target);
 
	var F = YAHOO.namespace(target);
 

	
 
	YUE.on(q_filter_field,'click',function(){
 
	   q_filter_field.value = '';
 
	});
 

	
 
	YUE.on(q_filter_field,'keyup',function(e){
 
	    clearTimeout(F.filterTimeout); 
 
	    F.filterTimeout = setTimeout(F.updateFilter,600); 
 
	});
 

	
 
	F.filterTimeout = null;
 

	
 
	var show_node = function(node){
 
		YUD.setStyle(node,'display','')
 
	}
 
	var hide_node = function(node){
 
		YUD.setStyle(node,'display','none');
 
	}
 
	
 
	F.updateFilter  = function() { 
 
	   // Reset timeout 
 
	   F.filterTimeout = null;
 
	   
 
	   var obsolete = [];
 
	   
 
	   var req = q_filter_field.value.toLowerCase();
 
	   
 
	   var l = nodes.length;
 
	   var i;
 
	   var showing = 0;
 
	   
 
       for (i=0;i<l;i++ ){
 
    	   var n = nodes[i];
 
    	   var target_element = display_element(n)
 
    	   if(req && n.innerHTML.toLowerCase().indexOf(req) == -1){
 
    		   hide_node(target_element);
 
    	   }
 
    	   else{
 
    		   show_node(target_element);
 
    		   showing+=1;
 
    	   }
 
       }	  	   
 

	
 
	   // if repo_count is set update the number
 
	   var cnt = YUD.get('repo_count');
 
	   if(cnt){
 
		   YUD.get('repo_count').innerHTML = showing;
 
	   }       
 
       
 
	}	
 
};
 

	
 
var tableTr = function(cls, body){
 
	var _el = document.createElement('div');
 
	var cont = new YAHOO.util.Element(body);
 
	var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
 
	var id = 'comment-tr-{0}'.format(comment_id);
 
	var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
 
	              '<td class="lineno-inline new-inline"></td>'+
 
    			  '<td class="lineno-inline old-inline"></td>'+ 
 
                  '<td>{2}</td>'+
 
                 '</tr></tbody></table>').format(id, cls, body);
 
	_el.innerHTML = _html;
 
	return _el.children[0].children[0].children[0];
 
};
 

	
 
/** comments **/
 
var removeInlineForm = function(form) {
 
	form.parentNode.removeChild(form);
 
};
 

	
 
var createInlineForm = function(parent_tr, f_path, line) {
 
	var tmpl = YUD.get('comment-inline-form-template').innerHTML;
 
	tmpl = tmpl.format(f_path, line);
 
	var form = tableTr('comment-form-inline',tmpl)
 

	
 
	// create event for hide button
 
	form = new YAHOO.util.Element(form);
 
	var form_hide_button = new YAHOO.util.Element(YUD.getElementsByClassName('hide-inline-form',null,form)[0]);
 
	form_hide_button.on('click', function(e) {
 
		var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
 
		if(YUD.hasClass(newtr.nextElementSibling,'inline-comments-button')){
 
			YUD.setStyle(newtr.nextElementSibling,'display','');
 
		}
 
		removeInlineForm(newtr);
 
		YUD.removeClass(parent_tr, 'form-open');
 
		YUD.removeClass(parent_tr, 'hl-comment');
 
		
 
	});
 
	
 
	return form
 
};
 

	
 
/**
 
 * Inject inline comment for on given TR this tr should be always an .line
 
 * tr containing the line. Code will detect comment, and always put the comment
 
 * block at the very bottom
 
 */
 
var injectInlineForm = function(tr){
 
	  if(!YUD.hasClass(tr, 'line')){
 
		  return
 
	  }
 
	  var submit_url = AJAX_COMMENT_URL;
 
	  var _td = YUD.getElementsByClassName('code',null,tr)[0];
 
	  if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(_td,'no-comment')){
 
		  return
 
	  }	
 
	  YUD.addClass(tr,'form-open');
 
	  YUD.addClass(tr,'hl-comment');
 
	  var node = YUD.getElementsByClassName('full_f_path',null,tr.parentNode.parentNode.parentNode)[0];
 
	  var f_path = YUD.getAttribute(node,'path');
 
	  var lineno = getLineNo(tr);
 
	  var form = createInlineForm(tr, f_path, lineno, submit_url);
 
	  
 
	  var parent = tr;
 
	  while (1){
 
		  var n = parent.nextElementSibling;
 
		  // next element are comments !
 
		  if(YUD.hasClass(n,'inline-comments')){
 
			  parent = n;
 
		  }
 
		  else{
 
			  break;
 
		  }
 
	  }	  
 
	  YUD.insertAfter(form,parent);
 
	  var f = YUD.get(form);
 
	  var overlay = YUD.getElementsByClassName('overlay',null,f)[0];
 
	  var _form = YUD.getElementsByClassName('inline-form',null,f)[0];
 
	  
 
	  YUE.on(YUD.get(_form), 'submit',function(e){
 
		  YUE.preventDefault(e);
 
		  
 
		  //ajax submit
 
		  var text = YUD.get('text_'+lineno).value;
 
		  var postData = {
 
	            'text':text,
 
	            'f_path':f_path,
 
	            'line':lineno
 
		  };
 
		  
 
		  if(lineno === undefined){
 
			  alert('missing line !');
 
			  return
 
		  }
 
		  if(f_path === undefined){
 
			  alert('missing file path !');
 
			  return
 
		  }
 
		  
 
		  if(text == ""){
 
			  return
 
		  }
 
		  
 
		  var success = function(o){
 
			  YUD.removeClass(tr, 'form-open');
 
			  removeInlineForm(f);			  
 
			  var json_data = JSON.parse(o.responseText);
 
	          renderInlineComment(json_data);
 
		  };
 

	
 
		  if (YUD.hasClass(overlay,'overlay')){
 
			  var w = _form.offsetWidth;
 
			  var h = _form.offsetHeight;
 
			  YUD.setStyle(overlay,'width',w+'px');
 
			  YUD.setStyle(overlay,'height',h+'px');
 
		  }		  
 
		  YUD.addClass(overlay, 'submitting');		  
 
		  
 
		  ajaxPOST(submit_url, postData, success);
 
	  });
 
	  
 
	  setTimeout(function(){
 
		  // callbacks
 
		  tooltip_activate();
 
		  MentionsAutoComplete('text_'+lineno, 'mentions_container_'+lineno, 
 
	                         _USERS_AC_DATA, _GROUPS_AC_DATA);
 
		  var _e = YUD.get('text_'+lineno);
 
		  if(_e){
 
			  _e.focus();
 
		  }
 
	  },10)
 
};
 

	
 
var deleteComment = function(comment_id){
 
	var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__',comment_id);
 
    var postData = {'_method':'delete'};
 
    var success = function(o){
 
        var n = YUD.get('comment-tr-'+comment_id);
 
        var root = prevElementSibling(prevElementSibling(n));
 
        n.parentNode.removeChild(n);
 

	
 
        // scann nodes, and attach add button to last one
 
        placeAddButton(root);
 
    }
 
    ajaxPOST(url,postData,success);
 
}
 

	
 
var createInlineAddButton = function(tr){
 

	
 
	var label = TRANSLATION_MAP['add another comment'];
 
	
 
	var html_el = document.createElement('div');
 
	YUD.addClass(html_el, 'add-comment');
 
	html_el.innerHTML = '<span class="ui-btn">{0}</span>'.format(label);
 
	
 
	var add = new YAHOO.util.Element(html_el);
 
	add.on('click', function(e) {
 
		injectInlineForm(tr);
 
	});
 
	return add;
 
};
 

	
 
var getLineNo = function(tr) {
 
	var line;
 
	var o = tr.children[0].id.split('_');
 
	var n = tr.children[1].id.split('_');
 

	
 
	if (n.length >= 2) {
 
		line = n[n.length-1];
 
	} else if (o.length >= 2) {
 
		line = o[o.length-1];
 
	}
 

	
 
	return line
 
};
 

	
 
var placeAddButton = function(target_tr){
 
	if(!target_tr){
 
		return
 
	}
 
	var last_node = target_tr;
 
    //scann	
 
	  while (1){
 
		  var n = last_node.nextElementSibling;
 
		  // next element are comments !
 
		  if(YUD.hasClass(n,'inline-comments')){
 
			  last_node = n;
 
			  //also remove the comment button from previous
 
			  var comment_add_buttons = YUD.getElementsByClassName('add-comment',null,last_node);
 
			  for(var i=0;i<comment_add_buttons.length;i++){
 
				  var b = comment_add_buttons[i];
 
				  b.parentNode.removeChild(b);
 
			  }
 
		  }
 
		  else{
 
			  break;
 
		  }
 
	  }
 
	  
 
    var add = createInlineAddButton(target_tr);
 
    // get the comment div
 
    var comment_block = YUD.getElementsByClassName('comment',null,last_node)[0];
 
    // attach add button
 
    YUD.insertAfter(add,comment_block);	
 
}
 

	
 
/**
 
 * Places the inline comment into the changeset block in proper line position
 
 */
 
var placeInline = function(target_container,lineno,html){
 
	  var lineid = "{0}_{1}".format(target_container,lineno);
 
	  var target_line = YUD.get(lineid);
 
	  var comment = new YAHOO.util.Element(tableTr('inline-comments',html))
rhodecode/templates/admin/repos/repo_edit.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Edit repository')} ${c.repo_info.repo_name} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    ${_('edit')}
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('options')}
 
</%def>
 

	
 
<%def name="main()">
 
 ${self.context_bar('options')}
 
<div class="box box-left">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
 
    <div class="form">
 
        <!-- fields -->
 
        <div class="fields">
 
            <div class="field">
 
                <div class="label">
 
                    <label for="repo_name">${_('Name')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('repo_name',class_="medium")}
 
                </div>
 
           </div>
 
           <div class="field">
 
               <div class="label">
 
                   <label for="clone_uri">${_('Clone uri')}:</label>
 
               </div>
 
               <div class="input">
 
                   ${h.text('clone_uri',class_="medium")}
 
                 <span class="help-block">${_('Optional http[s] url from which repository should be cloned.')}</span>
 
               </div>
 
            </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="repo_group">${_('Repository group')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.select('repo_group','',c.repo_groups,class_="medium")}
 
                    <span class="help-block">${_('Optional select a group to put this repository into.')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="repo_type">${_('Type')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.select('repo_type','hg',c.backends,class_="medium")}
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="repo_landing_rev">${_('Landing revision')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.select('repo_landing_rev','',c.landing_revs,class_="medium")}
 
                    <span class="help-block">${_('Default revision for files page, downloads, whoosh and readme')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label label-textarea">
 
                    <label for="repo_description">${_('Description')}:</label>
 
                </div>
 
                <div class="textarea text-area editor">
 
                    ${h.textarea('repo_description')}
 
                    <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
 
                </div>
 
            </div>
 

	
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="repo_private">${_('Private repository')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('repo_private',value="True")}
 
                    <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="repo_enable_statistics">${_('Enable statistics')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('repo_enable_statistics',value="True")}
 
                    <span class="help-block">${_('Enable statistics window on summary page.')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="repo_enable_downloads">${_('Enable downloads')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('repo_enable_downloads',value="True")}
 
                    <span class="help-block">${_('Enable download menu on summary page.')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="repo_enable_locking">${_('Enable locking')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('repo_enable_locking',value="True")}
 
                    <span class="help-block">${_('Enable lock-by-pulling on repository.')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="user">${_('Owner')}:</label>
 
                </div>
 
                <div class="input input-medium ac">
 
                    <div class="perm_ac">
 
                       ${h.text('user',class_='yui-ac-input')}
 
                       <span class="help-block">${_('Change owner of this repository.')}</span>
 
                       <div id="owner_container"></div>
 
                    </div>
 
                </div>
 
             </div>
 
            %if c.visual.repository_fields:
 
              ## EXTRA FIELDS
 
              %for field in c.repo_fields:
 
                <div class="field">
 
                    <div class="label">
 
                        <label for="${field.field_key_prefixed}">${field.field_label} (${field.field_key}):</label>
 
                    </div>
 
                    <div class="input input-medium">
 
                        ${h.text(field.field_key_prefixed, field.field_value, class_='medium')}
 
                        %if field.field_desc:
 
                          <span class="help-block">${field.field_desc}</span>
 
                        %endif
 
                    </div>
 
                 </div>
 
              %endfor
 
            %endif
 
            <div class="field">
 
                <div class="label">
 
                    <label for="input">${_('Permissions')}:</label>
 
                </div>
 
                <div class="input">
 
                    <%include file="repo_edit_perms.html"/>
 
                </div>
 

	
 
                <div class="buttons">
 
                  ${h.submit('save',_('Save'),class_="ui-btn large")}
 
                  ${h.reset('reset',_('Reset'),class_="ui-btn large")}
 
                </div>
 
            </div>
 
    </div>
 
    </div>
 
    ${h.end_form()}
 
</div>
 

	
 
<div class="box box-right">
 
    <div class="title">
 
        <h5>${_('Administration')}</h5>
 
    </div>
 

	
 
        <h3>${_('Statistics')}</h3>
 
        ${h.form(url('repo_stats', repo_name=c.repo_info.repo_name),method='delete')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.submit('reset_stats_%s' % c.repo_info.repo_name,_('Reset current statistics'),class_="ui-btn",onclick="return confirm('"+_('Confirm to remove current statistics')+"');")}
 
               <div class="field" style="border:none;color:#888">
 
               <ul>
 
                    <li>${_('Fetched to rev')}: ${c.stats_revision}/${c.repo_last_rev}</li>
 
                    <li>${_('Stats gathered')}: ${c.stats_percentage}%</li>
 
               </ul>
 
               </div>
 
           </div>
 
        </div>
 
        ${h.end_form()}
 

	
 
        %if c.repo_info.clone_uri:
 
        <h3>${_('Remote')}</h3>
 
        ${h.form(url('repo_pull', repo_name=c.repo_info.repo_name),method='put')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.submit('remote_pull_%s' % c.repo_info.repo_name,_('Pull changes from remote location'),class_="ui-btn",onclick="return confirm('"+_('Confirm to pull changes from remote side')+"');")}
 
               <div class="field" style="border:none">
 
               <ul>
 
                    <li><a href="${c.repo_info.clone_uri}">${c.repo_info.clone_uri}</a></li>
 
               </ul>
 
               </div>
 
           </div>
 
        </div>
 
        ${h.end_form()}
 
        %endif
 

	
 
        <h3>${_('Cache')}</h3>
 
        ${h.form(url('repo_cache', repo_name=c.repo_info.repo_name),method='delete')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.submit('reset_cache_%s' % c.repo_info.repo_name,_('Invalidate repository cache'),class_="ui-btn",onclick="return confirm('"+_('Confirm to invalidate repository cache')+"');")}
 
              <div class="field" style="border:none;color:#888">
 
              <ul>
 
                  <li>${_('Manually invalidate cache for this repository. On first access repository will be cached again')}
 
                  </li>
 
              </ul>
 
              </div>
 
              <div class="field" style="border:none;">
 
                ${_('List of cached values')}
 
                   <table>
 
                   <tr>
 
                    <th>${_('Prefix')}</th>
 
                    <th>${_('Key')}</th>
 
                    <th>${_('Active')}</th>
 
                    </tr>
 
                  %for cache in c.repo_info.cache_keys:
 
                      <tr>
 
                        <td>${cache.prefix or '-'}</td>
 
                        <td>${cache.cache_key}</td>
 
                        <td>${h.bool2icon(cache.cache_active)}</td>
 
                      </tr>
 
                  %endfor
 
                  </table>
 
              </div>
 
           </div>
 
        </div>
 
        ${h.end_form()}
 

	
 
        <h3>${_('Public journal')}</h3>
 
        ${h.form(url('repo_public_journal', repo_name=c.repo_info.repo_name),method='put')}
 
        <div class="form">
 
          ${h.hidden('auth_token',str(h.get_token()))}
 
          <div class="field">
 
          %if c.in_public_journal:
 
            ${h.submit('set_public_%s' % c.repo_info.repo_name,_('Remove from public journal'),class_="ui-btn")}
 
          %else:
 
            ${h.submit('set_public_%s' % c.repo_info.repo_name,_('Add to public journal'),class_="ui-btn")}
 
          %endif
 
          </div>
 
         <div class="field" style="border:none;color:#888">
 
         <ul>
 
              <li>${_('All actions made on this repository will be accessible to everyone in public journal')}
 
              </li>
 
         </ul>
 
         </div>
 
        </div>
 
        ${h.end_form()}
 

	
 
        <h3>${_('Locking')}</h3>
 
        ${h.form(url('repo_locking', repo_name=c.repo_info.repo_name),method='put')}
 
        <div class="form">
 
           <div class="fields">
 
              %if c.repo_info.locked[0]:
 
               ${h.submit('set_unlock' ,_('Unlock locked repo'),class_="ui-btn",onclick="return confirm('"+_('Confirm to unlock repository')+"');")}
 
               ${'Locked by %s on %s' % (h.person_by_id(c.repo_info.locked[0]),h.fmt_date(h.time_to_datetime(c.repo_info.locked[1])))}
 
              %else:
 
                ${h.submit('set_lock',_('lock repo'),class_="ui-btn",onclick="return confirm('"+_('Confirm to lock repository')+"');")}
 
                ${_('Repository is not locked')}
 
              %endif
 
           </div>
 
           <div class="field" style="border:none;color:#888">
 
           <ul>
 
                <li>${_('Force locking on repository. Works only when anonymous access is disabled')}
 
                </li>
 
           </ul>
 
           </div>
 
        </div>
 
        ${h.end_form()}
 

	
 
        <h3>${_('Set as fork of')}</h3>
 
        ${h.form(url('repo_as_fork', repo_name=c.repo_info.repo_name),method='put')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.select('id_fork_of','',c.repos_list,class_="medium")}
 
               ${h.submit('set_as_fork_%s' % c.repo_info.repo_name,_('set'),class_="ui-btn",)}
 
           </div>
 
               <div class="field" style="border:none;color:#888">
 
               <ul>
 
                    <li>${_('''Manually set this repository as a fork of another from the list''')}</li>
 
               </ul>
 
               </div>
 
        </div>
 
        ${h.end_form()}
 

	
 
        <h3>${_('Delete')}</h3>
 
        ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='delete')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.submit('remove_%s' % c.repo_info.repo_name,_('Remove this repository'),class_="ui-btn red",onclick="return confirm('"+_('Confirm to delete this repository')+"');")}
 
              %if c.repo_info.forks.count():
 
                    - ${ungettext('this repository has %s fork', 'this repository has %s forks', c.repo_info.forks.count()) % c.repo_info.forks.count()}
 
                    <input type="radio" name="forks" value="detach_forks" checked="checked"/> <label for="forks">${_('Detach forks')}</label>
 
                    <input type="radio" name="forks" value="delete_forks" /> <label for="forks">${_('Delete forks')}</label>
 
              %endif
 
           </div>
 
           <div class="field" style="border:none;color:#888">
 
           <ul>
 
                <li>${_('This repository will be renamed in a special way in order to be unaccesible for RhodeCode and VCS systems. If you need to fully delete it from file system please do it manually')}</li>
 
           </ul>
 
           </div>
 
        </div>
 
        ${h.end_form()}
 
</div>
 

	
 
##TODO: this should be controlled by the VISUAL setting
 
%if c.visual.repository_fields:
 
<div class="box box-left" style="clear:left">
 
    <!-- box / title -->
 
    <div class="title">
 
        <h5>${_('Extra fields')}</h5>
 
    </div>
 

	
 
    <div class="emails_wrap">
 
      <table class="noborder">
 
      %for field in c.repo_fields:
 
        <tr>
 
            <td>${field.field_label} (${field.field_key})</td>
 
            <td>${field.field_type}</td>
 
            <td>
 
              ${h.form(url('delete_repo_fields', repo_name=c.repo_info.repo_name, field_id=field.repo_field_id),method='delete')}
 
                  ${h.submit('remove_%s' % field.repo_field_id, _('delete'), id="remove_field_%s" % field.repo_field_id,
 
                  class_="delete_icon action_button", onclick="return confirm('"+_('Confirm to delete this field: %s') % field.field_key+"');")}
 
              ${h.end_form()}
 
            </td>
 
        </tr>
 
      %endfor
 
      </table>
 
    </div>
 

	
 
    ${h.form(url('create_repo_fields', repo_name=c.repo_info.repo_name),method='put')}
 
    <div class="form">
 
        <!-- fields -->
 
        <div class="fields">
 
             <div class="field">
 
                <div class="label">
 
                    <label for="new_field_key">${_('New field key')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('new_field_key', class_='small')}
 
                </div>
 
             </div>
 
             <div class="field">
 
                <div class="label">
 
                    <label for="new_field_label">${_('New field label')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('new_field_label', class_='small', placeholder=_('Enter short label'))}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="new_field_desc">${_('New field description')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('new_field_desc', class_='small', placeholder=_('Enter description of a field'))}
 
                </div>
 
             </div>
 

	
 
            <div class="buttons">
 
              ${h.submit('save',_('Add'),class_="ui-btn large")}
 
              ${h.reset('reset',_('Reset'),class_="ui-btn large")}
 
            </div>
 
        </div>
 
    </div>
 
    ${h.end_form()}
 
</div>
 
%endif
 
</%def>
rhodecode/templates/base/base.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="root.html"/>
 

	
 
<!-- HEADER -->
 
<div id="header-dd"></div>
 
<div id="header">
 
    <div id="header-inner" class="title">
 
        <div id="logo">
 
            <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
 
        </div>
 
        <!-- MENU -->
 
        ${self.page_nav()}
 
        <!-- END MENU -->
 
        ${self.body()}
 
    </div>
 
</div>
 
<!-- END HEADER -->
 

	
 
<!-- CONTENT -->
 
<div id="content">
 
    <div class="flash_msg">
 
        <% messages = h.flash.pop_messages() %>
 
        % if messages:
 
        <ul id="flash-messages">
 
            % for message in messages:
 
            <li class="${message.category}_msg">${message}</li>
 
            % endfor
 
        </ul>
 
        % endif
 
    </div>
 
    <div id="main">
 
        ${next.main()}
 
    </div>
 
</div>
 
<!-- END CONTENT -->
 

	
 
<!-- FOOTER -->
 
<div id="footer">
 
   <div id="footer-inner" class="title">
 
       <div>
 
           <p class="footer-link">
 
                <a href="${h.url('bugtracker')}">${_('Submit a bug')}</a>
 
           </p>
 
           <p class="footer-link-right">
 
               <a href="${h.url('rhodecode_official')}">RhodeCode${'-%s' % c.rhodecode_instanceid if c.rhodecode_instanceid else ''}</a>
 
               ${c.rhodecode_version} &copy; 2010-${h.datetime.today().year} by Marcin Kuzminski
 
           </p>
 
       </div>
 
   </div>
 
</div>
 
<!-- END FOOTER -->
 

	
 
### MAKO DEFS ###
 
<%def name="page_nav()">
 
    ${self.menu()}
 
</%def>
 

	
 
<%def name="breadcrumbs()">
 
    <div class="breadcrumbs">
 
    ${self.breadcrumbs_links()}
 
    </div>
 
</%def>
 

	
 
<%def name="context_bar(current=None)">
 
   %if c.repo_name:
 
    ${repo_context_bar(current)}
 
   %endif
 
</%def>
 

	
 
<%def name="repo_context_bar(current=None)">
 
  <%
 
      def follow_class():
 
          if c.repository_following:
 
              return h.literal('following')
 
          else:
 
            return h.literal('follow')
 
  %>
 
  <%
 
    def is_current(selected):
 
        if selected == current:
 
            return h.literal('class="current"')
 
    %>
 

	
 
  <!--- CONTEXT BAR -->
 
  <div id="context-bar" class="box">
 
    <div id="context-top">
 
      <div id= "breadcrumbs">
 
        ${h.link_to(_(u'Repositories'),h.url('home'))}
 
        »
 
        ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
      </div>
 
      ## TODO: this check feels wrong, it would be better to have a check for permissions
 
      ## also it feels like a job for the controller
 
      %if c.rhodecode_user.username != 'default':
 
        <ul id="context-actions" class="horizontal-list">
 
          <li>
 
           <button class="${follow_class()}" onclick="javascript:toggleFollowingRepo(this,${c.rhodecode_db_repo.repo_id},'${str(h.get_token())}');">
 
            <!--span class="icon show-follow follow"></span>
 
            <span class="icon show-following following"></span-->
 
            <span class="show-follow">${_('Follow')}</span>
 
            <span class="show-following">${_('Unfollow')}</span>
 
          </button>
 
          </li>
 
          <li><a href="${h.url('repo_fork_home',repo_name=c.repo_name)}" class="fork">${_('Fork')}</a></li>
 
          %if h.is_hg(c.rhodecode_repo):
 
          <li><a href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="pull-request">${_('Pull Request')}</a></li>
 
          %endif
 
        </ul>
 
      %endif
 
    </div>
 
    <div id="context-state">
 
      <button id="revision-changer">
 
        <span class="branch-name">graphics/shader-move</span>
 
        <span class="revision">@73318:8d3d6ee94072</span>
 
      </button>
 
      <ul id="context-pages" class="horizontal-list">
 
        <li ${is_current('summary')}><a href="${h.url('summary_home', repo_name=c.repo_name)}" class="summary">${_('Summary')}</a></li>
 
        <li ${is_current('changelog')}><a href="${h.url('changelog_home', repo_name=c.repo_name)}" class="changelogs">${_('Changelogs')}</a></li>
 
        <li ${is_current('files')}><a href="${h.url('files_home', repo_name=c.repo_name)}" class="files"></span>${_('Files')}</a></li>
 
        <li>
 
          <a href="#" id="branch_tag_switcher_2" class="dropdown switch-to"></span>${_('Switch To')}</a>
 
          <ul id="switch_to_list_2" class="switch_to submenu">
 
            <li><a href="#">${_('loading...')}</a></li>
 
          </ul>
 
        </li>
 
        <li ${is_current('options')}>
 
          <a href="#" class="dropdown options"></span>Options</a>
 
          <ul>
 
             %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
 
               %if h.HasPermissionAll('hg.admin')('access settings on repository'):
 
                   <li>${h.link_to(_('repository settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
 
               %else:
 
                   <li>${h.link_to(_('repository settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
 
               %endif
 
             %endif
 
              %if c.rhodecode_db_repo.fork:
 
               <li>${h.link_to(_('compare fork'),h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default'),class_='compare_request')}</li>
 
              %endif
 
              <li>${h.link_to(_('lightweight changelog'),h.url('shortlog_home',repo_name=c.repo_name),class_='shortlog')}</li>
 
              <li>${h.link_to(_('search'),h.url('search_repo',repo_name=c.repo_name),class_='search')}</li>
 

	
 
              %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
 
                %if c.rhodecode_db_repo.locked[0]:
 
                  <li>${h.link_to(_('unlock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_del')}</li>
 
                %else:
 
                  <li>${h.link_to(_('lock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_add')}</li>
 
                %endif
 
              %endif
 

	
 
              % if h.HasPermissionAll('hg.admin')('access admin main page'):
 
                 <li>
 
                   ${h.link_to(_('admin'),h.url('admin_home'),class_='admin childs')}
 
                    <%def name="admin_menu()">
 
                    <ul class="admin_menu">
 
                        <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li>
 
                        <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
 
                        <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
 
                        <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
 
                        <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
 
                        <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
 
                        <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
 
                        <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li>
 
                        <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
 
                    </ul>
 
                    </%def>
 
                    ## ADMIN MENU
 
                    ${admin_menu()}
 
                 </li>
 
              ## if you're a admin of any groups, show admin menu for it
 
              % elif c.rhodecode_user.groups_admin:
 
                 <li>
 
                   ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
 
                    <%def name="admin_menu_simple()">
 
                    <ul>
 
                        <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
 
                    </ul>
 
                    </%def>
 
                    ## ADMIN MENU
 
                    ${admin_menu_simple()}
 
                 </li>
 
              % endif
 
             </ul>
 
        </li>
 
        <li ${is_current('showpullrequest')}><a href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}" title="${_('Show Pull Requests')}" class="pull-request">1</a></li>
 
      </ul>
 
    </div>
 
  </div>
 
  <script type="text/javascript">
 
      YUE.on('branch_tag_switcher_2','mouseover',function(){
 
         var loaded = YUD.hasClass('branch_tag_switcher_2','loaded');
 
         if(!loaded){
 
             YUD.addClass('branch_tag_switcher_2','loaded');
 
             ypjax("${h.url('branch_tag_switcher',repo_name=c.repo_name)}",'switch_to_list_2',
 
                 function(o){},
 
                 function(o){YUD.removeClass('branch_tag_switcher_2','loaded');}
 
                 ,null);
 
         }
 
         return false;
 
      });
 
  </script>
 
  <!--- END CONTEXT BAR -->
 
</%def>
 

	
 
<%def name="usermenu()">
 
    ## USER MENU
 
    <li>
 
      <a class="menu_link" id="quick_login_link">
 
          <span class="icon" style="padding:5px 5px 0px 5px">
 
             <img src="${h.gravatar_url(c.rhodecode_user.email,20)}" alt="avatar">
 
          </span>
 
          %if c.rhodecode_user.username != 'default':
 
            <span class="menu_link_user">${c.rhodecode_user.username}</span>
 
            %if c.unread_notifications != 0:
 
              <span class="menu_link_notifications">${c.unread_notifications}</span>
 
            %endif
 
          %else:
 
              <span>${_('Not logged in')}</span>
 
          %endif
 
      </a>
 

	
 
  <div class="user-menu">
 
      <div id="quick_login">
 
        %if c.rhodecode_user.username == 'default':
 
            <h4>${_('Login to your account')}</h4>
 
            ${h.form(h.url('login_home',came_from=h.url.current()))}
 
            <div class="form">
 
                <div class="fields">
 
                    <div class="field">
 
                        <div class="label">
 
                            <label for="username">${_('Username')}:</label>
 
                        </div>
 
                        <div class="input">
 
                            ${h.text('username',class_='focus',size=40)}
 
                        </div>
 

	
 
                    </div>
 
                    <div class="field">
 
                        <div class="label">
 
                            <label for="password">${_('Password')}:</label>
 
                        </div>
 
                        <div class="input">
 
                            ${h.password('password',class_='focus',size=40)}
 
                        </div>
 

	
 
                    </div>
 
                    <div class="buttons">
 
                        <div class="password_forgoten">${h.link_to(_('Forgot password ?'),h.url('reset_password'))}</div>
 
                        <div class="register">
 
                        %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
 
                         ${h.link_to(_("Don't have an account ?"),h.url('register'))}
 
                        %endif
 
                        </div>
 
                        <div class="submit">
 
                            ${h.submit('sign_in',_('Log In'),class_="ui-btn xsmall")}
 
                        </div>
 
                    </div>
 
                </div>
 
            </div>
 
            ${h.end_form()}
 
        %else:
 
            <div class="links_left">
 
                <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
 
                <div class="email">${c.rhodecode_user.email}</div>
 
                <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,48)}" /></div>
 
                <div class="notifications"><a href="${h.url('notifications')}">${_('Notifications')}</a></div>
 
                <div class="unread"><a href="${h.url('notifications')}">${_('Unread')}: ${c.unread_notifications}</a></div>
 
            </div>
 
            <div class="links_right">
 
            <ol class="links">
 
              <li>${h.link_to(_(u'Home'),h.url('home'))}</li>
 
              <li>${h.link_to(_(u'Journal'),h.url('journal'))}</li>
 
              <li>${h.link_to(_(u'My account'),h.url('admin_settings_my_account'))}</li>
 
              <li class="logout">${h.link_to(_(u'Log Out'),h.url('logout_home'))}</li>
 
            </ol>
 
            </div>
 
        %endif
 
      </div>
 
  </div>
 

	
 
    </li>
 
</%def>
 

	
 
<%def name="menu(current=None)">
 
        <%
 
        def is_current(selected):
 
            if selected == current:
 
                return h.literal('class="current"')
 
        %>
 
        <ul id="quick">
 
          <!-- repo switcher -->
 
          <li ${is_current('home')}>
 
              <a class="menu_link" id="repo_switcher" title="${_('Switch repository')}" href="${h.url('home')}">
 
              <span class="icon">
 
                  <img src="${h.url('/images/icons/database.png')}" alt="${_('Products')}" />
 
              </span>
 
              <span>${_('Repositories')}</span>
 
              </a>
 
              <ul id="repo_switcher_list" class="repo_switcher">
 
                  <li>
 
                      <a href="#">${_('loading...')}</a>
 
                  </li>
 
              </ul>
 
          </li>
 
        ## we render this menu only not for those pages
 
        %if current not in ['home','admin', 'search', 'journal']:
 
            ##REGULAR MENU
 
            <li ${is_current('summary')}>
 
               <a class="menu_link" title="${_('Summary page')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
 
               <span class="icon">
 
                   <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
 
               </span>
 
               <span>${_('Summary')}</span>
 
               </a>
 
            </li>
 
            <li ${is_current('changelog')}>
 
               <a class="menu_link" title="${_('Changeset list')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
 
               <span class="icon">
 
                   <img src="${h.url('/images/icons/time.png')}" alt="${_('Changelog')}" />
 
               </span>
 
               <span>${_('Changelog')}</span>
 
               </a>
 
            </li>
 
            <li ${is_current('switch_to')}>
 
               <a class="menu_link" id="branch_tag_switcher" title="${_('Switch to')}" href="#">
 
               <span class="icon">
 
                   <img src="${h.url('/images/icons/arrow_switch.png')}" alt="${_('Switch to')}" />
 
               </span>
 
               <span>${_('Switch to')}</span>
 
               </a>
 
                <ul id="switch_to_list" class="switch_to">
 
                    <li><a href="#">${_('loading...')}</a></li>
 
                </ul>
 
            </li>
 
            <li ${is_current('files')}>
 
               <a class="menu_link" title="${_('Show repository content')}" href="${h.url('files_home',repo_name=c.repo_name)}">
 
               <span class="icon">
 
                   <img src="${h.url('/images/icons/file.png')}" alt="${_('Files')}" />
 
               </span>
 
               <span>${_('Files')}</span>
 
               </a>
 
            </li>
 
            <li ${is_current('options')}>
 
               <a class="menu_link" title="${_('Options')}" href="#">
 
               <span class="icon">
 
                   <img src="${h.url('/images/icons/table_gear.png')}" alt="${_('Admin')}" />
 
               </span>
 
               <span>${_('Options')}</span>
 
               </a>
 
               <ul>
 
               %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
 
                 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
 
                     <li>${h.link_to(_('repository settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
 
                 %else:
 
                     <li>${h.link_to(_('repository settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
 
                 %endif
 
               %endif
 

	
 
                <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
 
                %if h.is_hg(c.rhodecode_repo):
 
                 <li>${h.link_to(_('open new pull request'),h.url('pullrequest_home',repo_name=c.repo_name),class_='pull_request')}</li>
 
                %endif
 
                %if c.rhodecode_db_repo.fork:
 
                 <li>${h.link_to(_('compare fork'),h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default'),class_='compare_request')}</li>
 
                %endif
 
                <li>${h.link_to(_('lightweight changelog'),h.url('shortlog_home',repo_name=c.repo_name),class_='shortlog')}</li>
 
                <li>${h.link_to(_('search'),h.url('search_repo',repo_name=c.repo_name),class_='search')}</li>
 

	
 
                %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
 
                  %if c.rhodecode_db_repo.locked[0]:
 
                    <li>${h.link_to(_('unlock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_del')}</li>
 
                  %else:
 
                    <li>${h.link_to(_('lock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_add')}</li>
 
                  %endif
 
                %endif
 

	
 
                % if h.HasPermissionAll('hg.admin')('access admin main page'):
 
                   <li>
 
                     ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
 
                      <%def name="admin_menu()">
 
                      <ul>
 
                          <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li>
 
                          <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
 
                          <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
 
                          <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
 
                          <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
 
                          <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
 
                          <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
 
                          <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li>
 
                          <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
 
                      </ul>
 
                      </%def>
 
                      ## ADMIN MENU
 
                      ${admin_menu()}
 
                   </li>
 
                ## if you're a admin of any groups, show admin menu for it
 
                % elif c.rhodecode_user.groups_admin:
 
                   <li>
 
                     ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
 
                      <%def name="admin_menu_simple()">
 
                      <ul>
 
                          <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
 
                      </ul>
 
                      </%def>
 
                      ## ADMIN MENU
 
                      ${admin_menu_simple()}
 
                   </li>
 
                % endif
 
               </ul>
 
            </li>
 
            <li>
 
                <a class="menu_link" title="${_('Followers')}" href="${h.url('repo_followers_home',repo_name=c.repo_name)}">
 
                <span class="icon_short">
 
                    <img src="${h.url('/images/icons/heart.png')}" alt="${_('Followers')}" />
 
                </span>
 
                <span id="current_followers_count" class="short">${c.repository_followers}</span>
 
                </a>
 
            </li>
 
            <li>
 
                <a class="menu_link" title="${_('Forks')}" href="${h.url('repo_forks_home',repo_name=c.repo_name)}">
 
                <span class="icon_short">
 
                    <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Forks')}" />
 
                </span>
 
                <span class="short">${c.repository_forks}</span>
 
                </a>
 
            </li>
 
            <li>
 
                <a class="menu_link" title="${_('Pull requests')}" href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}">
 
                <span class="icon_short">
 
                    <img src="${h.url('/images/icons/arrow_join.png')}" alt="${_('Pull requests')}" />
 
                </span>
 
                <span class="short">${c.repository_pull_requests}</span>
 
                </a>
 
            </li>
 
            ${usermenu()}
 
            <script type="text/javascript">
 
                YUE.on('branch_tag_switcher','mouseover',function(){
 
                   var loaded = YUD.hasClass('branch_tag_switcher','loaded');
 
                   if(!loaded){
 
                       YUD.addClass('branch_tag_switcher','loaded');
 
                       ypjax("${h.url('branch_tag_switcher',repo_name=c.repo_name)}",'switch_to_list',
 
                           function(o){},
 
                           function(o){YUD.removeClass('branch_tag_switcher','loaded');}
 
                           ,null);
 
                   }
 
                   return false;
 
                });
 
            </script>
 
        %else:
 
            ##ROOT MENU
 
            %if c.rhodecode_user.username != 'default':
 
             <li ${is_current('journal')}>
 
                <a class="menu_link" title="${_('Show recent activity')}"  href="${h.url('journal')}">
 
                <span class="icon">
 
                    <img src="${h.url('/images/icons/book.png')}" alt="${_('Journal')}" />
 
                </span>
 
                <span>${_('Journal')}</span>
 
                </a>
 
             </li>
 
            %else:
 
             <li ${is_current('journal')}>
 
                <a class="menu_link" title="${_('Public journal')}"  href="${h.url('public_journal')}">
 
                <span class="icon">
 
                    <img src="${h.url('/images/icons/book.png')}" alt="${_('Public journal')}" />
 
                </span>
 
                <span>${_('Public journal')}</span>
 
                </a>
 
             </li>
 
            %endif
 
            <li ${is_current('search')}>
 
                <a class="menu_link" title="${_('Search in repositories')}"  href="${h.url('search')}">
 
                <span class="icon">
 
                    <img src="${h.url('/images/icons/search_16.png')}" alt="${_('Search')}" />
 
                </span>
 
                <span>${_('Search')}</span>
 
                </a>
 
            </li>
 
            % if h.HasPermissionAll('hg.admin')('access admin main page'):
 
            <li ${is_current('admin')}>
 
               <a class="menu_link" title="${_('Admin')}" href="${h.url('admin_home')}">
 
               <span class="icon">
 
                   <img src="${h.url('/images/icons/cog_edit.png')}" alt="${_('Admin')}" />
 
               </span>
 
               <span>${_('Admin')}</span>
 
               </a>
 
                ${admin_menu()}
 
            </li>
 
            % elif c.rhodecode_user.groups_admin:
 
            <li ${is_current('admin')}>
 
               <a class="menu_link" title="${_('Admin')}" href="${h.url('admin_home')}">
 
               <span class="icon">
 
                   <img src="${h.url('/images/icons/cog_edit.png')}" alt="${_('Admin')}" />
 
               </span>
 
               <span>${_('Admin')}</span>
 
               </a>
 
                ${admin_menu_simple()}
 
            </li>
 
            % endif
 
            ${usermenu()}
 
        %endif
 
<script type="text/javascript">
 
    YUE.on('repo_switcher','mouseover',function(){
 
      var target = 'q_filter_rs';
 
      var qfilter_activate = function(){
 
          var nodes = YUQ('ul#repo_switcher_list li a.repo_name');
 
          var func = function(node){
 
              return node.parentNode;
 
          }
 
          q_filter(target,nodes,func);
 
      }
 

	
 
      var loaded = YUD.hasClass('repo_switcher','loaded');
 
      if(!loaded){
 
         YUD.addClass('repo_switcher','loaded');
 
         ypjax("${h.url('repo_switcher')}",'repo_switcher_list',
 
             function(o){qfilter_activate();YUD.get(target).focus()},
 
             function(o){YUD.removeClass('repo_switcher','loaded');}
 
             ,null);
 
      }else{
 
         YUD.get(target).focus();
 
      }
 
      return false;
 
     });
 

	
 
     YUE.on('header-dd', 'click',function(e){
 
         YUD.addClass('header-inner', 'hover');
 
         YUD.addClass('content', 'hover');
 
     });
 

	
 
</script>
 
</%def>
rhodecode/templates/base/root.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
 
    <head>
 
        <title>${self.title()}</title>
 
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 
        <meta name="robots" content="index, nofollow"/>
 
        <link rel="icon" href="${h.url('/images/icons/database_gear.png')}" type="image/png" />
 

	
 
        ## CSS ###
 
        <%def name="css()">
 
            <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css', ver=c.rhodecode_version)}" media="screen"/>
 
            <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css', ver=c.rhodecode_version)}"/>
 

	
 
            <link rel="stylesheet" type="text/css" href="${h.url('/css/contextbar.css', ver=c.rhodecode_version)}"/>
 
            ## EXTRA FOR CSS
 
            ${self.css_extra()}
 
        </%def>
 
        <%def name="css_extra()">
 
        </%def>
 

	
 
        ${self.css()}
 

	
 
        %if c.ga_code:
 
        <!-- Analytics -->
 
        <script type="text/javascript">
 
            var _gaq = _gaq || [];
 
            _gaq.push(['_setAccount', '${c.ga_code}']);
 
            _gaq.push(['_trackPageview']);
 

	
 
            (function() {
 
                var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 
                ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 
                var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 
                })();
 
        </script>
 
        %endif
 

	
 
        ## JAVASCRIPT ##
 
        <%def name="js()">
 
            <script type="text/javascript">
 
            //JS translations map
 
            var TRANSLATION_MAP = {
 
                'add another comment':'${_("add another comment")}',
 
                'Stop following this repository':"${_('Stop following this repository')}",
 
                'Start following this repository':"${_('Start following this repository')}",
 
                'Group':"${_('Group')}",
 
                'members':"${_('members')}",
 
                'loading...':"${_('loading...')}",
 
                'search truncated': "${_('search truncated')}",
 
                'no matching files': "${_('no matching files')}",
 
                'Open new pull request': "${_('Open new pull request')}",
 
                'Open new pull request for selected changesets':  "${_('Open new pull request for selected changesets')}",
 
                'Show selected changes __S -> __E': "${_('Show selected changes __S -> __E')}",
 
                'Selection link': "${_('Selection link')}",
 
            };
 
            var _TM = TRANSLATION_MAP;
 

	
 
            var TOGGLE_FOLLOW_URL  = "${h.url('toggle_following')}";
 

	
 
            </script>
 
            <script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.rhodecode_version)}"></script>
 
            <!--[if lt IE 9]>
 
               <script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script>
 
            <![endif]-->
 
            <script type="text/javascript" src="${h.url('/js/yui.flot.js', ver=c.rhodecode_version)}"></script>
 
            <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.rhodecode_version)}"></script>
 
            <script type="text/javascript" src="${h.url('/js/pyroutes_map.js', ver=c.rhodecode_version)}"></script>
 
            <script type="text/javascript" src="${h.url('/js/rhodecode.js', ver=c.rhodecode_version)}"></script>
 
           ## EXTRA FOR JS
 
           ${self.js_extra()}
 
            <script type="text/javascript">
 
            (function(window,undefined){
 
                // Prepare
 
                var History = window.History; // Note: We are using a capital H instead of a lower h
 
                if ( !History.enabled ) {
 
                     // History.js is disabled for this browser.
 
                     // This is because we can optionally choose to support HTML4 browsers or not.
 
                    return false;
 
                }
 
            })(window);
 

	
 
            YUE.onDOMReady(function(){
 
              tooltip_activate();
 
              show_more_event();
 
              show_changeset_tooltip();
 
              // routes registration
 
              pyroutes.register('toggle_following', "${h.url('toggle_following')}");
 
              pyroutes.register('changeset_info', "${h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s')}", ['repo_name', 'revision']);
 
              pyroutes.register('repo_size', "${h.url('repo_size', repo_name='%(repo_name)s')}", ['repo_name']);
 
           })
 
            </script>
 
        </%def>
 
        <%def name="js_extra()"></%def>
 
        ${self.js()}
 
        <%def name="head_extra()"></%def>
 
        ${self.head_extra()}
 
    </head>
 
    <body id="body">
 
     ## IE hacks
 
      <!--[if IE 7]>
 
      <script>YUD.addClass(document.body,'ie7')</script>
 
      <![endif]-->
 
      <!--[if IE 8]>
 
      <script>YUD.addClass(document.body,'ie8')</script>
 
      <![endif]-->
 
      <!--[if IE 9]>
 
      <script>YUD.addClass(document.body,'ie9')</script>
 
      <![endif]-->
 

	
 
      ${next.body()}
 
    </body>
 
</html>
rhodecode/templates/changelog/changelog.html
Show inline comments
 
## -*- coding: utf-8 -*-
 

	
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
${_('%s Changelog') % c.repo_name} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    <% size = c.size if c.size <= c.total_cs else c.total_cs %>
 
    ${_('changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('changelog')}
 
</%def>
 

	
 
<%def name="main()">
 
 ${self.context_bar('changelog')}
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <div class="table">
 
        % if c.pagination:
 
            <div id="graph">
 
                <div id="graph_nodes">
 
                    <canvas id="graph_canvas"></canvas>
 
                </div>
 
                <div id="graph_content">
 
                    <div class="info_box" style="clear: both;padding: 10px 6px;vertical-align: right;text-align: right;">
 
                    <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a>
 
                    <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a>
 

	
 
                    %if c.rhodecode_db_repo.fork:
 
                        <a title="${_('compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default')}" class="ui-btn small">${_('Compare fork with parent')}</a>
 
                    %endif
 
                    %if h.is_hg(c.rhodecode_repo):
 
                    <a id="open_new_pr" href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('open new pull request')}</a>
 
                    %endif
 
                    </div>
 
                    <div class="container_header">
 
                        ${h.form(h.url.current(),method='get')}
 
                        <div class="info_box" style="float:left">
 
                          ${h.submit('set',_('Show'),class_="ui-btn")}
 
                          ${h.text('size',size=1,value=c.size)}
 
                          ${_('revisions')}
 
                        </div>
 
                        ${h.end_form()}
 
                    <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
 
                    </div>
 

	
 
                %for cnt,cs in enumerate(c.pagination):
 
                    <div id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
 
                        <div class="left">
 
                            <div>
 
                            ${h.checkbox(cs.raw_id,class_="changeset_range")}
 
                            <span class="tooltip" title="${h.tooltip(h.age(cs.date))}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}"><span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span></a></span>
 
                            </div>
 
                            <div class="author">
 
                                <div class="gravatar">
 
                                    <img alt="gravatar" src="${h.gravatar_url(h.email_or_none(cs.author),16)}"/>
 
                                </div>
 
                                <div title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</div>
 
                            </div>
 
                            <div class="date">${h.fmt_date(cs.date)}</div>
 
                        </div>
 
                        <div class="mid">
 
                            <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
 
                            <div class="expand"><span class="expandtext">&darr; ${_('show more')} &darr;</span></div>
 
                        </div>
 
                        <div class="right">
 
                                    <div class="changes">
 
                                        <div id="changed_total_${cs.raw_id}" style="float:right;" class="changed_total tooltip" title="${h.tooltip(_('Affected number of files, click to show more details'))}">${len(cs.affected_files)}</div>
 
                                        <div class="comments-container">
 
                                        %if len(c.comments.get(cs.raw_id,[])) > 0:
 
                                            <div class="comments-cnt" title="${('comments')}">
 
                                              <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
 
                                               <div class="comments-cnt">${len(c.comments[cs.raw_id])}</div>
 
                                               <img src="${h.url('/images/icons/comments.png')}">
 
                                              </a>
 
                                            </div>
 
                                        %endif
 
                                        </div>
 
                                        <div class="changeset-status-container">
 
                                            %if c.statuses.get(cs.raw_id):
 
                                              <div title="${_('Changeset status')}" class="changeset-status-lbl">${c.statuses.get(cs.raw_id)[1]}</div>
 
                                              <div class="changeset-status-ico">
 
                                              %if c.statuses.get(cs.raw_id)[2]:
 
                                                <a class="tooltip" title="${_('Click to open associated pull request #%s' % c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" /></a>
 
                                              %else:
 
                                                <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
 
                                              %endif
 
                                              </div>
 
                                            %endif
 
                                        </div>
 
                                    </div>
 
                                   %if cs.parents:
 
                                    %for p_cs in reversed(cs.parents):
 
                                        <div class="parent">${_('Parent')}
 
                                            <span class="changeset_id">${p_cs.revision}:<span class="changeset_hash">${h.link_to(h.short_id(p_cs.raw_id),
 
                                            h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}</span></span>
 
                                        </div>
 
                                    %endfor
 
                                   %else:
 
                                        <div class="parent">${_('No parents')}</div>
 
                                   %endif
 

	
 
                                <span class="logtags">
 
                                    %if len(cs.parents)>1:
 
                                    <span class="merge">${_('merge')}</span>
 
                                    %endif
 
                                    %if cs.branch:
 
                                    <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}">
 
                                       ${h.link_to(h.shorter(cs.branch),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
 
                                    </span>
 
                                    %endif
 
                                    %if h.is_hg(c.rhodecode_repo):
 
                                      %for book in cs.bookmarks:
 
                                      <span class="bookbook" title="${'%s %s' % (_('bookmark'),book)}">
 
                                         ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
 
                                      </span>
 
                                      %endfor
 
                                    %endif
 
                                    %for tag in cs.tags:
 
                                        <span class="tagtag"  title="${'%s %s' % (_('tag'),tag)}">
 
                                        ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span>
 
                                    %endfor
 
                                </span>
 
                        </div>
 
                    </div>
 

	
 
                %endfor
 
                <div class="pagination-wh pagination-left">
 
                    ${c.pagination.pager('$link_previous ~2~ $link_next')}
 
                </div>
 
                </div>
 
            </div>
 

	
 
            <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
 
            <script type="text/javascript">
 
                YAHOO.util.Event.onDOMReady(function(){
 

	
 
                    //Monitor range checkboxes and build a link to changesets
 
                    //ranges
 
                    var checkboxes = YUD.getElementsByClassName('changeset_range');
 
                    var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
 
                    var pr_tmpl = "${h.url('pullrequest_home',repo_name=c.repo_name)}";
 
                    YUE.on(checkboxes,'click',function(e){
 
                        var clicked_cb = e.currentTarget;
 
                        var checked_checkboxes = [];
 
                        for (pos in checkboxes){
 
                            if(checkboxes[pos].checked){
 
                                checked_checkboxes.push(checkboxes[pos]);
 
                            }
 
                        }
 
                        if(YUD.get('open_new_pr')){
 
                          if(checked_checkboxes.length>0){
 
                            // modify open pull request to show we have selected cs
 
                            YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets'];
 

	
 
                          }else{
 
                            YUD.get('open_new_pr').innerHTML = _TM['Open new pull request'];
 
                          }
 
                        }
 

	
 
                        if(checked_checkboxes.length>0){
 
                            var rev_end = checked_checkboxes[0].name;
 
                            var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
 

	
 
                            // now select all checkboxes in the middle.
 
                            var checked = false;
 
                            for (var i=0; i<checkboxes.length; i++){
 
                                var cb = checkboxes[i];
 
                                var rev = cb.name;
 

	
 
                                if (rev == rev_end){
 
                                    checked = true;
 
                                }
 
                                if (checked){
 
                                    cb.checked = true;
 
                                }
 
                                else{
 
                                    cb.checked = false;
 
                                }
 
                                if (rev == rev_start){
 
                                    checked = false;
 
                                }
 

	
 
                            }
 

	
 
                            var url = url_tmpl.replace('__REVRANGE__',
 
                                    rev_start+'...'+rev_end);
 

	
 
                            var link = _TM['Show selected changes __S -> __E'];
 
                            link = link.replace('__S',rev_start.substr(0,6));
 
                            link = link.replace('__E',rev_end.substr(0,6));
 
                            YUD.get('rev_range_container').href = url;
 
                            YUD.get('rev_range_container').innerHTML = link;
 
                            YUD.setStyle('rev_range_container','display','');
 
                            YUD.setStyle('rev_range_clear','display','');
 

	
 
                            YUD.get('open_new_pr').href = pr_tmpl + '?rev_start={0}&rev_end={1}'.format(rev_start,rev_end);
 

	
 
                        }
 
                        else{
 
                            YUD.setStyle('rev_range_container','display','none');
 
                            YUD.setStyle('rev_range_clear','display','none');
 
                        }
 
                    });
 
                    YUE.on('rev_range_clear','click',function(e){
 
                        for (var i=0; i<checkboxes.length; i++){
 
                            var cb = checkboxes[i];
 
                            cb.checked = false;
 
                        }
 
                        YUE.preventDefault(e);
 
                    })
 
                    var msgs = YUQ('.message');
 
                    // get first element height
 
                    var el = YUQ('#graph_content .container')[0];
 
                    var row_h = el.clientHeight;
 
                    for(var i=0;i<msgs.length;i++){
 
                        var m = msgs[i];
 

	
 
                        var h = m.clientHeight;
 
                        var pad = YUD.getStyle(m,'padding');
 
                        if(h > row_h){
 
                            var offset = row_h - (h+12);
 
                            YUD.setStyle(m.nextElementSibling,'display','block');
 
                            YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
 
                        };
 
                    }
 
                    YUE.on(YUQ('.expand'),'click',function(e){
 
                        var elem = e.currentTarget.parentNode.parentNode;
 
                        YUD.setStyle(e.currentTarget,'display','none');
 
                        YUD.setStyle(elem,'height','auto');
 

	
 
                        //redraw the graph, line_count and jsdata are global vars
 
                        set_canvas(100);
 

	
 
                        var r = new BranchRenderer();
 
                        r.render(jsdata,100,line_count);
 

	
 
                    })
 

	
 
                    // Fetch changeset details
 
                    YUE.on(YUD.getElementsByClassName('changed_total'),'click',function(e){
 
                        var id = e.currentTarget.id;
 
                        var url = "${h.url('changelog_details',repo_name=c.repo_name,cs='__CS__')}";
 
                        var url = url.replace('__CS__',id.replace('changed_total_',''));
 
                        ypjax(url,id,function(){tooltip_activate()});
 
                    });
 

	
 
                    // change branch filter
 
                    YUE.on(YUD.get('branch_filter'),'change',function(e){
 
                        var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
 
                        var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
 
                        var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
 
                        var url = url.replace('__BRANCH__',selected_branch);
 
                        if(selected_branch != ''){
 
                            window.location = url;
 
                        }else{
 
                            window.location = url_main;
 
                        }
 

	
 
                    });
 

	
 
                    function set_canvas(width) {
 
                        var c = document.getElementById('graph_nodes');
 
                        var t = document.getElementById('graph_content');
 
                        canvas = document.getElementById('graph_canvas');
 
                        var div_h = t.clientHeight;
 
                        c.style.height=div_h+'px';
 
                        canvas.setAttribute('height',div_h);
 
                        c.style.height=width+'px';
 
                        canvas.setAttribute('width',width);
 
                    };
 
                    var heads = 1;
 
                    var line_count = 0;
 
                    var jsdata = ${c.jsdata|n};
 

	
 
                    for (var i=0;i<jsdata.length;i++) {
 
                        var in_l = jsdata[i][2];
 
                        for (var j in in_l) {
 
                            var m = in_l[j][1];
 
                            if (m > line_count)
 
                                line_count = m;
 
                        }
 
                    }
 
                    set_canvas(100);
 

	
 
                    var r = new BranchRenderer();
 
                    r.render(jsdata,100,line_count);
 

	
 
                });
 
            </script>
 
        %else:
 
            ${_('There are no changes yet')}
 
        %endif
 
    </div>
 
</div>
 
</%def>
rhodecode/templates/files/files.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('%s files') % c.repo_name} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    ${_('files')}
 
    %if c.file:
 
        @ r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)}
 
    %endif
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('files')}
 
</%def>
 

	
 
<%def name="main()">
 
 ${self.context_bar('files')}
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
        <ul class="links">
 
            <li>
 
              <span style="text-transform: uppercase;"><a href="#">${_('branch')}: ${c.changeset.branch}</a></span>
 
            </li>
 
        </ul>
 
    </div>
 
    <div class="table">
 
        <div id="files_data">
 
            <%include file='files_ypjax.html'/>
 
        </div>
 
    </div>
 
</div>
 

	
 
<script type="text/javascript">
 
var CACHE = {};
 
var CACHE_EXPIRE = 5*60*1000; //cache for 5*60s
 
//used to construct links from the search list
 
var url_base = '${h.url("files_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}';
 
//send the nodelist request to this url
 
var node_list_url = '${h.url("files_nodelist_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}';
 
// send the node history requst to this url
 
var node_history_url = '${h.url("files_history_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}';
 

	
 
var ypjax_links = function(){
 
    YUE.on(YUQ('.ypjax-link'), 'click',function(e){
 

	
 
        //don't do ypjax on middle click
 
        if(e.which == 2 || !History.enabled){
 
            return true;
 
        }
 

	
 
        var el = e.currentTarget;
 
        var url = el.href;
 

	
 
        var _base_url = '${h.url("files_home",repo_name=c.repo_name,revision='',f_path='')}';
 
        _base_url = _base_url.replace('//','/')
 

	
 
        //extract rev and the f_path from url.
 
        parts = url.split(_base_url)
 
        if(parts.length != 2){
 
            return false;
 
        }
 

	
 
        var parts2 = parts[1].split('/');
 
          var rev = parts2.shift(); // pop the first element which is the revision
 
          var f_path = parts2.join('/');
 

	
 
        var title = "${_('%s files') % c.repo_name}" + " - " + f_path;
 

	
 
        var _node_list_url = node_list_url.replace('__REV__',rev).replace('__FPATH__', f_path);
 
        var _url_base = url_base.replace('__REV__',rev);
 

	
 
        // Change our States and save some data for handling events
 
        var data = {url:url,title:title, url_base:_url_base,
 
                    node_list_url:_node_list_url, rev:rev, f_path:f_path};
 
        History.pushState(data, title, url);
 

	
 
        //now we're sure that we can do ypjax things
 
        YUE.preventDefault(e);
 
        return false;
 
    });
 
}
 

	
 
var callbacks = function(State){
 
    ypjax_links();
 
    tooltip_activate();
 
    fileBrowserListeners(State.url, State.data.node_list_url, State.data.url_base);
 

	
 
    if(YUD.get('hlcode')){
 
        YUE.on('hlcode', 'mouseup', getSelectionLink);
 
    }
 
    //console.log(State);
 
    if(YUD.get('load_node_history')){
 
      //remove all listeners due to problems of history state
 
      YUE.removeListener('load_node_history', 'click');
 
      YUE.on('load_node_history', 'click', function(e){
 
          var _url = node_history_url.replace('__REV__',State.data.rev).replace('__FPATH__', State.data.f_path);
 
          ypjax(_url, 'node_history', function(o){
 
              tooltip_activate();
 
          })
 
      });
 
    }
 
    // Inform Google Analytics of the change
 
    if ( typeof window.pageTracker !== 'undefined' ) {
 
        window.pageTracker._trackPageview(State.url);
 
    }
 
}
 

	
 
YUE.onDOMReady(function(){
 
    ypjax_links();
 
    var container = 'files_data';
 
    //Bind to StateChange Event
 
    History.Adapter.bind(window,'statechange',function(){
 
        var State = History.getState();
 
        cache_key = State.url;
 
        //check if we have this request in cache maybe ?
 
        var _cache_obj = CACHE[cache_key];
 
        var _cur_time = new Date().getTime();
 
        // get from cache if it's there and not yet expired !
 
        if(_cache_obj !== undefined && _cache_obj[0] > _cur_time){
 
            YUD.get(container).innerHTML=_cache_obj[1];
 
            YUD.setStyle(container,'opacity','1.0');
 

	
 
            //callbacks after ypjax call
 
            callbacks(State);
 
        }
 
        else{
 
          ypjax(State.url,container,function(o){
 
              //callbacks after ypjax call
 
              callbacks(State);
 
              if (o !== undefined){
 
                //store our request in cache
 
                var _expire_on = new Date().getTime()+CACHE_EXPIRE;
 
              CACHE[cache_key] = [_expire_on, o.responseText];
 
            }
 
          });
 
        }
 
    });
 

	
 
    // init the search filter
 
    var _State = {
 
       url: "${h.url.current()}",
 
       data: {
 
         node_list_url: node_list_url.replace('__REV__',"${c.changeset.raw_id}").replace('__FPATH__', "${h.safe_unicode(c.file.path)}"),
 
         url_base: url_base.replace('__REV__',"${c.changeset.raw_id}"),
 
         rev:"${c.changeset.raw_id}",
 
         f_path: "${h.safe_unicode(c.file.path)}"
 
       }
 
    }
 
    fileBrowserListeners(_State.url, _State.data.node_list_url, _State.data.url_base);
 
});
 

	
 
</script>
 

	
 
</%def>
rhodecode/templates/pullrequests/pullrequest_show_all.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${c.repo_name} ${_('all pull requests')}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    ${_('pull requests')}
 
</%def>
 

	
 
<%def name="main()">
 

	
 
${self.context_bar('showpullrequest')}
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 

	
 
    %for pr in c.pull_requests:
 
        <div>
 
          <h4  style="border:0px;padding:0px">
 
            %if pr.is_closed():
 
                <img src="${h.url('/images/icons/lock_go.png')}" title="${_('Closed')}"/>
 
            %endif
 
            <img src="${h.url('/images/icons/flag_status_%s.png' % str(pr.last_review_status))}" />
 
            <a href="${h.url('pullrequest_show',repo_name=c.repo_name,pull_request_id=pr.pull_request_id)}">
 
            ${_('Pull request #%s opened by %s on %s') % (pr.pull_request_id, pr.author.full_name, h.fmt_date(pr.created_on))}
 
            </a>
 
          </h4>
 
          <h5 style="border:0px;padding-bottom:0px">${_('Title')}: ${pr.title}</h5>
 
          <div style="padding:0px 24px">${pr.description}</div>
 
          <div style="border-bottom: 1px solid #DDD;margin:10px 20px;padding-bottom:10px"></div>
 
        </div>
 
    %endfor
 

	
 
</div>
 

	
 
<script type="text/javascript"></script>
 

	
 
</%def>
rhodecode/templates/search/search.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
  %if c.repo_name:
 
    ${_('Search repository')} ${c.repo_name} - ${c.rhodecode_name}
 
  %else:
 
    ${_('Search in all repositories')}
 
  %endif
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
  %if c.repo_name:
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    ${_('search')}
 
  %else:
 
    ${_('search in all repositories')}
 
  %endif
 
  %if c.cur_query:
 
    &raquo;
 
    ${c.cur_query}
 
  %endif
 
</%def>
 

	
 
<%def name="page_nav()">
 
    %if c.repo_name:
 
    ${self.menu('options')}
 
    %else:
 
    ${self.menu('search')}
 
    %endif
 
</%def>
 
<%def name="main()">
 

	
 
 ${self.context_bar('options')}
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <!-- end box / title -->
 
    %if c.repo_name:
 
        ${h.form(h.url('search_repo',repo_name=c.repo_name),method='get')}
 
    %else:
 
        ${h.form(h.url('search'),method='get')}
 
    %endif
 
    <div class="form">
 
        <div class="fields">
 
            <div class="field field-first field-noborder">
 
             <div class="label">
 
                 <label for="q">${_('Search term')}</label>
 
             </div>
 
                <div class="input">${h.text('q',c.cur_query,class_="small")}
 
                    <div class="button highlight">
 
                        <input type="submit" value="${_('Search')}" class="ui-button"/>
 
                    </div>
 
                </div>
 
                <div style="font-weight: bold;clear:Both;margin-left:200px">${c.runtime}</div>
 
            </div>
 

	
 
            <div class="field">
 
                <div class="label">
 
                    <label for="type">${_('Search in')}</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('type',c.cur_type,[('content',_('File contents')),
 
                        ('commit',_('Commit messages')),
 
                        ('path',_('File names')),
 
                        ##('repository',_('Repository names')),
 
                        ])}
 
                </div>
 
             </div>
 

	
 
        </div>
 
    </div>
 
    ${h.end_form()}
 
    <div class="search">
 
    %if c.cur_type == 'content':
 
        <%include file='search_content.html'/>
 
    %elif c.cur_type == 'path':
 
        <%include file='search_path.html'/>
 
    %elif c.cur_type == 'commit':
 
        <%include file='search_commit.html'/>
 
    %elif c.cur_type == 'repository':
 
        <%include file='search_repository.html'/>
 
    %endif
 
    </div>
 
</div>
 

	
 
</%def>
rhodecode/templates/shortlog/shortlog.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('%s Shortlog') % c.repo_name} - ${c.rhodecode_name}
 
</%def>
 

	
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    %if c.file_history:
 
        ${h.link_to(_('shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}
 
        &raquo;
 
        ${c.file_history}
 
    %else:
 
        ${_('shortlog')}
 
    %endif
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('shortlog')}
 
</%def>
 
<%def name="main()">
 
 ${self.context_bar('options')}
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <!-- end box / title -->
 
    <div class="table">
 
        <div id="shortlog_data">
 
            ${c.shortlog_data}
 
        </div>
 
    </div>
 
</div>
 
</%def>
rhodecode/templates/summary/summary.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('%s Summary') % c.repo_name} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    ${_('summary')}
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('summary')}
 
</%def>
 

	
 
<%def name="head_extra()">
 
<link href="${h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('repo %s ATOM feed') % c.repo_name}" type="application/atom+xml" />
 
<link href="${h.url('rss_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('repo %s RSS feed') % c.repo_name}" type="application/rss+xml" />
 
</%def>
 

	
 
<%def name="main()">
 
    ${self.context_bar('summary')}
 
    <%
 
    summary = lambda n:{False:'summary-short'}.get(n)
 
    %>
 
    %if c.show_stats:
 
        <div class="box box-left">
 
    %else:
 
        <div class="box">
 
    %endif
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <!-- end box / title -->
 
    <div class="form">
 
      <div id="summary" class="fields">
 

	
 
             <div class="field">
 
              <div class="label-summary">
 
                  <label>${_('Name')}:</label>
 
              </div>
 
              <div class="input ${summary(c.show_stats)}">
 
                  <div style="float:right;padding:5px 0px 0px 5px">
 
                     %if c.rhodecode_user.username != 'default':
 
                      ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='atom_icon')}
 
                     %else:
 
                      ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name),class_='atom_icon')}
 
                     %endif
 
                  </div>
 
                  %if c.rhodecode_user.username != 'default':
 
                      %if c.following:
 
                      <span id="follow_toggle" class="following tooltip" title="${_('Stop following this repository')}"
 
                            onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
 
                      </span>
 
                      %else:
 
                      <span id="follow_toggle" class="follow tooltip" title="${_('Start following this repository')}"
 
                            onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
 
                      </span>
 
                      %endif
 
                      <div style="float:right;padding:0px 0px 0px 0px">
 
                         <span class="reposize tooltip" title="${_('Click to show size of repository')}"
 
                            onclick="javascript:showRepoSize('repo_size','${c.dbrepo.repo_name}','${str(h.get_token())}')">
 
                         </span>
 
                         <span id="repo_size"></span>
 
                      </div>
 
                  %endif:
 

	
 
                   ## locking icon
 
                    %if c.rhodecode_db_repo.enable_locking:
 
                      %if c.rhodecode_db_repo.locked[0]:
 
                        <span class="locking_locked tooltip" title="${_('Repository locked by %s') % h.person_by_id(c.rhodecode_db_repo.locked[0])}"></span>
 
                      %else:
 
                        <span class="locking_unlocked tooltip" title="${_('Repository unlocked')}"></span>
 
                      %endif
 
                    %endif
 
                 ##REPO TYPE
 
                 %if h.is_hg(c.dbrepo):
 
                   <img style="margin-bottom:2px" class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
 
                 %endif
 
                 %if h.is_git(c.dbrepo):
 
                   <img style="margin-bottom:2px" class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
 
                 %endif
 

	
 
                 ##PUBLIC/PRIVATE
 
                 %if c.dbrepo.private:
 
                    <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
 
                 %else:
 
                    <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
 
                 %endif
 

	
 
                  ##REPO NAME
 
                  <span class="repo_name" title="${_('Non changable ID %s') % c.dbrepo.repo_id}">${h.repo_link(c.dbrepo.groups_and_repo)}</span>
 

	
 
                  ##FORK
 
                  %if c.dbrepo.fork:
 
                    <div style="margin-top:5px;clear:both"">
 
                    <div style="margin-top:5px;clear:both">
 
                    <a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}"><img class="icon" alt="${_('public')}" title="${_('Fork of')} ${c.dbrepo.fork.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/>
 
                        ${_('Fork of')} ${c.dbrepo.fork.repo_name}
 
                    </a>
 
                    </div>
 
                  %endif
 
                  ##REMOTE
 
                  %if c.dbrepo.clone_uri:
 
                    <div style="margin-top:5px;clear:both">
 
                    <a href="${h.url(str(h.hide_credentials(c.dbrepo.clone_uri)))}"><img class="icon" alt="${_('remote clone')}" title="${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}" src="${h.url('/images/icons/connect.png')}"/>
 
                        ${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}
 
                    </a>
 
                    </div>
 
                  %endif
 
              </div>
 
             </div>
 

	
 
             <div class="field">
 
              <div class="label-summary">
 
                  <label>${_('Description')}:</label>
 
              </div>
 
              %if c.visual.stylify_metatags:
 
                <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(h.desc_stylize(c.dbrepo.description))}</div>
 
              %else:
 
                <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(c.dbrepo.description)}</div>
 
              %endif
 
             </div>
 

	
 
             <div class="field">
 
              <div class="label-summary">
 
                  <label>${_('Contact')}:</label>
 
              </div>
 
              <div class="input ${summary(c.show_stats)}">
 
                  <div class="gravatar">
 
                      <img alt="gravatar" src="${h.gravatar_url(c.dbrepo.user.email)}"/>
 
                  </div>
 
                      ${_('Username')}: ${c.dbrepo.user.username}<br/>
 
                      ${_('Name')}: ${c.dbrepo.user.name} ${c.dbrepo.user.lastname}<br/>
 
                      ${_('Email')}: <a href="mailto:${c.dbrepo.user.email}">${c.dbrepo.user.email}</a>
 
              </div>
 
             </div>
 

	
 
             <div class="field">
 
              <div class="label-summary">
 
                  <label>${_('Clone url')}:</label>
 
              </div>
 
              <div class="input ${summary(c.show_stats)}">
 
                  <input style="width:80%" type="text" id="clone_url" readonly="readonly" value="${c.clone_repo_url}"/>
 
                  <input style="display:none;width:80%" type="text" id="clone_url_id" readonly="readonly" value="${c.clone_repo_url_id}"/>
 
                  <div style="display:none" id="clone_by_name" class="ui-btn clone">${_('Show by Name')}</div>
 
                  <div id="clone_by_id" class="ui-btn clone">${_('Show by ID')}</div>
 
              </div>
 
             </div>
 

	
 
             <div class="field">
 
              <div class="label-summary">
 
                  <label>${_('Trending files')}:</label>
 
              </div>
 
              <div class="input ${summary(c.show_stats)}">
 
                %if c.show_stats:
 
                <div id="lang_stats"></div>
 
                %else:
 
                   ${_('Statistics are disabled for this repository')}
 
                   %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
 
                        ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
 
                   %endif
 
                %endif
 
              </div>
 
             </div>
 

	
 
             <div class="field">
 
              <div class="label-summary">
 
                  <label>${_('Download')}:</label>
 
              </div>
 
              <div class="input ${summary(c.show_stats)}">
 
                %if len(c.rhodecode_repo.revisions) == 0:
 
                  ${_('There are no downloads yet')}
 
                %elif c.enable_downloads is False:
 
                  ${_('Downloads are disabled for this repository')}
 
                    %if h.HasPermissionAll('hg.admin')('enable downloads on from summary'):
 
                        ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
 
                    %endif
 
                %else:
 
                    ${h.select('download_options',c.rhodecode_repo.get_changeset().raw_id,c.download_options)}
 
                         <span id="${'zip_link'}">${h.link_to(_('Download as zip'), h.url('files_archive_home',repo_name=c.dbrepo.repo_name,fname='tip.zip'),class_="archive_icon ui-btn")}</span>
 
                    <span style="vertical-align: bottom">
 
                        <input id="archive_subrepos" type="checkbox" name="subrepos" />
 
                        <label for="archive_subrepos" class="tooltip" title="${h.tooltip(_('Check this to download archive with subrepos'))}" >${_('with subrepos')}</label>
 
                    </span>
 
                %endif
 
              </div>
 
             </div>
 
      </div>
 
    </div>
 
</div>
 

	
 
%if c.show_stats:
 
<div class="box box-right"  style="min-height:455px">
 
    <!-- box / title -->
 
    <div class="title">
 
        <h5>${_('Commit activity by day / author')}</h5>
 
    </div>
 

	
 
    <div class="graph">
 
         <div style="padding:0 10px 10px 17px;">
 
         %if c.no_data:
 
           ${c.no_data_msg}
 
           %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
 
                ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
 
           %endif
 
        %else:
 
            ${_('Stats gathered: ')} ${c.stats_percentage}%
 
        %endif
 
        </div>
 
        <div id="commit_history" style="width:450px;height:300px;float:left"></div>
 
        <div style="clear: both;height: 10px"></div>
 
        <div id="overview" style="width:450px;height:100px;float:left"></div>
 

	
 
        <div id="legend_data" style="clear:both;margin-top:10px;">
 
            <div id="legend_container"></div>
 
            <div id="legend_choices">
 
                <table id="legend_choices_tables" class="noborder" style="font-size:smaller;color:#545454"></table>
 
            </div>
 
        </div>
 
    </div>
 
</div>
 
%endif
 

	
 
<div class="box">
 
    <div class="title">
 
        <div class="breadcrumbs">
 
        %if c.repo_changesets:
 
            ${h.link_to(_('Latest changes'),h.url('changelog_home',repo_name=c.repo_name))}
 
        %else:
 
            ${_('Quick start')}
 
         %endif
 
        </div>
 
    </div>
 
    <div class="table">
 
        <div id="shortlog_data">
 
            <%include file='../shortlog/shortlog_data.html'/>
 
        </div>
 
    </div>
 
</div>
 

	
 
%if c.readme_data:
 
<div id="readme" class="anchor">
 
<div class="box" style="background-color: #FAFAFA">
 
    <div class="title" title="${_("Readme file at revision '%s'" % c.rhodecode_db_repo.landing_rev)}">
 
        <div class="breadcrumbs">
 
            <a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a>
 
            <a class="permalink" href="#readme" title="${_('Permalink to this readme')}">&para;</a>
 
        </div>
 
    </div>
 
    <div class="readme">
 
      <div class="readme_box">
 
        ${c.readme_data|n}
 
      </div>
 
    </div>
 
</div>
 
</div>
 
%endif
 

	
 
<script type="text/javascript">
 
var clone_url = 'clone_url';
 
YUE.on(clone_url,'click',function(e){
 
    if(YUD.hasClass(clone_url,'selected')){
 
        return
 
    }
 
    else{
 
        YUD.addClass(clone_url,'selected');
 
        YUD.get(clone_url).select();
 
    }
 
})
 

	
 
YUE.on('clone_by_name','click',function(e){
 
    // show url by name and hide name button
 
    YUD.setStyle('clone_url','display','');
 
    YUD.setStyle('clone_by_name','display','none');
 

	
 
    // hide url by id and show name button
 
    YUD.setStyle('clone_by_id','display','');
 
    YUD.setStyle('clone_url_id','display','none');
 

	
 
})
 
YUE.on('clone_by_id','click',function(e){
 

	
 
    // show url by id and hide id button
 
    YUD.setStyle('clone_by_id','display','none');
 
    YUD.setStyle('clone_url_id','display','');
 

	
 
    // hide url by name and show id button
 
    YUD.setStyle('clone_by_name','display','');
 
    YUD.setStyle('clone_url','display','none');
 
})
 

	
 

	
 
var tmpl_links = {};
 
%for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
 
  tmpl_links["${archive['type']}"] = '${h.link_to('__NAME__', h.url('files_archive_home',repo_name=c.dbrepo.repo_name, fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_='archive_icon ui-btn')}';
 
%endfor
 

	
 
YUE.on(['download_options','archive_subrepos'],'change',function(e){
 
   var sm = YUD.get('download_options');
 
   var new_cs = sm.options[sm.selectedIndex];
 

	
 
   for(k in tmpl_links){
 
       var s = YUD.get(k+'_link');
 
       if(s){
 
         var title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}";
 
         title_tmpl= title_tmpl.replace('__CS_NAME__',new_cs.text);
 
         title_tmpl = title_tmpl.replace('__CS_EXT__',k);
 

	
 
         var url = tmpl_links[k].replace('__CS__',new_cs.value);
 
         var subrepos = YUD.get('archive_subrepos').checked;
 
         url = url.replace('__SUB__',subrepos);
 
         url = url.replace('__NAME__',title_tmpl);
 
         s.innerHTML = url
 
       }
 
   }
 
});
 
</script>
 
%if c.show_stats:
 
<script type="text/javascript">
 
var data = ${c.trending_languages|n};
 
var total = 0;
 
var no_data = true;
 
var tbl = document.createElement('table');
 
tbl.setAttribute('class','trending_language_tbl');
 
var cnt = 0;
 
for (var i=0;i<data.length;i++){
 
    total+= data[i][1].count;
 
}
 
for (var i=0;i<data.length;i++){
 
    cnt += 1;
 
    no_data = false;
 

	
 
    var hide = cnt>2;
 
    var tr = document.createElement('tr');
 
    if (hide){
 
        tr.setAttribute('style','display:none');
 
        tr.setAttribute('class','stats_hidden');
 
    }
 
    var k = data[i][0];
 
    var obj = data[i][1];
 
    var percentage = Math.round((obj.count/total*100),2);
 

	
 
    var td1 = document.createElement('td');
 
    td1.width = 150;
 
    var trending_language_label = document.createElement('div');
 
    trending_language_label.innerHTML = obj.desc+" ("+k+")";
 
    td1.appendChild(trending_language_label);
 

	
 
    var td2 = document.createElement('td');
 
    td2.setAttribute('style','padding-right:14px !important');
 
    var trending_language = document.createElement('div');
 
    var nr_files = obj.count+" ${_('files')}";
 

	
 
    trending_language.title = k+" "+nr_files;
 

	
 
    if (percentage>22){
 
        trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
 
    }
 
    else{
 
        trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
 
    }
 

	
 
    trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
 
    trending_language.style.width=percentage+"%";
 
    td2.appendChild(trending_language);
 

	
 
    tr.appendChild(td1);
 
    tr.appendChild(td2);
 
    tbl.appendChild(tr);
 
    if(cnt == 3){
 
        var show_more = document.createElement('tr');
 
        var td = document.createElement('td');
 
        lnk = document.createElement('a');
 

	
 
        lnk.href='#';
 
        lnk.innerHTML = "${_('show more')}";
 
        lnk.id='code_stats_show_more';
 
        td.appendChild(lnk);
 

	
 
        show_more.appendChild(td);
 
        show_more.appendChild(document.createElement('td'));
 
        tbl.appendChild(show_more);
 
    }
 

	
 
}
 

	
 
YUD.get('lang_stats').appendChild(tbl);
 
YUE.on('code_stats_show_more','click',function(){
 
    l = YUD.getElementsByClassName('stats_hidden')
 
    for (e in l){
 
        YUD.setStyle(l[e],'display','');
 
    };
 
    YUD.setStyle(YUD.get('code_stats_show_more'),
 
            'display','none');
 
});
 
</script>
 
<script type="text/javascript">
 
/**
 
 * Plots summary graph
 
 *
 
 * @class SummaryPlot
 
 * @param {from} initial from for detailed graph
 
 * @param {to} initial to for detailed graph
 
 * @param {dataset}
 
 * @param {overview_dataset}
 
 */
 
function SummaryPlot(from,to,dataset,overview_dataset) {
 
    var initial_ranges = {
 
        "xaxis":{
 
            "from":from,
 
            "to":to,
 
        },
 
    };
 
    var dataset = dataset;
 
    var overview_dataset = [overview_dataset];
 
    var choiceContainer = YUD.get("legend_choices");
 
    var choiceContainerTable = YUD.get("legend_choices_tables");
 
    var plotContainer = YUD.get('commit_history');
 
    var overviewContainer = YUD.get('overview');
 

	
 
    var plot_options = {
 
        bars: {show:true,align:'center',lineWidth:4},
 
        legend: {show:true, container:"legend_container"},
 
        points: {show:true,radius:0,fill:false},
 
        yaxis: {tickDecimals:0,},
 
        xaxis: {
 
            mode: "time",
 
            timeformat: "%d/%m",
 
            min:from,
 
            max:to,
 
        },
 
        grid: {
 
            hoverable: true,
 
            clickable: true,
 
            autoHighlight:true,
 
            color: "#999"
 
        },
 
        //selection: {mode: "x"}
 
    };
 
    var overview_options = {
 
        legend:{show:false},
 
        bars: {show:true,barWidth: 2,},
 
        shadowSize: 0,
 
        xaxis: {mode: "time", timeformat: "%d/%m/%y",},
 
        yaxis: {ticks: 3, min: 0,tickDecimals:0,},
 
        grid: {color: "#999",},
 
        selection: {mode: "x"}
 
    };
 

	
 
    /**
 
    *get dummy data needed in few places
 
    */
 
    function getDummyData(label){
 
        return {"label":label,
 
         "data":[{"time":0,
 
             "commits":0,
 
                 "added":0,
 
                 "changed":0,
 
                 "removed":0,
 
            }],
 
            "schema":["commits"],
 
            "color":'#ffffff',
 
        }
 
    }
 

	
 
    /**
 
     * generate checkboxes accordindly to data
 
     * @param keys
 
     * @returns
 
     */
 
    function generateCheckboxes(data) {
 
        //append checkboxes
 
        var i = 0;
 
        choiceContainerTable.innerHTML = '';
 
        for(var pos in data) {
 

	
 
            data[pos].color = i;
 
            i++;
 
            if(data[pos].label != ''){
 
                choiceContainerTable.innerHTML +=
0 comments (0 inline, 0 general)