Changeset - 65b2f150beb7
[Not reviewed]
default
0 4 4
Marcin Kuzminski - 15 years ago 2010-10-07 17:32:24
marcin@python-works.com
Added searching for file names within the repository in rhodecode
8 files changed with 147 insertions and 48 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/search.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
# search controller for pylons
 
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
 
# 
 
# This program is free software; you can redistribute it and/or
 
# modify it under the terms of the GNU General Public License
 
# as published by the Free Software Foundation; version 2
 
# of the License or (at your opinion) any later version of the license.
 
# 
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
# 
 
# You should have received a copy of the GNU General Public License
 
# along with this program; if not, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 
"""
 
Created on Aug 7, 2010
 
search controller for pylons
 
@author: marcink
 
"""
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from rhodecode.lib.auth import LoginRequired
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.lib.indexers import IDX_LOCATION, SCHEMA, IDX_NAME, ResultWrapper
 
from webhelpers.paginate import Page
 
from webhelpers.util import update_params
 
from pylons.i18n.translation import _
 
from whoosh.index import open_dir, EmptyIndexError
 
from whoosh.qparser import QueryParser, QueryParserError
 
from whoosh.query import Phrase
 
import logging
 
import traceback
 

	
 
log = logging.getLogger(__name__)
 

	
 
class SearchController(BaseController):
 

	
 
    @LoginRequired()
 
    def __before__(self):
 
        super(SearchController, self).__before__()    
 

	
 
    def index(self, search_repo=None):
 
        c.repo_name = search_repo
 
        c.formated_results = []
 
        c.runtime = ''
 
        c.cur_query = request.GET.get('q', None)
 
        c.cur_type = request.GET.get('type', 'source')
 
        c.cur_search = search_type = {'content':'content',
 
                                      'commit':'content',
 
                                      'path':'path',
 
                                      'repository':'repository'}\
 
                                      .get(c.cur_type, 'content')
 

	
 
        
 
        if c.cur_query:
 
            cur_query = c.cur_query.lower()
 
        
 
        if c.cur_query:
 
            p = int(request.params.get('page', 1))
 
            highlight_items = set()
 
            try:
 
                idx = open_dir(IDX_LOCATION, indexname=IDX_NAME)
 
                searcher = idx.searcher()
 

	
 
                qp = QueryParser("content", schema=SCHEMA)
 
                qp = QueryParser(search_type, schema=SCHEMA)
 
                if c.repo_name:
 
                    cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
 
                try:
 
                    query = qp.parse(unicode(cur_query))
 
                    
 
                    if isinstance(query, Phrase):
 
                        highlight_items.update(query.words)
 
                    else:
 
                        for i in query.all_terms():
 
                            if i[0] == 'content':
 
                                highlight_items.add(i[1])
 

	
 
                    matcher = query.matcher(searcher)
 
                    
 
                    log.debug(query)
 
                    log.debug(highlight_items)
 
                    results = searcher.search(query)
 
                    res_ln = len(results)
 
                    c.runtime = '%s results (%.3f seconds)' \
 
                    % (res_ln, results.runtime)
 
                        % (res_ln, results.runtime)
 
                    
 
                    def url_generator(**kw):
 
                        return update_params("?q=%s" % c.cur_query, **kw)
 
                        return update_params("?q=%s&type=%s" \
 
                                           % (c.cur_query, c.cur_search), **kw)
 

	
 
                    c.formated_results = Page(
 
                                ResultWrapper(searcher, matcher, highlight_items),
 
                                ResultWrapper(search_type, searcher, matcher,
 
                                              highlight_items),
 
                                page=p, item_count=res_ln,
 
                                items_per_page=10, url=url_generator)
 
                           
 
                     
 
                    
 
                except QueryParserError:
 
                    c.runtime = _('Invalid search query. Try quoting it.')
 
                searcher.close()
 
            except (EmptyIndexError, IOError):
 
                log.error(traceback.format_exc())
 
                log.error('Empty Index data')
 
                c.runtime = _('There is no index to search in. Please run whoosh indexer')
 
                        
 
        # Return a rendered template
 
        return render('/search/search.html')
rhodecode/lib/indexers/__init__.py
Show inline comments
 
from os.path import dirname as dn, join as jn
 
from rhodecode.config.environment import load_environment
 
from rhodecode.model.hg_model import HgModel
 
from shutil import rmtree
 
from webhelpers.html.builder import escape
 
from vcs.utils.lazy import LazyProperty
 

	
 
from whoosh.analysis import RegexTokenizer, LowercaseFilter, StopFilter
 
from whoosh.fields import TEXT, ID, STORED, Schema, FieldType
 
from whoosh.index import create_in, open_dir
 
from whoosh.formats import Characters
 
from whoosh.highlight import highlight, SimpleFragmenter, HtmlFormatter   
 

	
 
import os
 
import sys
 
import traceback
 

	
 
#to get the rhodecode import
 
sys.path.append(dn(dn(dn(os.path.realpath(__file__)))))
 

	
 

	
 
#LOCATION WE KEEP THE INDEX
 
IDX_LOCATION = jn(dn(dn(dn(dn(os.path.abspath(__file__))))), 'data', 'index')
 

	
 
#EXTENSIONS WE WANT TO INDEX CONTENT OFF
 
INDEX_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
 
                    'cfg', 'cfm', 'cpp', 'cs', 'css', 'diff', 'do', 'el', 'erl',
 
                    'h', 'htm', 'html', 'ini', 'java', 'js', 'jsp', 'jspx', 'lisp',
 
                    'lua', 'm', 'mako', 'ml', 'pas', 'patch', 'php', 'php3',
 
                    'php4', 'phtml', 'pm', 'py', 'rb', 'rst', 's', 'sh', 'sql',
 
                    'tpl', 'txt', 'vim', 'wss', 'xhtml', 'xml', 'xsl', 'xslt',
 
                    'yaws']
 

	
 
#CUSTOM ANALYZER wordsplit + lowercase filter
 
ANALYZER = RegexTokenizer(expression=r"\w+") | LowercaseFilter()
 

	
 

	
 
#INDEX SCHEMA DEFINITION
 
SCHEMA = Schema(owner=TEXT(),
 
                repository=TEXT(stored=True),
 
                path=ID(stored=True, unique=True),
 
                path=TEXT(stored=True),
 
                content=FieldType(format=Characters(ANALYZER),
 
                             scorable=True, stored=True),
 
                modtime=STORED(), extension=TEXT(stored=True))
 

	
 

	
 
IDX_NAME = 'HG_INDEX'
 
FORMATTER = HtmlFormatter('span', between='\n<span class="break">...</span>\n') 
 
FRAGMENTER = SimpleFragmenter(200)
 
                            
 
class ResultWrapper(object):
 
    def __init__(self, searcher, matcher, highlight_items):
 
    def __init__(self, search_type, searcher, matcher, highlight_items):
 
        self.search_type = search_type
 
        self.searcher = searcher
 
        self.matcher = matcher
 
        self.highlight_items = highlight_items
 
        self.fragment_size = 200 / 2
 
    
 
    @LazyProperty
 
    def doc_ids(self):
 
        docs_id = []
 
        while self.matcher.is_active():
 
            docnum = self.matcher.id()
 
            chunks = [offsets for offsets in self.get_chunks()]
 
            docs_id.append([docnum, chunks])
 
            self.matcher.next()
 
        return docs_id   
 
        
 
    def __str__(self):
 
        return '<%s at %s>' % (self.__class__.__name__, len(self.doc_ids))
 

	
 
    def __repr__(self):
 
        return self.__str__()
 

	
 
    def __len__(self):
 
        return len(self.doc_ids)
 

	
 
    def __iter__(self):
 
        """
 
        Allows Iteration over results,and lazy generate content
 

	
 
        *Requires* implementation of ``__getitem__`` method.
 
        """
 
        for docid in self.doc_ids:
 
            yield self.get_full_content(docid)
 

	
 
    def __getslice__(self, i, j):
 
        """
 
        Slicing of resultWrapper
 
        """
 
        slice = []
 
        for docid in self.doc_ids[i:j]:
 
            slice.append(self.get_full_content(docid))
 
        return slice   
 
                            
 

	
 
    def get_full_content(self, docid):
 
        res = self.searcher.stored_fields(docid[0])
 
        f_path = res['path'][res['path'].find(res['repository']) \
 
                             + len(res['repository']):].lstrip('/')
 
        
 
        content_short = self.get_short_content(res, docid[1])
 
        res.update({'content_short':content_short,
 
                    'content_short_hl':self.highlight(content_short),
 
                    'f_path':f_path})
 
        
 
        return res        
 
    
 
    def get_short_content(self, res, chunks):
 
        
 
        return ''.join([res['content'][chunk[0]:chunk[1]] for chunk in chunks])
 
    
 
    def get_chunks(self):
 
        """
 
        Smart function that implements chunking the content
 
        but not overlap chunks so it doesn't highlight the same
 
        close occurences twice.
 
        close occurrences twice.
 
        @param matcher:
 
        @param size:
 
        """
 
        memory = [(0, 0)]
 
        for span in self.matcher.spans():
 
            start = span.startchar or 0
 
            end = span.endchar or 0
 
            start_offseted = max(0, start - self.fragment_size)
 
            end_offseted = end + self.fragment_size
 
            
 
            if start_offseted < memory[-1][1]:
 
                start_offseted = memory[-1][1]
 
            memory.append((start_offseted, end_offseted,))    
 
            yield (start_offseted, end_offseted,)  
 
        
 
    def highlight(self, content, top=5):
 
        if self.search_type != 'content':
 
            return ''
 
        hl = highlight(escape(content),
 
                 self.highlight_items,
 
                 analyzer=ANALYZER,
 
                 fragmenter=FRAGMENTER,
 
                 formatter=FORMATTER,
 
                 top=top)
 
        return hl 
rhodecode/public/css/style.css
Show inline comments
 
@@ -937,768 +937,774 @@ div.options a:hover
 
 
#content div.box-left
 
{
 
	margin: 0 0 10px;
 
	width: 49%;
 
	clear: none;
 
	float: left;	
 
}
 
 
#content div.box-right
 
{
 
	margin: 0 0 10px;
 
	width: 49%;
 
	clear: none;
 
	float: right;	
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> box / title
 
----------------------------------------------------------- */
 
 
#content div.box div.title
 
{
 
	margin: 0 0 20px 0;
 
	padding: 0;
 
	clear: both;
 
	overflow: hidden;
 
	background: #336699 url("../images/colors/blue/title.png") repeat-x;
 
}
 
 
#content div.box div.title h5
 
{
 
	margin: 0;
 
	padding: 11px 0 11px 10px;
 
	float: left;
 
	border: none;
 
	color: #ffffff;
 
	text-transform: uppercase;
 
}
 
 
#content div.box div.title ul.links
 
{
 
	margin: 0;
 
	padding: 0;
 
	float: right;
 
}
 
 
#content div.box div.title ul.links li
 
{
 
	margin: 0;
 
	padding: 0;
 
	list-style: none;
 
	float: left;
 
}
 
 
#content div.box div.title ul.links li a
 
{
 
	margin: 0;
 
	padding: 13px 16px 12px 16px;
 
	height: 1%;
 
	display: block;
 
	float: left;
 
	background: url("../images/colors/blue/title_link.png") no-repeat top left;
 
	border-left: 1px solid #316293;
 
	color: #ffffff;
 
	font-size: 11px;
 
	font-weight: bold;
 
	text-decoration: none;
 
}
 
 
#content div.box div.title ul.links li a:hover
 
{
 
	color: #bfe3ff;
 
}
 
 
#content div.box div.title ul.links li.ui-tabs-selected a
 
{
 
	background: url("../../../resources/images/colors/blue/title_tab_selected.png") no-repeat bottom center;
 
	color: #bfe3ff;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> box / headings
 
----------------------------------------------------------- */
 
 
#content div.box h1,
 
#content div.box h2,
 
#content div.box h3,
 
#content div.box h4,
 
#content div.box h5,
 
#content div.box h6
 
{
 
    margin: 10px 20px 10px 20px;
 
    padding: 0 0 15px 0;
 
    clear: both;
 
    overflow: hidden;
 
    border-bottom: 1px solid #DDDDDD;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> box / paragraphs
 
----------------------------------------------------------- */
 
 
#content div.box p
 
{
 
    margin: 0 24px 10px 24px;
 
    padding: 0;
 
    color: #5f5f5f;
 
    font-size: 12px;
 
    line-height: 150%;
 
}
 
 
#content div.box blockquote
 
{
 
    margin: 0 34px 0 34px;
 
    padding: 0 0 0 14px;
 
    border-left: 4px solid #DDDDDD;
 
    color: #5f5f5f;
 
    font-size: 11px;
 
    line-height: 150%;
 
}
 
 
#content div.box blockquote p
 
{
 
    margin: 10px 0 10px 0;
 
    padding: 0; 
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> box / lists
 
----------------------------------------------------------- */
 
 
#content div.box dl
 
{
 
    margin: 10px 24px 10px 24px;	
 
}
 
 
#content div.box dt
 
{
 
	margin: 0;
 
    font-size: 12px; 
 
}
 
 
#content div.box dd
 
{
 
	margin: 0;
 
	padding: 8px 0 8px 15px;
 
    font-size: 12px; 
 
}
 
 
#content div.box ul.left
 
{
 
    float: left;    
 
}
 
 
#content div.box ol.left
 
{
 
    float: left;    
 
}
 
 
#content div.box li
 
{
 
    padding: 4px 0 4px 0;
 
    font-size: 12px;  
 
}
 
 
#content div.box ol.lower-roman, 
 
#content div.box ol.upper-roman 
 
{
 
    margin: 10px 24px 10px 44px;
 
}
 
 
#content div.box ol.lower-alpha, 
 
#content div.box ol.upper-alpha
 
{
 
    margin: 10px 24px 10px 44px;
 
}
 
 
#content div.box ol.decimal
 
{
 
    margin: 10px 24px 10px 44px;
 
}
 
 
#content div.box ul.disc,
 
#content div.box ul.circle
 
{
 
    margin: 10px 24px 10px 38px;
 
}
 
 
#content div.box ul.square  
 
{
 
    margin: 10px 24px 10px 40px; 
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> box / images
 
----------------------------------------------------------- */
 
 
#content div.box img.left
 
{
 
    margin: 10px 10px 10px 0;
 
	border: none;
 
	float: left;
 
}
 
 
#content div.box img.right
 
{
 
    margin: 10px 0 10px 10px;
 
	border: none;
 
	float: right;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> box / messages
 
----------------------------------------------------------- */ 
 
 
#content div.box div.messages
 
{
 
	margin: 0 20px 0 20px;
 
    padding: 0;
 
	clear: both;
 
	overflow: hidden;
 
}
 
 
#content div.box div.message
 
{
 
	margin: 0 0 0px 0;
 
    padding: 10px 0 10px 0;
 
	clear: both;
 
	overflow: hidden;
 
}
 
 
#content div.box div.message div.image
 
{
 
	margin: 9px 0 0 5px;
 
	padding: 6px;
 
	float: left;
 
}
 
 
#content div.box div.message div.image img
 
{
 
    margin: 0;
 
    vertical-align: middle;
 
}
 
 
#content div.box div.message div.text
 
{
 
    margin: 0;
 
    padding: 9px 6px 9px 6px;
 
    float: left;
 
}
 
 
#content div.box div.message div.dismiss
 
{
 
    margin: 0;
 
    padding: 0;
 
    float: right;
 
}
 
 
#content div.box div.message div.dismiss a
 
{
 
	margin: 15px 14px 0 0;
 
	padding: 0;
 
	height: 16px;
 
	width: 16px;
 
	display: block;
 
	background: url("../images/icons/cross.png") no-repeat;
 
}
 
 
#content div.box div.message div.text h1,
 
#content div.box div.message div.text h2,
 
#content div.box div.message div.text h3,
 
#content div.box div.message div.text h4,
 
#content div.box div.message div.text h5,
 
#content div.box div.message div.text h6
 
{
 
    margin: 0;
 
    padding: 0px;
 
    border: none;
 
}
 
 
#content div.box div.message div.text span
 
{
 
    margin: 0;
 
    padding: 5px 0 0 0;
 
    height: 1%;
 
    display: block;
 
}
 
 
#content div.box div.message-error
 
{
 
    height: 1%;
 
	clear: both;
 
	overflow: hidden;
 
	background: #FBE3E4;
 
    border: 1px solid #FBC2C4;
 
	color: #860006;
 
}
 
 
#content div.box div.message-error h6
 
{
 
	color: #860006;
 
}
 
 
#content div.box div.message-warning
 
{
 
    height: 1%;
 
	clear: both;
 
	overflow: hidden;
 
    background: #FFF6BF;
 
    border: 1px solid #FFD324;
 
    color: #5f5200;
 
}
 
 
#content div.box div.message-warning h6
 
{
 
    color: #5f5200;
 
}
 
 
#content div.box div.message-notice
 
{
 
    height: 1%;
 
	clear: both;
 
	overflow: hidden;
 
    background: #8FBDE0;
 
    border: 1px solid #6BACDE;
 
    color: #003863;
 
}
 
 
#content div.box div.message-notice h6
 
{
 
    color: #003863;
 
}
 
 
#content div.box div.message-success
 
{
 
    height: 1%;
 
	clear: both;
 
	overflow: hidden;
 
    background: #E6EFC2;
 
    border: 1px solid #C6D880;
 
    color: #4e6100;
 
}
 
 
#content div.box div.message-success h6
 
{
 
    color: #4e6100;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> box / forms
 
----------------------------------------------------------- */
 
 
#content div.box div.form
 
{
 
	margin: 0;
 
	padding: 0 20px 10px 20px;
 
    clear: both;
 
    overflow: hidden;
 
}
 
 
#content div.box div.form div.fields
 
{
 
	margin: 0;
 
	padding: 0;
 
    clear: both;
 
    overflow: hidden;
 
}
 
 
#content div.box div.form div.fields div.field
 
{
 
	margin: 0;
 
	padding: 10px 0 10px 0; 
 
	height: 1%;
 
	border-bottom: 1px solid #DDDDDD;
 
	clear: both;
 
	overflow: hidden;
 
}
 
 
#content div.box div.form div.fields div.field-first
 
{
 
	padding: 0 0 10px 0; 
 
}
 
 
#content div.box div.form div.fields div.field-noborder
 
{
 
    border-bottom: 0px !important; 
 
}
 
 
 
#content div.box div.form div.fields div.field span.error-message
 
{
 
	margin: 8px 0 0 0;
 
	padding: 0;
 
	height: 1%;
 
	display: block;
 
	color: #FF0000;
 
}
 
 
#content div.box div.form div.fields div.field span.success
 
{
 
	margin: 8px 0 0 0;
 
	padding: 0;
 
	height: 1%;
 
	display: block;
 
	color: #316309;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> labels
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.label
 
{
 
	left: 310px;
 
	margin: 0;
 
	padding: 8px 0 0 5px;
 
	width: auto;
 
	position: absolute;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label,
 
#content div.box-right div.form div.fields div.field div.label
 
{
 
    left: 0;
 
    margin: 0;
 
    padding: 0 0 8px 0;
 
    width: auto;
 
    position: relative;
 
    clear: both;
 
    overflow: hidden;
 
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> label (select)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.label-select
 
{
 
	padding: 2px 0 0 5px;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label-select,
 
#content div.box-right div.form div.fields div.field div.label-select
 
{
 
	padding: 0 0 8px 0;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> label (checkbox)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.label-checkbox
 
{
 
	padding:0 0 0 5px !important;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> label (radio)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.label-radio
 
{
 
	padding:0 0 0 5px !important;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> label (textarea)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.label-textarea
 
{
 
	padding:0 0 0 5px !important;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label-textarea,
 
#content div.box-right div.form div.fields div.field div.label-textarea
 
{
 
	padding: 0 0 8px 0 !important;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> labels (label)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.label label
 
{
 
    color: #393939;
 
    font-weight: bold;
 
}
 
 
#content div.box div.form div.fields div.field div.label span
 
{
 
	margin: 0;
 
	padding: 2px 0 0 0;
 
	height: 1%;
 
	display: block;
 
	color: #363636;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> input
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.input
 
{
 
	margin: 0 0 0 200px;
 
	padding: 0;
 
}
 
 
#content div.box-left div.form div.fields div.field div.input,
 
#content div.box-right div.form div.fields div.field div.input
 
{
 
    margin: 0;
 
    padding: 7px 7px 6px 7px;
 
    clear: both;
 
    overflow: hidden;
 
    border-top: 1px solid #b3b3b3;
 
    border-left: 1px solid #b3b3b3;
 
    border-right: 1px solid #eaeaea;
 
    border-bottom: 1px solid #eaeaea;
 
 
}
 
 
#content div.box div.form div.fields div.field div.input input
 
{
 
    margin: 0;
 
    padding: 7px 7px 6px 7px;
 
    background: #FFFFFF;
 
    border-top: 1px solid #b3b3b3;
 
    border-left: 1px solid #b3b3b3;
 
    border-right: 1px solid #eaeaea;
 
    border-bottom: 1px solid #eaeaea;
 
    color: #000000;
 
	font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
	font-size: 11px;
 
	float: left;
 
}
 
 
#content div.box-left div.form div.fields div.field div.input input,
 
#content div.box-right div.form div.fields div.field div.input input
 
{
 
	width: 100%;
 
    padding: 0;
 
    border: none;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.small
 
{
 
	width: 30%;	
 
}
 
 
#content div.box div.form div.fields div.field div.input input.medium
 
{
 
	width: 55%;	
 
}
 
 
#content div.box div.form div.fields div.field div.input input.large
 
{
 
	width: 85%;	
 
}
 
 
#content div.box div.form div.fields div.field div.input input.date
 
{
 
	width: 177px;	
 
}
 
 
#content div.box div.form div.fields div.field div.input input.button
 
{
 
    margin: 0;
 
    padding: 4px 8px 4px 8px;
 
    background: #D4D0C8;
 
    border-top: 1px solid #FFFFFF;
 
    border-left: 1px solid #FFFFFF;
 
    border-right: 1px solid #404040;
 
    border-bottom: 1px solid #404040;
 
    color: #000000;
 
}
 
 
#content div.box 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
 
{
 
	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 div.form div.fields div.field div.input img.ui-datepicker-trigger
 
{
 
    margin: 0 0 0 6px;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> input (file styling)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.input a.ui-input-file
 
{
 
    margin: 0 0 0 6px;
 
    padding: 0;
 
    width: 28px;
 
    height: 28px;
 
    display: inline;
 
    position: absolute;
 
    overflow: hidden;
 
    cursor: pointer;
 
    background: #e5e3e3 url("../images/button_browse.png") no-repeat;
 
    border: none;
 
    text-decoration: none;
 
}
 
 
#content div.box div.form div.fields div.field div.input a:hover.ui-input-file
 
{
 
    background: #e5e3e3 url("../images/button_browse_selected.png") no-repeat;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> textarea
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.textarea
 
{
 
	margin: 0 0 0 200px;
 
	padding: 10px;
 
    border-top: 1px solid #b3b3b3;
 
    border-left: 1px solid #b3b3b3;
 
    border-right: 1px solid #eaeaea;
 
    border-bottom: 1px solid #eaeaea;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea-editor
 
{
 
	padding: 0;
 
    border: 1px solid #dddddd;
 
}
 
 
#content div.box-left div.form div.fields div.field div.textarea,
 
#content div.box-right div.form div.fields div.field div.textarea
 
{
 
	margin: 0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea textarea
 
{
 
    margin: 0;
 
    padding: 0;
 
	width: 100%;
 
	height: 220px;
 
	overflow: hidden;
 
    background: #FFFFFF;
 
	border-width: 0;
 
    color: #000000;
 
	font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
	font-size: 11px;
 
    outline: none;
 
}
 
 
#content div.box-left div.form div.fields div.field div.textarea textarea,
 
#content div.box-right div.form div.fields div.field div.textarea textarea
 
{
 
	width: 100%;
 
	height: 100px;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea textarea.error
 
{
 
    padding: 3px 10px 10px 23px;
 
	background-color: #FBE3E4;
 
	background-image: url("../../../resources/images/icons/exclamation.png");
 
	background-repeat: no-repeat;
 
	background-position: 3px 3px;
 
    border: 1px solid #FBC2C4;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea textarea.success
 
{
 
    padding: 3px 10px 10px 23px;
 
	background-color: #E6EFC2;
 
	background-image: url("../../../resources/images/icons/accept.png");
 
	background-repeat: no-repeat;
 
	background-position: 3px 3px;
 
    border: 1px solid #C6D880;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> textarea (tinymce editor)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.textarea table
 
{
 
	margin: 0;
 
	padding: 0;
 
	width: 100%;
 
	border: none;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td
 
{
 
	padding: 0;
 
	background: #DDDDDD;
 
	border: none;	
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td table
 
{
 
	margin: 0;
 
	padding: 0;
 
	width: auto;
 
	border: none;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td table td
 
{
 
	padding: 5px 5px 5px 0;
 
	font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
	font-size: 11px;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td table td a
 
{
 
	border: none;	
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive
 
{
 
	background: #b1b1b1;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> select
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.select
 
{
 
	margin: 0 0 0 200px;
 
	padding: 0;
 
}
 
 
#content div.box div.form div.fields div.field div.select a:hover
 
{
 
    color: #000000;
 
    text-decoration: none;
 
}
 
 
#content div.box div.form div.fields div.field div.select select
 
{
 
    margin: 0;
 
}
 
 
/* -----------------------------------------------------------
 
	content -> right -> forms -> select (jquery styling)
 
----------------------------------------------------------- */
 
 
#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus
 
{
 
	border: 1px solid #666666;
 
}
 
 
#content div.box div.form div.fields div.field div.select a.ui-selectmenu  
 
{
 
    color: #565656; 
 
    text-decoration: none;
 
}
 
@@ -2930,768 +2936,798 @@ div.form div.fields div.buttons input
 
    font-weight: bold;
 
}
 
 
#register div.form div.fields div.buttons
 
{
 
	margin: 0;
 
	padding: 10px 0 0 114px;
 
	clear: both;
 
	overflow: hidden;
 
	border-top: 1px solid #DDDDDD;
 
	text-align: left;
 
}
 
 
#register div.form div.fields div.buttons input
 
{
 
	margin: 0;
 
    color: #000000;
 
	font-size: 1.0em; 
 
    font-weight: bold;
 
	font-family: Verdana, Helvetica, Sans-Serif; 
 
}
 
 
#register div.form div.fields div.buttons input.ui-state-default
 
{
 
    margin: 0;
 
    padding: 6px 12px 6px 12px;
 
    background: #e5e3e3 url("../images/button.png") repeat-x;
 
    border-top: 1px solid #DDDDDD;
 
    border-left: 1px solid #c6c6c6;
 
    border-right: 1px solid #DDDDDD;
 
    border-bottom: 1px solid #c6c6c6;
 
    color: #515151;
 
}
 
#register div.form div.fields div.buttons div.highlight input.ui-state-default
 
{
 
	background:url("../images/colors/blue/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
 
	border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
 
	border-style:solid;
 
	border-width:1px;
 
	color:#FFFFFF;
 
}
 
 
 
 
#register div.form div.fields div.buttons input.ui-state-hover
 
{
 
    margin: 0;
 
    padding: 6px 12px 6px 12px;
 
    background: #b4b4b4 url("../images/button_selected.png") repeat-x;
 
    border-top: 1px solid #cccccc;
 
    border-left: 1px solid #bebebe;
 
    border-right: 1px solid #b1b1b1;
 
    border-bottom: 1px solid #afafaf;
 
    color: #515151;
 
}
 
 
#register div.form div.activation_msg {
 
	padding-top:4px;
 
	padding-bottom:4px;
 
	
 
}
 
 
/* -----------------------------------------------------------
 
	SUMMARY
 
----------------------------------------------------------- */
 
.trending_language_tbl, .trending_language_tbl td {
 
	margin:  0px !important;
 
	padding: 0px !important;
 
	border: 0 !important;
 
 
}
 
.trending_language{
 
	-moz-border-radius-bottomright:4px;
 
	-moz-border-radius-topright:4px;
 
	border-bottom-right-radius: 4px 4px;
 
	border-top-right-radius: 4px 4px;
 
	background-color:#336699;
 
	color:#FFFFFF;
 
	display:block;
 
	min-width:20px;
 
	max-width:400px;
 
	padding:3px;
 
	text-decoration:none;
 
	height: 12px;
 
	margin-bottom: 4px;
 
	margin-left: 5px;
 
	white-space: pre;
 
}
 
 
#clone_url{
 
	border: none;
 
}
 
/* -----------------------------------------------------------
 
    FILES
 
----------------------------------------------------------- */
 
 
h3.files_location{
 
    font-size: 1.8em;
 
    font-weight: bold;
 
    margin: 10px 0 !important;
 
    border-bottom: none !important;
 
}
 
 
#files_data.dl{
 
 
 
}
 
#files_data dl dt{
 
    float:left;
 
    margin:0 !important;
 
    padding:5px;
 
    width:115px;
 
}
 
#files_data dl dd{
 
    margin:0 !important;
 
    padding: 5px !important;
 
}
 
 
 
/* -----------------------------------------------------------
 
	CHANGESETS
 
----------------------------------------------------------- */
 
#changeset_content {
 
	border:1px solid #CCCCCC;
 
	padding:5px;
 
}
 
 
#changeset_content .container .wrapper {
 
	width: 600px;
 
}
 
 
#changeset_content .container {
 
	min-height: 120px;
 
	font-size: 1.2em;
 
	overflow: hidden;
 
}
 
 
#changeset_content .container .left {
 
	float: left;
 
	width: 70%;
 
	padding-left: 5px;
 
}
 
 
#changeset_content .container .right {
 
	float: right;
 
	width: 25%;
 
	text-align: right;
 
}
 
 
#changeset_content .container .left .date {
 
	font-weight: bold;
 
}
 
 
#changeset_content .container .left .author {
 
	
 
}
 
 
#changeset_content .container .left .message {
 
	font-style: italic;
 
	color: #556CB5;
 
	white-space: pre-wrap;
 
}
 
 
.cs_files {
 
 
}
 
 
.cs_files .cs_added {
 
	background: url("/images/icons/page_white_add.png") no-repeat scroll 3px;
 
	/*background-color:#BBFFBB;*/
 
	height: 16px;
 
	padding-left: 20px;
 
	margin-top: 7px;
 
	text-align: left;
 
}
 
 
.cs_files .cs_changed {
 
	background: url("/images/icons/page_white_edit.png") no-repeat scroll
 
		3px;
 
	/*background-color: #FFDD88;*/
 
	height: 16px;
 
	padding-left: 20px;
 
	margin-top: 7px;
 
	text-align: left;
 
}
 
 
.cs_files .cs_removed {
 
	background: url("/images/icons/page_white_delete.png") no-repeat scroll
 
		3px;
 
	/*background-color: #FF8888;*/
 
	height: 16px;
 
	padding-left: 20px;
 
	margin-top: 7px;
 
	text-align: left;
 
}
 
 
/* -----------------------------------------------------------
 
	CHANGESETS - CANVAS
 
----------------------------------------------------------- */
 
 
#graph {
 
	overflow: hidden;
 
}
 
 
#graph_nodes {
 
	width: 160px;
 
	float: left;
 
	margin-left:-50px;
 
	margin-top: 5px;
 
}
 
 
#graph_content {
 
	width: 800px;
 
	float: left;
 
}
 
 
#graph_content .container_header {
 
	border: 1px solid #CCCCCC;
 
	padding:10px;
 
}
 
 
#graph_content .container .wrapper {
 
	width: 600px;
 
}
 
 
#graph_content .container {
 
	border-bottom: 1px solid #CCCCCC;
 
	border-left: 1px solid #CCCCCC;
 
	border-right: 1px solid #CCCCCC;
 
	min-height: 80px;
 
	overflow: hidden;
 
	font-size:1.2em;	
 
}
 
 
#graph_content .container .left {
 
	float: left;
 
	width: 70%;
 
	padding-left: 5px;
 
}
 
 
#graph_content .container .right {
 
	float: right;
 
	width: 28%;
 
	text-align: right;
 
	padding-bottom: 5px;
 
}
 
 
#graph_content .container .left .date {
 
	font-weight: bold;
 
	padding-bottom:5px;
 
}
 
 
#graph_content .container .left .author {
 
	
 
}
 
 
#graph_content .container .left .message {
 
	font-size: 100%;
 
	padding-top: 3px;
 
	white-space: pre-wrap;
 
}
 
 
.right div {
 
	clear: both;
 
}
 
 
.right .changes .added,.changed,.removed {
 
	border: 1px solid #DDDDDD;
 
	display: block;
 
	float: right;
 
	text-align: center;
 
	min-width: 15px;
 
}
 
 
.right .changes .added {
 
	background: #BBFFBB;
 
}
 
 
.right .changes .changed {
 
	background: #FFDD88;
 
}
 
 
.right .changes .removed {
 
	background: #FF8888;
 
}
 
 
.right .merge {
 
	vertical-align: top;
 
	font-size: 60%;
 
	font-weight: bold;
 
}
 
 
.right .merge img {
 
	vertical-align: bottom;
 
}
 
 
.right .parent {
 
	font-size: 90%;
 
	font-family: monospace;
 
}
 
 
.right .logtags .branchtag{
 
	background: #FFFFFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
 
    display:block;
 
    padding:8px 16px 0px 0px
 
}
 
.right .logtags .tagtag{
 
    background: #FFFFFF url("../images/icons/tag_blue.png") no-repeat right 6px;
 
    display:block;
 
    padding:6px 18px 0px 0px
 
}
 
 
/* -----------------------------------------------------------
 
	FILE BROWSER
 
----------------------------------------------------------- */
 
div.browserblock {
 
	overflow: hidden;
 
	padding: 0px;
 
	border: 1px solid #ccc;
 
	background: #f8f8f8;
 
	font-size: 100%;
 
	line-height: 100%;
 
	/* new */
 
	line-height: 125%;
 
}
 
 
div.browserblock .browser-header {
 
	border-bottom: 1px solid #CCCCCC;
 
	background: #FFFFFF;
 
	color: blue;
 
	padding: 10px 0 10px 0;
 
}
 
 
div.browserblock .browser-header span {
 
	margin-left: 25px;
 
	font-weight: bold;
 
}
 
 
div.browserblock .browser-body {
 
	background: #EEEEEE;
 
}
 
 
table.code-browser {
 
	border-collapse: collapse;
 
	width: 100%;
 
}
 
 
table.code-browser tr {
 
	margin: 3px;
 
}
 
 
table.code-browser thead th {
 
	background-color: #EEEEEE;
 
	height: 20px;
 
	font-size: 1.1em;
 
	font-weight: bold;
 
	text-align: center;
 
	text-align: left;
 
	padding-left: 10px;
 
}
 
 
table.code-browser tbody tr {
 
	
 
}
 
 
table.code-browser tbody td {
 
	padding-left: 10px;
 
	height: 20px;
 
}
 
table.code-browser .browser-file {
 
	background: url("/images/icons/document_16.png") no-repeat scroll 3px;
 
	height: 16px;
 
	padding-left: 20px;
 
	text-align: left;
 
}
 
 
table.code-browser .browser-dir {
 
	background: url("/images/icons/folder_16.png") no-repeat scroll 3px;
 
	height: 16px;
 
	padding-left: 20px;
 
	text-align: left;
 
}
 
 
/* -----------------------------------------------------------
 
    SEARCH
 
----------------------------------------------------------- */
 
 
.box .search {
 
	clear:both;
 
	margin:0;
 
	overflow:hidden;
 
	padding:0 20px 10px;
 
}
 
.box .search div.search_path{
 
    background:none repeat scroll 0 0 #EEEEEE;
 
    border:1px solid #CCCCCC;
 
 
    color:blue;
 
    padding:10px 0;
 
    margin-bottom:10px;
 
}
 
.box .search div.search_path div.link{
 
	font-weight:bold;
 
	margin-left:25px;
 
}
 
.box .search div.search_path div.link a{
 
	color:#0066CC;
 
	cursor:pointer;
 
	text-decoration:none;
 
}
 
 
 
 
/* -----------------------------------------------------------
 
	ADMIN - SETTINGS
 
----------------------------------------------------------- */
 
#path_unlock{
 
	color: red;
 
	font-size: 1.2em;
 
	padding-left: 4px;
 
}
 
 
/* -----------------------------------------------------------
 
    INFOBOX
 
----------------------------------------------------------- */
 
.info_box *{
 
	background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
 
	border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
 
	border-style:solid;
 
	border-width:1px;
 
	color:#4A4A4A;
 
	display:block;
 
	font-weight:bold;
 
	height:1%;
 
	padding:4px 6px;
 
	display: inline;
 
}
 
.info_box span{
 
    margin-left:3px;
 
    margin-right:3px;
 
}
 
.info_box input#at_rev {
 
	padding:5px 3px 3px 2px;
 
	text-align:center;
 
}
 
.info_box input#view {
 
	padding:4px 3px 2px 2px;
 
	text-align:center;
 
}
 
/* -----------------------------------------------------------
 
    YUI TOOLTIP
 
----------------------------------------------------------- */
 
.yui-overlay,.yui-panel-container {
 
    visibility: hidden;
 
    position: absolute;
 
    z-index: 2;
 
}
 
 
.yui-tt {
 
    visibility: hidden;
 
    position: absolute;
 
    color: #666666;
 
    background-color: #FFFFFF;
 
    font-family: arial, helvetica, verdana, sans-serif;
 
    padding: 8px;
 
    border: 2px solid #556CB5;
 
    font: 100% sans-serif;
 
    width: auto;
 
    opacity: 1.0;
 
}
 
 
.yui-tt-shadow {
 
    display: none;
 
}
 
 
/* -----------------------------------------------------------
 
    YUI AUTOCOMPLETE 
 
----------------------------------------------------------- */
 
 
.ac{
 
    vertical-align: top;
 
 
}
 
.ac .match {
 
    font-weight:bold;
 
}
 
 
.ac .yui-ac {
 
    position: relative;
 
    font-family: arial;
 
    font-size: 100%;
 
}
 
 
.ac .perm_ac{
 
    width:15em;
 
}
 
/* styles for input field */
 
.ac .yui-ac-input {
 
    width: 100%;
 
}
 
 
/* styles for results container */
 
.ac .yui-ac-container {
 
    position: absolute;
 
    top: 1.6em;
 
    width: 100%;
 
}
 
 
/* styles for header/body/footer wrapper within container */
 
.ac .yui-ac-content {
 
    position: absolute;
 
    width: 100%;
 
    border: 1px solid #808080;
 
    background: #fff;
 
    overflow: hidden;
 
    z-index: 9050;
 
}
 
 
/* styles for container shadow */
 
.ac .yui-ac-shadow {
 
    position: absolute;
 
    margin: .3em;
 
    width: 100%;
 
    background: #000;
 
    -moz-opacity: 0.10;
 
    opacity: .10;
 
    filter: alpha(opacity = 10);
 
    z-index: 9049;
 
}
 
 
/* styles for results list */
 
.ac .yui-ac-content ul {
 
    margin: 0;
 
    padding: 0;
 
    width: 100%;
 
}
 
 
/* styles for result item */
 
.ac .yui-ac-content li {
 
    margin: 0;
 
    padding: 2px 5px;
 
    cursor: default;
 
    white-space: nowrap;
 
}
 
 
/* styles for prehighlighted result item */
 
.ac .yui-ac-content li.yui-ac-prehighlight {
 
    background: #B3D4FF;
 
}
 
 
/* styles for highlighted result item */
 
.ac .yui-ac-content li.yui-ac-highlight {
 
    background: #556CB5;
 
    color: #FFF;
 
}
 
 
 
/* -----------------------------------------------------------
 
    ACTION ICONS
 
----------------------------------------------------------- */
 
.add_icon {
 
    background: url("/images/icons/add.png") no-repeat scroll 3px ;
 
    height: 16px;
 
    padding-left: 20px;
 
    padding-top: 1px;
 
    text-align: left;
 
}
 
 
.edit_icon {
 
    background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
 
    height: 16px;
 
    padding-left: 20px;
 
    padding-top: 1px;
 
    text-align: left;
 
}
 
 
.delete_icon {
 
    background: url("/images/icons/delete.png") no-repeat scroll 3px;
 
    height: 16px;
 
    padding-left: 20px;
 
    padding-top: 1px;
 
    text-align: left;
 
}
 
 
.rss_icon {
 
    background: url("/images/icons/rss_16.png") no-repeat scroll 3px;
 
    height: 16px;
 
    padding-left: 20px;
 
    padding-top: 1px;
 
    text-align: left;
 
}
 
 
.atom_icon {
 
    background: url("/images/icons/atom.png") no-repeat scroll 3px;
 
    height: 16px;
 
    padding-left: 20px;
 
    padding-top: 1px;
 
    text-align: left;
 
}
 
 
.archive_icon {
 
    background: url("/images/icons/compress.png") no-repeat scroll 3px;
 
    height: 16px;
 
    padding-left: 20px;
 
    text-align: left;
 
    padding-top: 1px;
 
}
 
 
.action_button {
 
    border: 0px;
 
    display: block;
 
    color:#0066CC;
 
}
 
 
.action_button:hover {
 
    border: 0px;
 
    text-decoration:underline;
 
    cursor: pointer;
 
    color:#0066CC;
 
}
 
 
/* -----------------------------------------------------------
 
    REPO SWITCHER
 
----------------------------------------------------------- */
 
 
#switch_repos{
 
	position: absolute;
 
	height: 25px;
 
	z-index: 1;
 
}
 
#switch_repos select{
 
    min-width:150px;
 
    max-height: 250px;
 
    z-index: 1;
 
}
 
/* -----------------------------------------------------------
 
    BREADCRUMBS
 
----------------------------------------------------------- */
 
 
.breadcrumbs{
 
	border:medium none;
 
	color:#FFFFFF;
 
	float:left;
 
	margin:0;
 
	padding:11px 0 11px 10px;
 
	text-transform:uppercase;
 
    font-weight: bold;
 
    font-size: 14px;
 
}
 
.breadcrumbs a{
 
 color: #FFFFFF;
 
}
 
 
 
/* -----------------------------------------------------------
 
    FLASH MSG
 
----------------------------------------------------------- */
 
.flash_msg ul {
 
    margin: 0;
 
    padding: 0px 0px 10px 0px;
 
}
 
 
.error_msg {
 
    background-color: #FFCFCF;
 
    background-image: url("/images/icons/error_msg.png");
 
    border: 1px solid #FF9595;
 
    color: #CC3300;
 
}
 
 
.warning_msg {
 
    background-color: #FFFBCC;
 
    background-image: url("/images/icons/warning_msg.png");
 
    border: 1px solid #FFF35E;
 
    color: #C69E00;
 
}
 
 
.success_msg {
 
    background-color: #D5FFCF;
 
    background-image: url("/images/icons/success_msg.png");
 
    border: 1px solid #97FF88;
 
    color: #009900;
 
}
 
 
.notice_msg {
 
    background-color: #DCE3FF;
 
    background-image: url("/images/icons/notice_msg.png");
 
    border: 1px solid #93A8FF;
 
    color: #556CB5;
 
}
 
 
.success_msg,.error_msg,.notice_msg,.warning_msg {
 
    background-position: 10px center;
 
    background-repeat: no-repeat;
 
    font-size: 12px;
 
    font-weight: bold;
 
    min-height: 14px;
 
    line-height: 14px;
 
    margin-bottom: 0px;
 
    margin-top: 0px;
 
    padding: 6px 10px 6px 40px;
 
    display: block;
 
    overflow: auto;
 
}
 
 
#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;
 
}
 
/* -----------------------------------------------------------
 
	YUI FLOT
 
----------------------------------------------------------- */
 
 
div#commit_history{
 
	float: left;
 
}
 
div#legend_data{
 
	float:left;
 
	
 
}
 
div#legend_container {
 
	float: left;
 
}
 
 
div#legend_container table,div#legend_choices table{
 
	width:auto !important;
 
}
 
 
div#legend_container table td{
 
	border: none !important;
 
	padding: 0px !important;
 
	height: 20px  !important;
 
}
 
 
div#legend_choices table td{
 
	border: none !important;
 
	padding: 0px !important;
 
	height: 20px  !important;
 
}
 
 
div#legend_choices{
 
	float:left;
 
}
 
 
/* -----------------------------------------------------------
 
    PERMISSIONS TABLE
 
----------------------------------------------------------- */
 
table#permissions_manage{
 
    width: 0 !important;
 
 
}
 
table#permissions_manage span.private_repo_msg{
 
    font-size: 0.8em;
 
    opacity:0.6;
 
    
 
}
 
table#permissions_manage td.private_repo_msg{
 
    font-size: 0.8em;
 
    
 
}
 
table#permissions_manage tr#add_perm_input td{
 
    vertical-align:middle;
 
 
}
 
 
/* -----------------------------------------------------------
 
    GRAVATARS
 
----------------------------------------------------------- */
 
div.gravatar{
 
	background-color:white;
 
	border:1px solid #D0D0D0;
 
	float:left;
 
	margin-right:0.7em;
 
	padding: 2px 2px 0px;
 
}
 
 
/* -----------------------------------------------------------
 
    STYLING OF LAYOUT
 
----------------------------------------------------------- */
 
 
 
/* -----------------------------------------------------------
 
    GLOBAL WIDTH
 
----------------------------------------------------------- */
 
#header,#content,#footer{
 
    min-width: 1224px;
 
}
 
 
/* -----------------------------------------------------------
 
    content
 
----------------------------------------------------------- */ 
 
 
#content 
rhodecode/templates/search/search.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 
<%def name="title()">
 
   ${_('Search')} 
 
	%if c.repo_name:
 
		${_('in repository: ') + c.repo_name}
 
	%else:
 
		${_('in all repositories')}		
 
	%endif
 
	:${c.cur_query}
 
</%def>
 
<%def name="breadcrumbs()">
 
	${c.rhodecode_name}
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('home')}
 
</%def>
 
<%def name="main()">
 

	
 
<div class="box">
 
	<!-- box / title -->
 
	<div class="title">
 
		<h5>${_('Search')}
 
		%if c.repo_name:
 
			${_('in repository: ') + c.repo_name}
 
		%else:
 
			${_('in all repositories')}
 
		%endif		
 
		</h5>
 
	</div>
 
	<!-- end box / title -->
 
	%if c.repo_name:
 
		${h.form(h.url('search_repo',search_repo=c.repo_name),method='get')}	
 
	%else:
 
		${h.form(h.url('search'),method='get')}
 
	%endif
 
	<div class="form">
 
		<div class="fields">
 
		
 
			<div class="field ">
 
				<div class="label">
 
					<label for="q">${_('Search')}:</label>
 
			<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>
 
				<div class="button highlight">
 
					<input type="submit" value="${_('Search')}" class="ui-button ui-widget ui-state-default ui-corner-all"/>
 
				</div>
 
				<div class="input">
 
					${h.text('q',c.cur_query,class_="small")}
 
					<div class="button highlight">
 
						<input type="submit" value="${_('Search')}" class="ui-button ui-widget ui-state-default ui-corner-all"/>
 
					</div>		
 
					<div style="font-weight: bold;clear:both;padding: 5px">${c.runtime}</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',_('Source codes')),
 
                        ##('commit',_('Commit messages')),
 
                        ('path',_('File names')),
 
                        ##('repository',_('Repository names')),
 
                        ])} 
 
                </div>
 
             </div>
 
			             
 
		</div>
 
	</div>
 
	${h.end_form()}
 
	
 
	%for cnt,sr in enumerate(c.formated_results):
 
		%if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(sr['repository'],'search results check'):
 
		<div class="table">
 
			<div id="body${cnt}" class="codeblock">
 
				<div class="code-header">
 
					<div class="revision">${h.link_to(h.literal('%s &raquo; %s' % (sr['repository'],sr['f_path'])),
 
					h.url('files_home',repo_name=sr['repository'],revision='tip',f_path=sr['f_path']))}</div>
 
				</div>
 
				<div class="code-body">
 
					<pre>${h.literal(sr['content_short_hl'])}</pre>
 
				</div>
 
			</div>
 
		</div>
 
		%else:
 
			%if cnt == 0:
 
			<div class="table">
 
				<div id="body${cnt}" class="codeblock">
 
					<div class="error">${_('Permission denied')}</div>
 
				</div>
 
			</div>		
 
			%endif
 
			
 
		%endif		
 
	%endfor
 
	%if c.cur_query:
 
	<div class="pagination-wh pagination-left">
 
		${c.formated_results.pager('$link_previous ~2~ $link_next')}
 
	</div>	
 
	%endif
 
    %if c.cur_search == 'content':
 
        <%include file='search_content.html'/>
 
    %elif c.cur_search == 'path':
 
        <%include file='search_path.html'/>
 
    %elif c.cur_search == 'commit':
 
        <%include file='search_commit.html'/>
 
    %elif c.cur_search == 'repository':
 
        <%include file='search_repository.html'/>
 
    %endif                            
 
</div>
 

	
 
</%def>    
rhodecode/templates/search/search_commit.html
Show inline comments
 
new file 100644
rhodecode/templates/search/search_content.html
Show inline comments
 
new file 100644
 
##content highligthing
 

	
 
%for cnt,sr in enumerate(c.formated_results):
 
    %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(sr['repository'],'search results check'):
 
    <div class="table">
 
        <div id="body${cnt}" class="codeblock">
 
            <div class="code-header">
 
                <div class="revision">${h.link_to(h.literal('%s &raquo; %s' % (sr['repository'],sr['f_path'])),
 
                h.url('files_home',repo_name=sr['repository'],revision='tip',f_path=sr['f_path']))}</div>
 
            </div>
 
            <div class="code-body">
 
                <pre>${h.literal(sr['content_short_hl'])}</pre>
 
            </div>
 
        </div>
 
    </div>
 
    %else:
 
        %if cnt == 0:
 
        <div class="table">
 
            <div id="body${cnt}" class="codeblock">
 
                <div class="error">${_('Permission denied')}</div>
 
            </div>
 
        </div>      
 
        %endif
 
        
 
    %endif      
 
%endfor
 
%if c.cur_query and c.formated_results:
 
<div class="pagination-wh pagination-left">
 
    ${c.formated_results.pager('$link_previous ~2~ $link_next')}
 
</div>  
 
%endif
 
\ No newline at end of file
rhodecode/templates/search/search_path.html
Show inline comments
 
new file 100644
 
##path search
 
<div class="search">
 
	%for cnt,sr in enumerate(c.formated_results):
 
	    %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(sr['repository'],'search results check'):
 
		    <div class="search_path">
 
		        <div class="link">
 
		            ${h.link_to(h.literal('%s &raquo; %s' % (sr['repository'],sr['f_path'])),
 
		                h.url('files_home',repo_name=sr['repository'],revision='tip',f_path=sr['f_path']))}        
 
		        </div>
 
		    </div>
 
	    %else:
 
	        %if cnt == 0:
 
			    <div class="error">
 
			        <div class="link">
 
			            ${_('Permission denied')}        
 
			        </div>
 
			    </div>        
 
	        %endif
 
	        
 
	    %endif      
 
	%endfor
 
	%if c.cur_query and c.formated_results:
 
	<div class="pagination-wh pagination-left">
 
	    ${c.formated_results.pager('$link_previous ~2~ $link_next')}
 
	</div>  
 
	%endif
 
</div>
 
\ No newline at end of file
rhodecode/templates/search/search_repository.html
Show inline comments
 
new file 100644
0 comments (0 inline, 0 general)