##// END OF EJS Templates
pull-requests: also expose universal url as singular form.
pull-requests: also expose universal url as singular form.

File last commit:

r1194:f606ad60 default
r1195:d9fbfd45 default
Show More
diffs.html
577 lines | 22.4 KiB | text/html | HtmlLexer
<%def name="diff_line_anchor(filename, line, type)"><%
return '%s_%s_%i' % (h.safeid(filename), type, line)
%></%def>
<%def name="action_class(action)"><%
return {
'-': 'cb-deletion',
'+': 'cb-addition',
' ': 'cb-context',
}.get(action, 'cb-empty')
%></%def>
<%def name="op_class(op_id)"><%
return {
DEL_FILENODE: 'deletion', # file deleted
BIN_FILENODE: 'warning' # binary diff hidden
}.get(op_id, 'addition')
%></%def>
<%def name="link_for(**kw)"><%
new_args = request.GET.mixed()
new_args.update(kw)
return h.url('', **new_args)
%></%def>
<%def name="render_diffset(diffset, commit=None,
# collapse all file diff entries when there are more than this amount of files in the diff
collapse_when_files_over=20,
# collapse lines in the diff when more than this amount of lines changed in the file diff
lines_changed_limit=500,
# add a ruler at to the output
ruler_at_chars=0,
# show inline comments
use_comments=False,
# disable new comments
disable_new_comments=False,
)">
%if use_comments:
<div id="cb-comments-inline-container-template" class="js-template">
${inline_comments_container([])}
</div>
<div class="js-template" id="cb-comment-inline-form-template">
<div class="comment-inline-form ac">
%if c.rhodecode_user.username != h.DEFAULT_USER:
${h.form('#', method='get')}
<div id="edit-container_{1}" class="clearfix">
<div class="comment-title pull-left">
${_('Create a comment on line {1}.')}
</div>
<div class="comment-help pull-right">
${(_('Comments parsed using %s syntax with %s support.') % (
('<a href="%s">%s</a>' % (h.url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())),
('<span class="tooltip" title="%s">@mention</span>' % _('Use @username inside this text to send notification to this RhodeCode user'))
)
)|n
}
</div>
<div style="clear: both"></div>
<textarea id="text_{1}" name="text" class="comment-block-ta ac-input"></textarea>
</div>
<div id="preview-container_{1}" class="clearfix" style="display: none;">
<div class="comment-help">
${_('Comment preview')}
</div>
<div id="preview-box_{1}" class="preview-box"></div>
</div>
<div class="comment-footer">
<div class="action-buttons">
<input type="hidden" name="f_path" value="{0}">
<input type="hidden" name="line" value="{1}">
<button id="preview-btn_{1}" class="btn btn-secondary">${_('Preview')}</button>
<button id="edit-btn_{1}" class="btn btn-secondary" style="display: none;">${_('Edit')}</button>
${h.submit('save', _('Comment'), class_='btn btn-success save-inline-form')}
</div>
<div class="comment-button">
<button type="button" class="cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
${_('Cancel')}
</button>
</div>
${h.end_form()}
</div>
%else:
${h.form('', class_='inline-form comment-form-login', method='get')}
<div class="pull-left">
<div class="comment-help pull-right">
${_('You need to be logged in to comment.')} <a href="${h.route_path('login', _query={'came_from': h.url.current()})}">${_('Login now')}</a>
</div>
</div>
<div class="comment-button pull-right">
<button type="button" class="cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
${_('Cancel')}
</button>
</div>
<div class="clearfix"></div>
${h.end_form()}
%endif
</div>
</div>
%endif
<%
collapse_all = len(diffset.files) > collapse_when_files_over
%>
%if c.diffmode == 'sideside':
<style>
.wrapper {
max-width: 1600px !important;
}
</style>
%endif
%if ruler_at_chars:
<style>
.diff table.cb .cb-content:after {
content: "";
border-left: 1px solid blue;
position: absolute;
top: 0;
height: 18px;
opacity: .2;
z-index: 10;
## +5 to account for diff action (+/-)
left: ${ruler_at_chars + 5}ch;
</style>
%endif
<div class="diffset ${disable_new_comments and 'diffset-comments-disabled'}">
<div class="diffset-heading ${diffset.limited_diff and 'diffset-heading-warning' or ''}">
%if commit:
<div class="pull-right">
<a class="btn tooltip" title="${_('Browse Files at revision {}').format(commit.raw_id)}" href="${h.url('files_home',repo_name=diffset.repo_name, revision=commit.raw_id, f_path='')}">
${_('Browse Files')}
</a>
</div>
%endif
<h2 class="clearinner">
%if commit:
<a class="tooltip revision" title="${h.tooltip(commit.message)}" href="${h.url('changeset_home',repo_name=c.repo_name,revision=commit.raw_id)}">${'r%s:%s' % (commit.revision,h.short_id(commit.raw_id))}</a> -
${h.age_component(commit.date)} -
%endif
%if diffset.limited_diff:
${_('The requested commit is too big and content was truncated.')}
${ungettext('%(num)s file changed.', '%(num)s files changed.', diffset.changed_files) % {'num': diffset.changed_files}}
<a href="${link_for(fulldiff=1)}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a>
%else:
${ungettext('%(num)s file changed: %(linesadd)s inserted, ''%(linesdel)s deleted',
'%(num)s files changed: %(linesadd)s inserted, %(linesdel)s deleted', diffset.changed_files) % {'num': diffset.changed_files, 'linesadd': diffset.lines_added, 'linesdel': diffset.lines_deleted}}
%endif
</h2>
</div>
%if not diffset.files:
<p class="empty_data">${_('No files')}</p>
%endif
<div class="filediffs">
%for i, filediff in enumerate(diffset.files):
<%
lines_changed = filediff['patch']['stats']['added'] + filediff['patch']['stats']['deleted']
over_lines_changed_limit = lines_changed > lines_changed_limit
%>
<input ${collapse_all and 'checked' or ''} class="filediff-collapse-state" id="filediff-collapse-${id(filediff)}" type="checkbox">
<div
class="filediff"
data-f-path="${filediff['patch']['filename']}"
id="a_${h.FID('', filediff['patch']['filename'])}">
<label for="filediff-collapse-${id(filediff)}" class="filediff-heading">
<div class="filediff-collapse-indicator"></div>
${diff_ops(filediff)}
</label>
${diff_menu(filediff, use_comments=use_comments)}
<table class="cb cb-diff-${c.diffmode} code-highlight ${over_lines_changed_limit and 'cb-collapsed' or ''}">
%if not filediff.hunks:
%for op_id, op_text in filediff['patch']['stats']['ops'].items():
<tr>
<td class="cb-text cb-${op_class(op_id)}" ${c.diffmode == 'unified' and 'colspan=3' or 'colspan=4'}>
%if op_id == DEL_FILENODE:
${_('File was deleted')}
%elif op_id == BIN_FILENODE:
${_('Binary file hidden')}
%else:
${op_text}
%endif
</td>
</tr>
%endfor
%endif
%if over_lines_changed_limit:
<tr class="cb-warning cb-collapser">
<td class="cb-text" ${c.diffmode == 'unified' and 'colspan=4' or 'colspan=6'}>
${_('This diff has been collapsed as it changes many lines, (%i lines changed)' % lines_changed)}
<a href="#" class="cb-expand"
onclick="$(this).closest('table').removeClass('cb-collapsed'); return false;">${_('Show them')}
</a>
<a href="#" class="cb-collapse"
onclick="$(this).closest('table').addClass('cb-collapsed'); return false;">${_('Hide them')}
</a>
</td>
</tr>
%endif
%if filediff.patch['is_limited_diff']:
<tr class="cb-warning cb-collapser">
<td class="cb-text" ${c.diffmode == 'unified' and 'colspan=4' or 'colspan=6'}>
${_('The requested commit is too big and content was truncated.')} <a href="${link_for(fulldiff=1)}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a>
</td>
</tr>
%endif
%for hunk in filediff.hunks:
<tr class="cb-hunk">
<td ${c.diffmode == 'unified' and 'colspan=3' or ''}>
## TODO: dan: add ajax loading of more context here
## <a href="#">
<i class="icon-more"></i>
## </a>
</td>
<td ${c.diffmode == 'sideside' and 'colspan=5' or ''}>
@@
-${hunk.source_start},${hunk.source_length}
+${hunk.target_start},${hunk.target_length}
${hunk.section_header}
</td>
</tr>
%if c.diffmode == 'unified':
${render_hunk_lines_unified(hunk, use_comments=use_comments)}
%elif c.diffmode == 'sideside':
${render_hunk_lines_sideside(hunk, use_comments=use_comments)}
%else:
<tr class="cb-line">
<td>unknown diff mode</td>
</tr>
%endif
%endfor
</table>
</div>
%endfor
</div>
</div>
</%def>
<%def name="diff_ops(filediff)">
<%
stats = filediff['patch']['stats']
from rhodecode.lib.diffs import NEW_FILENODE, DEL_FILENODE, \
MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE
%>
<span class="pill">
%if filediff.source_file_path and filediff.target_file_path:
%if filediff.source_file_path != filediff.target_file_path: # file was renamed
<strong>${filediff.target_file_path}</strong> ⬅ <del>${filediff.source_file_path}</del>
%else:
## file was modified
<strong>${filediff.source_file_path}</strong>
%endif
%else:
%if filediff.source_file_path:
## file was deleted
<strong>${filediff.source_file_path}</strong>
%else:
## file was added
<strong>${filediff.target_file_path}</strong>
%endif
%endif
</span>
<span class="pill-group" style="float: left">
%if filediff.patch['is_limited_diff']:
<span class="pill tooltip" op="limited" title="The stats for this diff are not complete">limited diff</span>
%endif
%if RENAMED_FILENODE in stats['ops']:
<span class="pill" op="renamed">renamed</span>
%endif
%if NEW_FILENODE in stats['ops']:
<span class="pill" op="created">created</span>
%if filediff['target_mode'].startswith('120'):
<span class="pill" op="symlink">symlink</span>
%else:
<span class="pill" op="mode">${nice_mode(filediff['target_mode'])}</span>
%endif
%endif
%if DEL_FILENODE in stats['ops']:
<span class="pill" op="removed">removed</span>
%endif
%if CHMOD_FILENODE in stats['ops']:
<span class="pill" op="mode">
${nice_mode(filediff['source_mode'])} âž¡ ${nice_mode(filediff['target_mode'])}
</span>
%endif
</span>
<a class="pill filediff-anchor" href="#a_${h.FID('', filediff.patch['filename'])}">¶</a>
<span class="pill-group" style="float: right">
%if BIN_FILENODE in stats['ops']:
<span class="pill" op="binary">binary</span>
%if MOD_FILENODE in stats['ops']:
<span class="pill" op="modified">modified</span>
%endif
%endif
%if stats['added']:
<span class="pill" op="added">+${stats['added']}</span>
%endif
%if stats['deleted']:
<span class="pill" op="deleted">-${stats['deleted']}</span>
%endif
</span>
</%def>
<%def name="nice_mode(filemode)">
${filemode.startswith('100') and filemode[3:] or filemode}
</%def>
<%def name="diff_menu(filediff, use_comments=False)">
<div class="filediff-menu">
%if filediff.diffset.source_ref:
%if filediff.patch['operation'] in ['D', 'M']:
<a
class="tooltip"
href="${h.url('files_home',repo_name=filediff.diffset.repo_name,f_path=filediff.source_file_path,revision=filediff.diffset.source_ref)}"
title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
>
${_('Show file before')}
</a>
%else:
<span
class="tooltip"
title="${h.tooltip(_('File no longer present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
>
${_('Show file before')}
</span>
%endif
%if filediff.patch['operation'] in ['A', 'M']:
<a
class="tooltip"
href="${h.url('files_home',repo_name=filediff.diffset.source_repo_name,f_path=filediff.target_file_path,revision=filediff.diffset.target_ref)}"
title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
>
${_('Show file after')}
</a>
%else:
<span
class="tooltip"
title="${h.tooltip(_('File no longer present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
>
${_('Show file after')}
</span>
%endif
<a
class="tooltip"
title="${h.tooltip(_('Raw diff'))}"
href="${h.url('files_diff_home',repo_name=filediff.diffset.repo_name,f_path=filediff.target_file_path,diff2=filediff.diffset.target_ref,diff1=filediff.diffset.source_ref,diff='raw')}"
>
${_('Raw diff')}
</a>
<a
class="tooltip"
title="${h.tooltip(_('Download diff'))}"
href="${h.url('files_diff_home',repo_name=filediff.diffset.repo_name,f_path=filediff.target_file_path,diff2=filediff.diffset.target_ref,diff1=filediff.diffset.source_ref,diff='download')}"
>
${_('Download diff')}
</a>
## TODO: dan: refactor ignorews_url and context_url into the diff renderer same as diffmode=unified/sideside. Also use ajax to load more context (by clicking hunks)
%if hasattr(c, 'ignorews_url'):
${c.ignorews_url(request.GET, h.FID('', filediff['patch']['filename']))}
%endif
%if hasattr(c, 'context_url'):
${c.context_url(request.GET, h.FID('', filediff['patch']['filename']))}
%endif
%if use_comments:
<a href="#" onclick="return Rhodecode.comments.toggleComments(this);">
<span class="show-comment-button">${_('Show comments')}</span><span class="hide-comment-button">${_('Hide comments')}</span>
</a>
%endif
%endif
</div>
</%def>
<%namespace name="commentblock" file="/changeset/changeset_file_comment.html"/>
<%def name="inline_comments_container(comments)">
<div class="inline-comments">
%for comment in comments:
${commentblock.comment_block(comment, inline=True)}
%endfor
<span onclick="return Rhodecode.comments.createComment(this)"
class="btn btn-secondary cb-comment-add-button ${'comment-outdated' if comments and comments[-1].outdated else ''}"
style="${'display: none;' if comments and comments[-1].outdated else ''}">
${_('Add another comment')}
</span>
</div>
</%def>
<%def name="render_hunk_lines_sideside(hunk, use_comments=False)">
%for i, line in enumerate(hunk.sideside):
<%
old_line_anchor, new_line_anchor = None, None
if line.original.lineno:
old_line_anchor = diff_line_anchor(hunk.filediff.source_file_path, line.original.lineno, 'o')
if line.modified.lineno:
new_line_anchor = diff_line_anchor(hunk.filediff.target_file_path, line.modified.lineno, 'n')
%>
<tr class="cb-line">
<td class="cb-data ${action_class(line.original.action)}"
data-line-number="${line.original.lineno}"
>
<div>
%if line.original.comments:
<i class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
%endif
</div>
</td>
<td class="cb-lineno ${action_class(line.original.action)}"
data-line-number="${line.original.lineno}"
%if old_line_anchor:
id="${old_line_anchor}"
%endif
>
%if line.original.lineno:
<a name="${old_line_anchor}" href="#${old_line_anchor}">${line.original.lineno}</a>
%endif
</td>
<td class="cb-content ${action_class(line.original.action)}"
data-line-number="o${line.original.lineno}"
>
%if use_comments and line.original.lineno:
${render_add_comment_button()}
%endif
<span class="cb-code">${line.original.action} ${line.original.content or '' | n}</span>
%if use_comments and line.original.lineno and line.original.comments:
${inline_comments_container(line.original.comments)}
%endif
</td>
<td class="cb-data ${action_class(line.modified.action)}"
data-line-number="${line.modified.lineno}"
>
<div>
%if line.modified.comments:
<i class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
%endif
</div>
</td>
<td class="cb-lineno ${action_class(line.modified.action)}"
data-line-number="${line.modified.lineno}"
%if new_line_anchor:
id="${new_line_anchor}"
%endif
>
%if line.modified.lineno:
<a name="${new_line_anchor}" href="#${new_line_anchor}">${line.modified.lineno}</a>
%endif
</td>
<td class="cb-content ${action_class(line.modified.action)}"
data-line-number="n${line.modified.lineno}"
>
%if use_comments and line.modified.lineno:
${render_add_comment_button()}
%endif
<span class="cb-code">${line.modified.action} ${line.modified.content or '' | n}</span>
%if use_comments and line.modified.lineno and line.modified.comments:
${inline_comments_container(line.modified.comments)}
%endif
</td>
</tr>
%endfor
</%def>
<%def name="render_hunk_lines_unified(hunk, use_comments=False)">
%for old_line_no, new_line_no, action, content, comments in hunk.unified:
<%
old_line_anchor, new_line_anchor = None, None
if old_line_no:
old_line_anchor = diff_line_anchor(hunk.filediff.source_file_path, old_line_no, 'o')
if new_line_no:
new_line_anchor = diff_line_anchor(hunk.filediff.target_file_path, new_line_no, 'n')
%>
<tr class="cb-line">
<td class="cb-data ${action_class(action)}">
<div>
%if comments:
<i class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
%endif
</div>
</td>
<td class="cb-lineno ${action_class(action)}"
data-line-number="${old_line_no}"
%if old_line_anchor:
id="${old_line_anchor}"
%endif
>
%if old_line_anchor:
<a name="${old_line_anchor}" href="#${old_line_anchor}">${old_line_no}</a>
%endif
</td>
<td class="cb-lineno ${action_class(action)}"
data-line-number="${new_line_no}"
%if new_line_anchor:
id="${new_line_anchor}"
%endif
>
%if new_line_anchor:
<a name="${new_line_anchor}" href="#${new_line_anchor}">${new_line_no}</a>
%endif
</td>
<td class="cb-content ${action_class(action)}"
data-line-number="${new_line_no and 'n' or 'o'}${new_line_no or old_line_no}"
>
%if use_comments:
${render_add_comment_button()}
%endif
<span class="cb-code">${action} ${content or '' | n}</span>
%if use_comments and comments:
${inline_comments_container(comments)}
%endif
</td>
</tr>
%endfor
</%def>
<%def name="render_add_comment_button()">
<button
class="btn btn-small btn-primary cb-comment-box-opener"
onclick="return Rhodecode.comments.createComment(this)"
><span>+</span></button>
</%def>
<%def name="render_diffset_menu()">
<div class="diffset-menu clearinner">
<div class="pull-right">
<div class="btn-group">
<a
class="btn ${c.diffmode == 'sideside' and 'btn-primary'} tooltip"
title="${_('View side by side')}"
href="${h.url_replace(diffmode='sideside')}">
<span>${_('Side by Side')}</span>
</a>
<a
class="btn ${c.diffmode == 'unified' and 'btn-primary'} tooltip"
title="${_('View unified')}" href="${h.url_replace(diffmode='unified')}">
<span>${_('Unified')}</span>
</a>
</div>
</div>
<div class="pull-left">
<div class="btn-group">
<a
class="btn"
href="#"
onclick="$('input[class=filediff-collapse-state]').prop('checked', false); return false">${_('Expand All')}</a>
<a
class="btn"
href="#"
onclick="$('input[class=filediff-collapse-state]').prop('checked', true); return false">${_('Collapse All')}</a>
<a
class="btn"
href="#"
onclick="return Rhodecode.comments.toggleWideMode(this)">${_('Wide Mode')}</a>
</div>
</div>
</div>
</%def>