Mercurial > kallithea
changeset 1776:22333ddd1a40 beta
implements #307, configurable diffs
- global context increase and whitespace
- perfile context and whitespace
- fixed anchor links support
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 11 Dec 2011 00:51:53 +0200 |
parents | fb423ee576e8 |
children | 910e3a0d27c0 |
files | rhodecode/controllers/changeset.py rhodecode/lib/helpers.py rhodecode/public/css/style.css rhodecode/templates/changeset/changeset.html |
diffstat | 4 files changed, 161 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/controllers/changeset.py Sat Dec 10 14:49:12 2011 +0200 +++ b/rhodecode/controllers/changeset.py Sun Dec 11 00:51:53 2011 +0200 @@ -25,12 +25,18 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import logging import traceback +from collections import defaultdict +from webob.exc import HTTPForbidden from pylons import tmpl_context as c, url, request, response from pylons.i18n.translation import _ from pylons.controllers.util import redirect from pylons.decorators import jsonify +from vcs.exceptions import RepositoryError, ChangesetError, \ + ChangesetDoesNotExistError +from vcs.nodes import FileNode + import rhodecode.lib.helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.base import BaseRepoController, render @@ -39,16 +45,109 @@ from rhodecode.lib import diffs from rhodecode.model.db import ChangesetComment from rhodecode.model.comment import ChangesetCommentsModel - -from vcs.exceptions import RepositoryError, ChangesetError, \ - ChangesetDoesNotExistError -from vcs.nodes import FileNode -from webob.exc import HTTPForbidden from rhodecode.model.meta import Session log = logging.getLogger(__name__) +def anchor_url(revision,path): + fid = h.FID(revision, path) + return h.url.current(anchor=fid,**request.GET) + +def get_ignore_ws(fid, GET): + ig_ws_global = request.GET.get('ignorews') + ig_ws = filter(lambda k:k.startswith('WS'),GET.getall(fid)) + if ig_ws: + try: + return int(ig_ws[0].split(':')[-1]) + except: + pass + return ig_ws_global + +def _ignorews_url(fileid=None): + + params = defaultdict(list) + lbl = _('show white space') + ig_ws = get_ignore_ws(fileid, request.GET) + ln_ctx = get_line_ctx(fileid, request.GET) + # global option + if fileid is None: + if ig_ws is None: + params['ignorews'] += [1] + lbl = _('ignore white space') + ctx_key = 'context' + ctx_val = ln_ctx + # per file options + else: + if ig_ws is None: + params[fileid] += ['WS:1'] + lbl = _('ignore white space') + + ctx_key = fileid + ctx_val = 'C:%s' % ln_ctx + # if we have passed in ln_ctx pass it along to our params + if ln_ctx: + params[ctx_key] += [ctx_val] + + params['anchor'] = fileid + return h.link_to(lbl, h.url.current(**params)) + +def get_line_ctx(fid, GET): + ln_ctx_global = request.GET.get('context') + ln_ctx = filter(lambda k:k.startswith('C'),GET.getall(fid)) + + if ln_ctx: + retval = ln_ctx[0].split(':')[-1] + else: + retval = ln_ctx_global + + try: + return int(retval) + except: + return + +def _context_url(fileid=None): + """ + Generates url for context lines + + :param fileid: + """ + ig_ws = get_ignore_ws(fileid, request.GET) + ln_ctx = (get_line_ctx(fileid, request.GET) or 3) * 2 + + params = defaultdict(list) + + # global option + if fileid is None: + if ln_ctx > 0: + params['context'] += [ln_ctx] + + if ig_ws: + ig_ws_key = 'ignorews' + ig_ws_val = 1 + + # per file option + else: + params[fileid] += ['C:%s' % ln_ctx] + ig_ws_key = fileid + ig_ws_val = 'WS:%s' % 1 + + if ig_ws: + params[ig_ws_key] += [ig_ws_val] + + lbl = _('%s line context') % ln_ctx + + params['anchor'] = fileid + return h.link_to(lbl, h.url.current(**params)) + +def wrap_to_table(str_): + return '''<table class="code-difftable"> + <tr class="line"> + <td class="lineno new"></td> + <td class="code"><pre>%s</pre></td> + </tr> + </table>''' % str_ + class ChangesetController(BaseRepoController): @LoginRequired() @@ -59,16 +158,10 @@ c.affected_files_cut_off = 60 def index(self, revision): - ignore_whitespace = request.GET.get('ignorews') == '1' - line_context = request.GET.get('context', 3) - def wrap_to_table(str): - return '''<table class="code-difftable"> - <tr class="line"> - <td class="lineno new"></td> - <td class="code"><pre>%s</pre></td> - </tr> - </table>''' % str + c.anchor_url = anchor_url + c.ignorews_url = _ignorews_url + c.context_url = _context_url #get ranges of revisions if preset rev_range = revision.split('...')[:2] @@ -130,10 +223,13 @@ # added nodes and their size defines how many changes were # made c.sum_added += node.size + fid = h.FID(revision, node.path) + line_context_lcl = get_line_ctx(fid, request.GET) + ignore_whitespace_lcl = get_ignore_ws(fid, request.GET) if c.sum_added < self.cut_off_limit: f_gitdiff = diffs.get_gitdiff(filenode_old, node, - ignore_whitespace=ignore_whitespace, - context=line_context) + ignore_whitespace=ignore_whitespace_lcl, + context=line_context_lcl) d = diffs.DiffProcessor(f_gitdiff, format='gitdiff') st = d.stat() @@ -171,9 +267,12 @@ else: if c.sum_removed < self.cut_off_limit: + fid = h.FID(revision, node.path) + line_context_lcl = get_line_ctx(fid, request.GET) + ignore_whitespace_lcl = get_ignore_ws(fid, request.GET,) f_gitdiff = diffs.get_gitdiff(filenode_old, node, - ignore_whitespace=ignore_whitespace, - context=line_context) + ignore_whitespace=ignore_whitespace_lcl, + context=line_context_lcl) d = diffs.DiffProcessor(f_gitdiff, format='gitdiff') st = d.stat()
--- a/rhodecode/lib/helpers.py Sat Dec 10 14:49:12 2011 +0200 +++ b/rhodecode/lib/helpers.py Sun Dec 11 00:51:53 2011 +0200 @@ -52,6 +52,17 @@ reset = _reset safeid = _make_safe_id_component + +def FID(raw_id,path): + """ + Creates a uniqe ID for filenode based on it's path and revision + + :param raw_id: + :param path: + """ + return 'C-%s-%s' % (short_id(raw_id), safeid(safe_unicode(path))) + + def get_token(): """Return the current authentication token, creating one if one doesn't already exist.
--- a/rhodecode/public/css/style.css Sat Dec 10 14:49:12 2011 +0200 +++ b/rhodecode/public/css/style.css Sun Dec 11 00:51:53 2011 +0200 @@ -1890,7 +1890,9 @@ color: #556CB5; white-space: pre-wrap; } - +#changeset_content .container .left .message a:hover { + text-decoration: none; +} .cs_files .cur_cs { margin: 10px 2px; font-weight: bold; @@ -2254,7 +2256,7 @@ float: left; } -.diffblock .changeset_header .diff-menu{ +.diffblock .diff-menu{ position: absolute; background: none repeat scroll 0 0 #FFFFFF; border-color: #003367 #666666 #666666; @@ -2267,14 +2269,14 @@ } -.diffblock .changeset_header .diff-menu ul li { +.diffblock .diff-menu ul li { padding: 0px 0px 0px 0px !important; } -.diffblock .changeset_header .diff-menu ul li a{ +.diffblock .diff-menu ul li a{ display: block; padding: 3px 8px 3px 8px !important; } -.diffblock .changeset_header .diff-menu ul li a:hover{ +.diffblock .diff-menu ul li a:hover{ text-decoration: none; background-color: #EEEEEE; } @@ -3689,6 +3691,11 @@ border-bottom: 1px solid #CCCCCC; background: #EEEEEE; padding:10px 0 10px 0; + height: 14px; +} +div.diffblock .code-header .date{ + float:left; + text-transform: uppercase; } div.diffblock .code-header div{ margin-left:4px;
--- a/rhodecode/templates/changeset/changeset.html Sat Dec 10 14:49:12 2011 +0200 +++ b/rhodecode/templates/changeset/changeset.html Sun Dec 11 00:51:53 2011 +0200 @@ -18,12 +18,6 @@ ${self.menu('changelog')} </%def> -<%def name="fid(raw_id,path)" filter="strip"> - <% - return 'C-%s-%s' % (h.short_id(raw_id),h.safeid(h.safe_unicode(path))) - %> -</%def> - <%def name="main()"> <div class="box"> <!-- box / title --> @@ -33,19 +27,24 @@ <div class="table"> <div class="diffblock"> <div class="code-header"> - <div> - <span>${h.link_to(_('raw diff'), - h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))}</span> - » <span>${h.link_to(_('download diff'), - h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))}</span> - <div class="comments-number" style="float:right;padding-right:5px">${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})</div> - </div> + <div class="date">${_('commit')} ${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} ${c.changeset.date}</div> + <div class="diff-menu-wrapper"> + <img class="diff-menu-activate" style="cursor: pointer" alt="diff-menu" src="${h.url('/images/icons/script_gear.png')}" /> + <div class="diff-menu" style="display:none"> + <ul> + <li>${h.link_to(_('raw diff'),h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))}</li> + <li>${h.link_to(_('download diff'),h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))}</li> + <li>${c.ignorews_url()}</li> + <li>${c.context_url()}</li> + </ul> + </div> + </div> + <div class="comments-number" style="float:right;padding-right:5px">${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})</div> </div> </div> <div id="changeset_content"> <div class="container"> <div class="left"> - <div class="date">${_('commit')} ${c.changeset.revision}: ${h.short_id(c.changeset.raw_id)}@${c.changeset.date}</div> <div class="author"> <div class="gravatar"> <img alt="gravatar" src="${h.gravatar_url(h.email(c.changeset.author),20)}"/> @@ -100,9 +99,9 @@ <div class="cs_${change}"> <div class="node"> %if change != 'removed': - ${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=self.fid(filenode.changeset.raw_id,filenode.path)))} + ${h.link_to(h.safe_unicode(filenode.path),c.anchor_url(filenode.changeset.raw_id,filenode.path))} %else: - ${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=self.fid('',filenode.path)))} + ${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=h.FID('',filenode.path)))} %endif </div> <div class="changes">${h.fancy_file_stats(stat)}</div> @@ -118,8 +117,8 @@ %for change,filenode,diff,cs1,cs2,stat in c.changes: %if change !='removed': - <div style="clear:both;height:10px"></div> - <div class="diffblock margined comm" id="${self.fid(filenode.changeset.raw_id,filenode.path)}"> + <div id="${h.FID(filenode.changeset.raw_id,filenode.path)}" style="clear:both;height:90px;margin-top:-60px"></div> + <div class="diffblock margined comm"> <div class="code-header"> <div class="changeset_header"> <div class="changeset_file"> @@ -133,13 +132,15 @@ <li>${h.link_to(_('diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='diff'))}</li> <li>${h.link_to(_('raw diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='raw'))}</li> <li>${h.link_to(_('download diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='download'))}</li> + <li>${c.ignorews_url(h.FID(filenode.changeset.raw_id,filenode.path))}</li> + <li>${c.context_url(h.FID(filenode.changeset.raw_id,filenode.path))}</li> </ul> </div> </div> <span style="float:right;margin-top:-3px"> <label> ${_('show inline comments')} - ${h.checkbox('',checked="checked",class_="show-inline-comments",id_for=self.fid(filenode.changeset.raw_id,filenode.path))} + ${h.checkbox('',checked="checked",class_="show-inline-comments",id_for=h.FID(filenode.changeset.raw_id,filenode.path))} </label> </span> </div> @@ -164,7 +165,7 @@ <div class="comments-number">${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})</div> %for path, lines in c.inline_comments: - <div style="display:none" class="inline-comment-placeholder" path="${path}" target_id="${self.fid(c.changeset.raw_id,path)}"> + <div style="display:none" class="inline-comment-placeholder" path="${path}" target_id="${h.FID(c.changeset.raw_id,path)}"> % for line,comments in lines.iteritems(): <div class="inline-comment-placeholder-line" line="${line}" target_id="${h.safeid(h.safe_unicode(path))}"> %for co in comments: