diff --git a/rhodecode/controllers/changeset.py b/rhodecode/controllers/changeset.py --- a/rhodecode/controllers/changeset.py +++ b/rhodecode/controllers/changeset.py @@ -50,13 +50,14 @@ from rhodecode.model.meta import Session log = logging.getLogger(__name__) -def anchor_url(revision,path): +def anchor_url(revision, path): fid = h.FID(revision, path) - return h.url.current(anchor=fid,**request.GET) + 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)) + ig_ws = filter(lambda k: k.startswith('WS'), GET.getall(fid)) if ig_ws: try: return int(ig_ws[0].split(':')[-1]) @@ -64,6 +65,7 @@ def get_ignore_ws(fid, GET): pass return ig_ws_global + def _ignorews_url(fileid=None): params = defaultdict(list) @@ -88,14 +90,15 @@ def _ignorews_url(fileid=None): # 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)) - + ln_ctx = filter(lambda k: k.startswith('C'), GET.getall(fid)) + if ln_ctx: retval = ln_ctx[0].split(':')[-1] else: @@ -106,10 +109,11 @@ def get_line_ctx(fid, GET): except: return + def _context_url(fileid=None): """ Generates url for context lines - + :param fileid: """ ig_ws = get_ignore_ws(fileid, request.GET) @@ -131,7 +135,7 @@ def _context_url(fileid=None): 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] @@ -140,14 +144,16 @@ def _context_url(fileid=None): 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"> + <tr class="line no-comment"> <td class="lineno new"></td> - <td class="code"><pre>%s</pre></td> + <td class="code no-comment"><pre>%s</pre></td> </tr> </table>''' % str_ + class ChangesetController(BaseRepoController): @LoginRequired() @@ -165,9 +171,10 @@ class ChangesetController(BaseRepoContro #get ranges of revisions if preset rev_range = revision.split('...')[:2] - + enable_comments = True try: if len(rev_range) == 2: + enable_comments = False rev_start = rev_range[0] rev_end = rev_range[1] rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start, @@ -233,7 +240,7 @@ class ChangesetController(BaseRepoContro d = diffs.DiffProcessor(f_gitdiff, format='gitdiff') st = d.stat() - diff = d.as_html() + diff = d.as_html(enable_comments=enable_comments) else: diff = wrap_to_table(_('Changeset is to big and ' @@ -281,7 +288,7 @@ class ChangesetController(BaseRepoContro 'and was cut off, see ' 'raw diff instead')) else: - diff = d.as_html() + diff = d.as_html(enable_comments=enable_comments) if diff: c.sum_removed += len(diff) @@ -397,11 +404,10 @@ class ChangesetController(BaseRepoContro @jsonify def delete_comment(self, repo_name, comment_id): co = ChangesetComment.get(comment_id) - owner = lambda : co.author.user_id == c.rhodecode_user.user_id + owner = lambda: co.author.user_id == c.rhodecode_user.user_id if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner: ChangesetCommentsModel().delete(comment=co) Session.commit() return True else: raise HTTPForbidden() - diff --git a/rhodecode/lib/diffs.py b/rhodecode/lib/diffs.py --- a/rhodecode/lib/diffs.py +++ b/rhodecode/lib/diffs.py @@ -114,15 +114,17 @@ class DiffProcessor(object): try: if line1.startswith('--- ') and line2.startswith('+++ '): l1 = line1[4:].split(None, 1) - old_filename = l1[0].lstrip('a/') if len(l1) >= 1 else None + old_filename = (l1[0].replace('a/', '', 1) + if len(l1) >= 1 else None) old_rev = l1[1] if len(l1) == 2 else 'old' l2 = line2[4:].split(None, 1) - new_filename = l2[0].lstrip('b/') if len(l1) >= 1 else None + new_filename = (l2[0].replace('b/', '', 1) + if len(l1) >= 1 else None) new_rev = l2[1] if len(l2) == 2 else 'new' - filename = old_filename if (old_filename != - 'dev/null') else new_filename + filename = (old_filename + if old_filename != '/dev/null' else new_filename) return filename, new_rev, old_rev except (ValueError, IndexError): @@ -359,7 +361,7 @@ class DiffProcessor(object): def as_html(self, table_class='code-difftable', line_class='line', new_lineno_class='lineno old', old_lineno_class='lineno new', - code_class='code'): + code_class='code', enable_comments=False): """ Return udiff as html table with customized css classes """ @@ -429,8 +431,10 @@ class DiffProcessor(object): ########################################################### # CODE ########################################################### - _html.append('''\t<td class="%(code_class)s">''' \ - % {'code_class': code_class}) + comments = '' if enable_comments else 'no-comment' + _html.append('''\t<td class="%(code_class)s %(in-comments)s">''' \ + % {'code_class': code_class, + 'in-comments': comments}) _html.append('''\n\t\t<pre>%(code)s</pre>\n''' \ % {'code': change['line']}) _html.append('''\t</td>''') diff --git a/rhodecode/public/css/style.css b/rhodecode/public/css/style.css --- a/rhodecode/public/css/style.css +++ b/rhodecode/public/css/style.css @@ -3898,17 +3898,19 @@ form.comment-inline-form { text-decoration: none !important; } .notification-header{ - + padding-top:6px; } .notification-header .desc{ font-size: 16px; height: 24px; - padding-top: 6px; float: left } .notification-list .container.unread{ } +.notification-header .gravatar{ + +} .notification-header .desc.unread{ font-weight: bold; font-size: 17px; @@ -4069,4 +4071,10 @@ table.code-difftable .code pre{ background-repeat:no-repeat !important; background-position: right !important; background-position: 0% 50% !important; +} +.diffblock.margined.comm .line .code.no-comment:hover{ + background-image: none !important; + cursor: auto !important; + background-color: inherit !important; + } \ No newline at end of file diff --git a/rhodecode/public/js/rhodecode.js b/rhodecode/public/js/rhodecode.js --- a/rhodecode/public/js/rhodecode.js +++ b/rhodecode/public/js/rhodecode.js @@ -343,7 +343,7 @@ var createInlineForm = function(parent_t return form }; var injectInlineForm = function(tr){ - if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context')){ + if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(tr,'no-comment')){ return } YUD.addClass(tr,'form-open'); diff --git a/rhodecode/templates/changeset/changeset.html b/rhodecode/templates/changeset/changeset.html --- a/rhodecode/templates/changeset/changeset.html +++ b/rhodecode/templates/changeset/changeset.html @@ -114,89 +114,17 @@ </div> </div> - - %for change,filenode,diff,cs1,cs2,stat in c.changes: - %if change !='removed': - <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"> - ${h.link_to_if(change!='removed',h.safe_unicode(filenode.path),h.url('files_home',repo_name=c.repo_name, - revision=filenode.changeset.raw_id,f_path=h.safe_unicode(filenode.path)))} - </div> - <div class="diff-menu-wrapper"> - <img class="diff-menu-activate" style="margin-bottom:-6px;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(_('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=h.FID(filenode.changeset.raw_id,filenode.path))} - </label> - </span> - </div> - </div> - <div class="code-body"> - <div class="full_f_path" path="${filenode.path}"></div> - %if diff: - ${diff|n} - %else: - ${_('No changes in this file')} - %endif - </div> - </div> - %endif - %endfor - + + ## diff block + <%namespace name="diff_block" file="/changeset/diff_block.html"/> + ${diff_block.diff_block(c.changes)} + + ## template for inline comment form <%namespace name="comment" file="/changeset/changeset_file_comment.html"/> - ## template for inline comment form - ${comment.comment_inline_form()} + ${comment.comment_inline_form(c.changeset)} - <div class="comments"> - <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="${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: - ${comment.comment_block(co)} - %endfor - </div> - %endfor - </div> - %endfor - - %for co in c.comments: - ${comment.comment_block(co)} - %endfor - %if c.rhodecode_user.username != 'default': - <div class="comment-form"> - ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=c.changeset.raw_id))} - <strong>${_('Leave a comment')}</strong> - <div class="clearfix"> - <div class="comment-help"> - ${_('Comments parsed using')} <a href="${h.url('rst_help')}">RST</a> ${_('syntax')} - ${_('with')} <span style="color:#003367" class="tooltip" title="${_('Use @username inside this text to send notification to this RhodeCode user')}">@mention</span> ${_('support')} - </div> - ${h.textarea('text')} - </div> - <div class="comment-button"> - ${h.submit('save', _('Comment'), class_='ui-button')} - </div> - ${h.end_form()} - </div> - %endif - </div> + ${comment.comments(c.changeset)} + <script type="text/javascript"> var deleteComment = function(comment_id){ @@ -211,52 +139,52 @@ YUE.onDOMReady(function(){ - YUE.on(YUQ('.diff-menu-activate'),'click',function(e){ + YUE.on(YUQ('.diff-menu-activate'),'click',function(e){ var act = e.currentTarget.nextElementSibling; if(YUD.hasClass(act,'active')){ - YUD.removeClass(act,'active'); - YUD.setStyle(act,'display','none'); + YUD.removeClass(act,'active'); + YUD.setStyle(act,'display','none'); }else{ - YUD.addClass(act,'active'); - YUD.setStyle(act,'display',''); + YUD.addClass(act,'active'); + YUD.setStyle(act,'display',''); } }); - - YUE.on(YUQ('.show-inline-comments'),'change',function(e){ - var show = 'none'; - var target = e.currentTarget; - if(target.checked){ - var show = '' - } - var boxid = YUD.getAttribute(target,'id_for'); - var comments = YUQ('#{0} .inline-comments'.format(boxid)); - for(c in comments){ - YUD.setStyle(comments[c],'display',show); - } - var btns = YUQ('#{0} .inline-comments-button'.format(boxid)); + + YUE.on(YUQ('.show-inline-comments'),'change',function(e){ + var show = 'none'; + var target = e.currentTarget; + if(target.checked){ + var show = '' + } + var boxid = YUD.getAttribute(target,'id_for'); + var comments = YUQ('#{0} .inline-comments'.format(boxid)); + for(c in comments){ + YUD.setStyle(comments[c],'display',show); + } + var btns = YUQ('#{0} .inline-comments-button'.format(boxid)); for(c in btns){ YUD.setStyle(btns[c],'display',show); - } - }) + } + }) YUE.on(YUQ('.line'),'click',function(e){ - var tr = e.currentTarget; - injectInlineForm(tr); + var tr = e.currentTarget; + injectInlineForm(tr); }); // inject comments into they proper positions var file_comments = YUQ('.inline-comment-placeholder'); for (f in file_comments){ - var box = file_comments[f]; - var inlines = box.children; - for(var i=0; i<inlines.length; i++){ - try{ + var box = file_comments[f]; + var inlines = box.children; + for(var i=0; i<inlines.length; i++){ + try{ - var inline = inlines[i]; - var lineno = YUD.getAttribute(inlines[i],'line'); - var lineid = "{0}_{1}".format(YUD.getAttribute(inline,'target_id'),lineno); + var inline = inlines[i]; + var lineno = YUD.getAttribute(inlines[i],'line'); + var lineid = "{0}_{1}".format(YUD.getAttribute(inline,'target_id'),lineno); var target_line = YUD.get(lineid); var add = createInlineAddButton(target_line.parentNode,'${_("add another comment")}'); @@ -264,11 +192,14 @@ var comment = new YAHOO.util.Element(tableTr('inline-comments',inline.innerHTML)) YUD.insertAfter(comment,target_line.parentNode); - }catch(e){} - } + }catch(e){ + console.log(e); + } + } } }) - </script> - </div> + </script> + + </div> </%def> diff --git a/rhodecode/templates/changeset/changeset_file_comment.html b/rhodecode/templates/changeset/changeset_file_comment.html --- a/rhodecode/templates/changeset/changeset_file_comment.html +++ b/rhodecode/templates/changeset/changeset_file_comment.html @@ -1,4 +1,5 @@ -##usage: +## -*- coding: utf-8 -*- +## usage: ## <%namespace name="comment" file="/changeset/changeset_file_comment.html"/> ## ${comment.comment_block(co)} ## @@ -33,12 +34,11 @@ </%def> - -<%def name="comment_inline_form()"> +<%def name="comment_inline_form(changeset)"> <div id='comment-inline-form-template' style="display:none"> <div class="comment-inline-form"> %if c.rhodecode_user.username != 'default': - ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=c.changeset.raw_id))} + ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=changeset.raw_id))} <div class="clearfix"> <div class="comment-help">${_('Commenting on line')} {1}. ${_('Comments parsed using')} <a href="${h.url('rst_help')}">RST</a> ${_('syntax')} ${_('with')} @@ -67,4 +67,45 @@ %endif </div> </div> -</%def> \ No newline at end of file +</%def> + + +<%def name="comments(changeset)"> + +<div class="comments"> + <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="${h.FID(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: + ${comment_block(co)} + %endfor + </div> + %endfor + </div> + %endfor + + %for co in c.comments: + ${comment.comment_block(co)} + %endfor + %if c.rhodecode_user.username != 'default': + <div class="comment-form"> + ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=changeset.raw_id))} + <strong>${_('Leave a comment')}</strong> + <div class="clearfix"> + <div class="comment-help"> + ${_('Comments parsed using')} <a href="${h.url('rst_help')}">RST</a> ${_('syntax')} + ${_('with')} <span style="color:#003367" class="tooltip" title="${_('Use @username inside this text to send notification to this RhodeCode user')}">@mention</span> ${_('support')} + </div> + ${h.textarea('text')} + </div> + <div class="comment-button"> + ${h.submit('save', _('Comment'), class_='ui-button')} + </div> + ${h.end_form()} + </div> + %endif +</div> +</%def> diff --git a/rhodecode/templates/changeset/changeset_range.html b/rhodecode/templates/changeset/changeset_range.html --- a/rhodecode/templates/changeset/changeset_range.html +++ b/rhodecode/templates/changeset/changeset_range.html @@ -1,3 +1,4 @@ +## -*- coding: utf-8 -*- <%inherit file="/base/base.html"/> <%def name="title()"> @@ -24,8 +25,8 @@ </div> <div class="table"> <div id="body" class="diffblock"> - <div class="code-header"> - <h3>${_('Compare View')}</h3> + <div class="code-header cv"> + <h3 class="code-header-title">${_('Compare View')}</h3> <div> ${_('Changesets')} - r${c.cs_ranges[0].revision}:${h.short_id(c.cs_ranges[0].raw_id)} -> r${c.cs_ranges[-1].revision}:${h.short_id(c.cs_ranges[-1].raw_id)} </div> @@ -57,37 +58,32 @@ </div> </div> - %for cs in c.cs_ranges: - %for change,filenode,diff,cs1,cs2,st in c.changes[cs.raw_id]: - %if change !='removed': - <div style="clear:both;height:10px"></div> - <div class="diffblock margined"> - <div id="${h.FID(cs.raw_id,filenode.path)}" class="code-header"> - <div class="changeset_header"> - <span class="changeset_file"> - ${h.link_to_if(change!='removed',h.safe_unicode(filenode.path),h.url('files_home',repo_name=c.repo_name, - revision=filenode.changeset.raw_id,f_path=h.safe_unicode(filenode.path)))} - </span> - %if 1: - » <span>${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'))}</span> - » <span>${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'))}</span> - » <span>${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'))}</span> - %endif - </div> - </div> - <div class="code-body"> - %if diff: - ${diff|n} - %else: - ${_('No changes in this file')} - %endif - </div> - </div> - %endif - %endfor - %endfor + <%namespace name="comment" file="/changeset/changeset_file_comment.html"/> + <%namespace name="diff_block" file="/changeset/diff_block.html"/> + %for cs in c.cs_ranges: + ##${comment.comment_inline_form(cs)} + ## diff block + <h3 style="border:none;padding-top:8px;">${'r%s:%s' % (cs.revision,h.short_id(cs.raw_id))}</h3> + ${diff_block.diff_block(c.changes[cs.raw_id])} + ##${comment.comments(cs)} + + %endfor + <script type="text/javascript"> + + YUE.onDOMReady(function(){ + + YUE.on(YUQ('.diff-menu-activate'),'click',function(e){ + var act = e.currentTarget.nextElementSibling; + + if(YUD.hasClass(act,'active')){ + YUD.removeClass(act,'active'); + YUD.setStyle(act,'display','none'); + }else{ + YUD.addClass(act,'active'); + YUD.setStyle(act,'display',''); + } + }); + }) + </script> </div> </%def> \ No newline at end of file diff --git a/rhodecode/templates/changeset/diff_block.html b/rhodecode/templates/changeset/diff_block.html new file mode 100644 --- /dev/null +++ b/rhodecode/templates/changeset/diff_block.html @@ -0,0 +1,50 @@ +## -*- coding: utf-8 -*- +##usage: +## <%namespace name="diff_block" file="/changeset/diff_block.html"/> +## ${diff_block.diff_block(changes)} +## +<%def name="diff_block(changes)"> + +%for change,filenode,diff,cs1,cs2,stat in changes: + %if change !='removed': + <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"> + ${h.link_to_if(change!='removed',h.safe_unicode(filenode.path),h.url('files_home',repo_name=c.repo_name, + revision=filenode.changeset.raw_id,f_path=h.safe_unicode(filenode.path)))} + </div> + <div class="diff-menu-wrapper"> + <img class="diff-menu-activate" style="margin-bottom:-6px;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(_('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=h.FID(filenode.changeset.raw_id,filenode.path))} + </label> + </span> + </div> + </div> + <div class="code-body"> + <div class="full_f_path" path="${h.safe_unicode(filenode.path)}"></div> + %if diff: + ${diff|n} + %else: + ${_('No changes in this file')} + %endif + </div> + </div> + %endif +%endfor + +</%def> \ No newline at end of file