##// END OF EJS Templates
comments: show nicer tooltip about outdated comments.
marcink -
r4382:b8cc803a stable
parent child Browse files
Show More
@@ -1,1215 +1,1215 b''
1 <%namespace name="commentblock" file="/changeset/changeset_file_comment.mako"/>
1 <%namespace name="commentblock" file="/changeset/changeset_file_comment.mako"/>
2
2
3 <%def name="diff_line_anchor(commit, filename, line, type)"><%
3 <%def name="diff_line_anchor(commit, filename, line, type)"><%
4 return '%s_%s_%i' % (h.md5_safe(commit+filename), type, line)
4 return '%s_%s_%i' % (h.md5_safe(commit+filename), type, line)
5 %></%def>
5 %></%def>
6
6
7 <%def name="action_class(action)">
7 <%def name="action_class(action)">
8 <%
8 <%
9 return {
9 return {
10 '-': 'cb-deletion',
10 '-': 'cb-deletion',
11 '+': 'cb-addition',
11 '+': 'cb-addition',
12 ' ': 'cb-context',
12 ' ': 'cb-context',
13 }.get(action, 'cb-empty')
13 }.get(action, 'cb-empty')
14 %>
14 %>
15 </%def>
15 </%def>
16
16
17 <%def name="op_class(op_id)">
17 <%def name="op_class(op_id)">
18 <%
18 <%
19 return {
19 return {
20 DEL_FILENODE: 'deletion', # file deleted
20 DEL_FILENODE: 'deletion', # file deleted
21 BIN_FILENODE: 'warning' # binary diff hidden
21 BIN_FILENODE: 'warning' # binary diff hidden
22 }.get(op_id, 'addition')
22 }.get(op_id, 'addition')
23 %>
23 %>
24 </%def>
24 </%def>
25
25
26
26
27
27
28 <%def name="render_diffset(diffset, commit=None,
28 <%def name="render_diffset(diffset, commit=None,
29
29
30 # collapse all file diff entries when there are more than this amount of files in the diff
30 # collapse all file diff entries when there are more than this amount of files in the diff
31 collapse_when_files_over=20,
31 collapse_when_files_over=20,
32
32
33 # collapse lines in the diff when more than this amount of lines changed in the file diff
33 # collapse lines in the diff when more than this amount of lines changed in the file diff
34 lines_changed_limit=500,
34 lines_changed_limit=500,
35
35
36 # add a ruler at to the output
36 # add a ruler at to the output
37 ruler_at_chars=0,
37 ruler_at_chars=0,
38
38
39 # show inline comments
39 # show inline comments
40 use_comments=False,
40 use_comments=False,
41
41
42 # disable new comments
42 # disable new comments
43 disable_new_comments=False,
43 disable_new_comments=False,
44
44
45 # special file-comments that were deleted in previous versions
45 # special file-comments that were deleted in previous versions
46 # it's used for showing outdated comments for deleted files in a PR
46 # it's used for showing outdated comments for deleted files in a PR
47 deleted_files_comments=None,
47 deleted_files_comments=None,
48
48
49 # for cache purpose
49 # for cache purpose
50 inline_comments=None,
50 inline_comments=None,
51
51
52 # additional menu for PRs
52 # additional menu for PRs
53 pull_request_menu=None,
53 pull_request_menu=None,
54
54
55 # show/hide todo next to comments
55 # show/hide todo next to comments
56 show_todos=True,
56 show_todos=True,
57
57
58 )">
58 )">
59
59
60 <%
60 <%
61 diffset_container_id = h.md5(diffset.target_ref)
61 diffset_container_id = h.md5(diffset.target_ref)
62 collapse_all = len(diffset.files) > collapse_when_files_over
62 collapse_all = len(diffset.files) > collapse_when_files_over
63 active_pattern_entries = h.get_active_pattern_entries(getattr(c, 'repo_name', None))
63 active_pattern_entries = h.get_active_pattern_entries(getattr(c, 'repo_name', None))
64 %>
64 %>
65
65
66 %if use_comments:
66 %if use_comments:
67
67
68 ## Template for injecting comments
68 ## Template for injecting comments
69 <div id="cb-comments-inline-container-template" class="js-template">
69 <div id="cb-comments-inline-container-template" class="js-template">
70 ${inline_comments_container([])}
70 ${inline_comments_container([])}
71 </div>
71 </div>
72
72
73 <div class="js-template" id="cb-comment-inline-form-template">
73 <div class="js-template" id="cb-comment-inline-form-template">
74 <div class="comment-inline-form ac">
74 <div class="comment-inline-form ac">
75
75
76 %if c.rhodecode_user.username != h.DEFAULT_USER:
76 %if c.rhodecode_user.username != h.DEFAULT_USER:
77 ## render template for inline comments
77 ## render template for inline comments
78 ${commentblock.comment_form(form_type='inline')}
78 ${commentblock.comment_form(form_type='inline')}
79 %else:
79 %else:
80 ${h.form('', class_='inline-form comment-form-login', method='get')}
80 ${h.form('', class_='inline-form comment-form-login', method='get')}
81 <div class="pull-left">
81 <div class="pull-left">
82 <div class="comment-help pull-right">
82 <div class="comment-help pull-right">
83 ${_('You need to be logged in to leave comments.')} <a href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">${_('Login now')}</a>
83 ${_('You need to be logged in to leave comments.')} <a href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">${_('Login now')}</a>
84 </div>
84 </div>
85 </div>
85 </div>
86 <div class="comment-button pull-right">
86 <div class="comment-button pull-right">
87 <button type="button" class="cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
87 <button type="button" class="cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
88 ${_('Cancel')}
88 ${_('Cancel')}
89 </button>
89 </button>
90 </div>
90 </div>
91 <div class="clearfix"></div>
91 <div class="clearfix"></div>
92 ${h.end_form()}
92 ${h.end_form()}
93 %endif
93 %endif
94 </div>
94 </div>
95 </div>
95 </div>
96
96
97 %endif
97 %endif
98
98
99 %if c.user_session_attrs["diffmode"] == 'sideside':
99 %if c.user_session_attrs["diffmode"] == 'sideside':
100 <style>
100 <style>
101 .wrapper {
101 .wrapper {
102 max-width: 1600px !important;
102 max-width: 1600px !important;
103 }
103 }
104 </style>
104 </style>
105 %endif
105 %endif
106
106
107 %if ruler_at_chars:
107 %if ruler_at_chars:
108 <style>
108 <style>
109 .diff table.cb .cb-content:after {
109 .diff table.cb .cb-content:after {
110 content: "";
110 content: "";
111 border-left: 1px solid blue;
111 border-left: 1px solid blue;
112 position: absolute;
112 position: absolute;
113 top: 0;
113 top: 0;
114 height: 18px;
114 height: 18px;
115 opacity: .2;
115 opacity: .2;
116 z-index: 10;
116 z-index: 10;
117 //## +5 to account for diff action (+/-)
117 //## +5 to account for diff action (+/-)
118 left: ${ruler_at_chars + 5}ch;
118 left: ${ruler_at_chars + 5}ch;
119 </style>
119 </style>
120 %endif
120 %endif
121
121
122 <div class="diffset ${disable_new_comments and 'diffset-comments-disabled'}">
122 <div class="diffset ${disable_new_comments and 'diffset-comments-disabled'}">
123
123
124 <div style="height: 20px; line-height: 20px">
124 <div style="height: 20px; line-height: 20px">
125 ## expand/collapse action
125 ## expand/collapse action
126 <div class="pull-left">
126 <div class="pull-left">
127 <a class="${'collapsed' if collapse_all else ''}" href="#expand-files" onclick="toggleExpand(this, '${diffset_container_id}'); return false">
127 <a class="${'collapsed' if collapse_all else ''}" href="#expand-files" onclick="toggleExpand(this, '${diffset_container_id}'); return false">
128 % if collapse_all:
128 % if collapse_all:
129 <i class="icon-plus-squared-alt icon-no-margin"></i>${_('Expand all files')}
129 <i class="icon-plus-squared-alt icon-no-margin"></i>${_('Expand all files')}
130 % else:
130 % else:
131 <i class="icon-minus-squared-alt icon-no-margin"></i>${_('Collapse all files')}
131 <i class="icon-minus-squared-alt icon-no-margin"></i>${_('Collapse all files')}
132 % endif
132 % endif
133 </a>
133 </a>
134
134
135 </div>
135 </div>
136
136
137 ## todos
137 ## todos
138 % if show_todos and getattr(c, 'at_version', None):
138 % if show_todos and getattr(c, 'at_version', None):
139 <div class="pull-right">
139 <div class="pull-right">
140 <i class="icon-flag-filled" style="color: #949494">TODOs:</i>
140 <i class="icon-flag-filled" style="color: #949494">TODOs:</i>
141 ${_('not available in this view')}
141 ${_('not available in this view')}
142 </div>
142 </div>
143 % elif show_todos:
143 % elif show_todos:
144 <div class="pull-right">
144 <div class="pull-right">
145 <div class="comments-number" style="padding-left: 10px">
145 <div class="comments-number" style="padding-left: 10px">
146 % if hasattr(c, 'unresolved_comments') and hasattr(c, 'resolved_comments'):
146 % if hasattr(c, 'unresolved_comments') and hasattr(c, 'resolved_comments'):
147 <i class="icon-flag-filled" style="color: #949494">TODOs:</i>
147 <i class="icon-flag-filled" style="color: #949494">TODOs:</i>
148 % if c.unresolved_comments:
148 % if c.unresolved_comments:
149 <a href="#show-todos" onclick="$('#todo-box').toggle(); return false">
149 <a href="#show-todos" onclick="$('#todo-box').toggle(); return false">
150 ${_('{} unresolved').format(len(c.unresolved_comments))}
150 ${_('{} unresolved').format(len(c.unresolved_comments))}
151 </a>
151 </a>
152 % else:
152 % else:
153 ${_('0 unresolved')}
153 ${_('0 unresolved')}
154 % endif
154 % endif
155
155
156 ${_('{} Resolved').format(len(c.resolved_comments))}
156 ${_('{} Resolved').format(len(c.resolved_comments))}
157 % endif
157 % endif
158 </div>
158 </div>
159 </div>
159 </div>
160 % endif
160 % endif
161
161
162 ## comments
162 ## comments
163 <div class="pull-right">
163 <div class="pull-right">
164 <div class="comments-number" style="padding-left: 10px">
164 <div class="comments-number" style="padding-left: 10px">
165 % if hasattr(c, 'comments') and hasattr(c, 'inline_cnt'):
165 % if hasattr(c, 'comments') and hasattr(c, 'inline_cnt'):
166 <i class="icon-comment" style="color: #949494">COMMENTS:</i>
166 <i class="icon-comment" style="color: #949494">COMMENTS:</i>
167 % if c.comments:
167 % if c.comments:
168 <a href="#comments">${_ungettext("{} General", "{} General", len(c.comments)).format(len(c.comments))}</a>,
168 <a href="#comments">${_ungettext("{} General", "{} General", len(c.comments)).format(len(c.comments))}</a>,
169 % else:
169 % else:
170 ${_('0 General')}
170 ${_('0 General')}
171 % endif
171 % endif
172
172
173 % if c.inline_cnt:
173 % if c.inline_cnt:
174 <a href="#" onclick="return Rhodecode.comments.nextComment();"
174 <a href="#" onclick="return Rhodecode.comments.nextComment();"
175 id="inline-comments-counter">${_ungettext("{} Inline", "{} Inline", c.inline_cnt).format(c.inline_cnt)}
175 id="inline-comments-counter">${_ungettext("{} Inline", "{} Inline", c.inline_cnt).format(c.inline_cnt)}
176 </a>
176 </a>
177 % else:
177 % else:
178 ${_('0 Inline')}
178 ${_('0 Inline')}
179 % endif
179 % endif
180 % endif
180 % endif
181
181
182 % if pull_request_menu:
182 % if pull_request_menu:
183 <%
183 <%
184 outdated_comm_count_ver = pull_request_menu['outdated_comm_count_ver']
184 outdated_comm_count_ver = pull_request_menu['outdated_comm_count_ver']
185 %>
185 %>
186
186
187 % if outdated_comm_count_ver:
187 % if outdated_comm_count_ver:
188 <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">
188 <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">
189 (${_("{} Outdated").format(outdated_comm_count_ver)})
189 (${_("{} Outdated").format(outdated_comm_count_ver)})
190 </a>
190 </a>
191 <a href="#" class="showOutdatedComments" onclick="showOutdated(this); return false;"> | ${_('show outdated')}</a>
191 <a href="#" class="showOutdatedComments" onclick="showOutdated(this); return false;"> | ${_('show outdated')}</a>
192 <a href="#" class="hideOutdatedComments" style="display: none" onclick="hideOutdated(this); return false;"> | ${_('hide outdated')}</a>
192 <a href="#" class="hideOutdatedComments" style="display: none" onclick="hideOutdated(this); return false;"> | ${_('hide outdated')}</a>
193 % else:
193 % else:
194 (${_("{} Outdated").format(outdated_comm_count_ver)})
194 (${_("{} Outdated").format(outdated_comm_count_ver)})
195 % endif
195 % endif
196
196
197 % endif
197 % endif
198
198
199 </div>
199 </div>
200 </div>
200 </div>
201
201
202 </div>
202 </div>
203
203
204 % if diffset.limited_diff:
204 % if diffset.limited_diff:
205 <div class="diffset-heading ${(diffset.limited_diff and 'diffset-heading-warning' or '')}">
205 <div class="diffset-heading ${(diffset.limited_diff and 'diffset-heading-warning' or '')}">
206 <h2 class="clearinner">
206 <h2 class="clearinner">
207 ${_('The requested changes are too big and content was truncated.')}
207 ${_('The requested changes are too big and content was truncated.')}
208 <a href="${h.current_route_path(request, fulldiff=1)}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a>
208 <a href="${h.current_route_path(request, fulldiff=1)}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a>
209 </h2>
209 </h2>
210 </div>
210 </div>
211 ## commit range header for each individual diff
211 ## commit range header for each individual diff
212 % elif commit and hasattr(c, 'commit_ranges') and len(c.commit_ranges) > 1:
212 % elif commit and hasattr(c, 'commit_ranges') and len(c.commit_ranges) > 1:
213 <div class="diffset-heading ${(diffset.limited_diff and 'diffset-heading-warning' or '')}">
213 <div class="diffset-heading ${(diffset.limited_diff and 'diffset-heading-warning' or '')}">
214 <div class="clearinner">
214 <div class="clearinner">
215 <a class="tooltip revision" title="${h.tooltip(commit.message)}" href="${h.route_path('repo_commit',repo_name=diffset.repo_name,commit_id=commit.raw_id)}">${('r%s:%s' % (commit.idx,h.short_id(commit.raw_id)))}</a>
215 <a class="tooltip revision" title="${h.tooltip(commit.message)}" href="${h.route_path('repo_commit',repo_name=diffset.repo_name,commit_id=commit.raw_id)}">${('r%s:%s' % (commit.idx,h.short_id(commit.raw_id)))}</a>
216 </div>
216 </div>
217 </div>
217 </div>
218 % endif
218 % endif
219
219
220 <div id="todo-box">
220 <div id="todo-box">
221 % if hasattr(c, 'unresolved_comments') and c.unresolved_comments:
221 % if hasattr(c, 'unresolved_comments') and c.unresolved_comments:
222 % for co in c.unresolved_comments:
222 % for co in c.unresolved_comments:
223 <a class="permalink" href="#comment-${co.comment_id}"
223 <a class="permalink" href="#comment-${co.comment_id}"
224 onclick="Rhodecode.comments.scrollToComment($('#comment-${co.comment_id}'))">
224 onclick="Rhodecode.comments.scrollToComment($('#comment-${co.comment_id}'))">
225 <i class="icon-flag-filled-red"></i>
225 <i class="icon-flag-filled-red"></i>
226 ${co.comment_id}</a>${('' if loop.last else ',')}
226 ${co.comment_id}</a>${('' if loop.last else ',')}
227 % endfor
227 % endfor
228 % endif
228 % endif
229 </div>
229 </div>
230 %if diffset.has_hidden_changes:
230 %if diffset.has_hidden_changes:
231 <p class="empty_data">${_('Some changes may be hidden')}</p>
231 <p class="empty_data">${_('Some changes may be hidden')}</p>
232 %elif not diffset.files:
232 %elif not diffset.files:
233 <p class="empty_data">${_('No files')}</p>
233 <p class="empty_data">${_('No files')}</p>
234 %endif
234 %endif
235
235
236 <div class="filediffs">
236 <div class="filediffs">
237
237
238 ## initial value could be marked as False later on
238 ## initial value could be marked as False later on
239 <% over_lines_changed_limit = False %>
239 <% over_lines_changed_limit = False %>
240 %for i, filediff in enumerate(diffset.files):
240 %for i, filediff in enumerate(diffset.files):
241
241
242 <%
242 <%
243 lines_changed = filediff.patch['stats']['added'] + filediff.patch['stats']['deleted']
243 lines_changed = filediff.patch['stats']['added'] + filediff.patch['stats']['deleted']
244 over_lines_changed_limit = lines_changed > lines_changed_limit
244 over_lines_changed_limit = lines_changed > lines_changed_limit
245 %>
245 %>
246 ## anchor with support of sticky header
246 ## anchor with support of sticky header
247 <div class="anchor" id="a_${h.FID(filediff.raw_id, filediff.patch['filename'])}"></div>
247 <div class="anchor" id="a_${h.FID(filediff.raw_id, filediff.patch['filename'])}"></div>
248
248
249 <input ${(collapse_all and 'checked' or '')} class="filediff-collapse-state collapse-${diffset_container_id}" id="filediff-collapse-${id(filediff)}" type="checkbox" onchange="updateSticky();">
249 <input ${(collapse_all and 'checked' or '')} class="filediff-collapse-state collapse-${diffset_container_id}" id="filediff-collapse-${id(filediff)}" type="checkbox" onchange="updateSticky();">
250 <div
250 <div
251 class="filediff"
251 class="filediff"
252 data-f-path="${filediff.patch['filename']}"
252 data-f-path="${filediff.patch['filename']}"
253 data-anchor-id="${h.FID(filediff.raw_id, filediff.patch['filename'])}"
253 data-anchor-id="${h.FID(filediff.raw_id, filediff.patch['filename'])}"
254 >
254 >
255 <label for="filediff-collapse-${id(filediff)}" class="filediff-heading">
255 <label for="filediff-collapse-${id(filediff)}" class="filediff-heading">
256 <%
256 <%
257 file_comments = (get_inline_comments(inline_comments, filediff.patch['filename']) or {}).values()
257 file_comments = (get_inline_comments(inline_comments, filediff.patch['filename']) or {}).values()
258 total_file_comments = [_c for _c in h.itertools.chain.from_iterable(file_comments) if not _c.outdated]
258 total_file_comments = [_c for _c in h.itertools.chain.from_iterable(file_comments) if not _c.outdated]
259 %>
259 %>
260 <div class="filediff-collapse-indicator icon-"></div>
260 <div class="filediff-collapse-indicator icon-"></div>
261 <span class="pill-group pull-right" >
261 <span class="pill-group pull-right" >
262 <span class="pill"><i class="icon-comment"></i> ${len(total_file_comments)}</span>
262 <span class="pill"><i class="icon-comment"></i> ${len(total_file_comments)}</span>
263 </span>
263 </span>
264 ${diff_ops(filediff)}
264 ${diff_ops(filediff)}
265
265
266 </label>
266 </label>
267
267
268 ${diff_menu(filediff, use_comments=use_comments)}
268 ${diff_menu(filediff, use_comments=use_comments)}
269 <table data-f-path="${filediff.patch['filename']}" data-anchor-id="${h.FID(filediff.raw_id, filediff.patch['filename'])}" class="code-visible-block cb cb-diff-${c.user_session_attrs["diffmode"]} code-highlight ${(over_lines_changed_limit and 'cb-collapsed' or '')}">
269 <table data-f-path="${filediff.patch['filename']}" data-anchor-id="${h.FID(filediff.raw_id, filediff.patch['filename'])}" class="code-visible-block cb cb-diff-${c.user_session_attrs["diffmode"]} code-highlight ${(over_lines_changed_limit and 'cb-collapsed' or '')}">
270
270
271 ## new/deleted/empty content case
271 ## new/deleted/empty content case
272 % if not filediff.hunks:
272 % if not filediff.hunks:
273 ## Comment container, on "fakes" hunk that contains all data to render comments
273 ## Comment container, on "fakes" hunk that contains all data to render comments
274 ${render_hunk_lines(filediff, c.user_session_attrs["diffmode"], filediff.hunk_ops, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
274 ${render_hunk_lines(filediff, c.user_session_attrs["diffmode"], filediff.hunk_ops, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
275 % endif
275 % endif
276
276
277 %if filediff.limited_diff:
277 %if filediff.limited_diff:
278 <tr class="cb-warning cb-collapser">
278 <tr class="cb-warning cb-collapser">
279 <td class="cb-text" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=6')}>
279 <td class="cb-text" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=6')}>
280 ${_('The requested commit or file is too big and content was truncated.')} <a href="${h.current_route_path(request, fulldiff=1)}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a>
280 ${_('The requested commit or file is too big and content was truncated.')} <a href="${h.current_route_path(request, fulldiff=1)}" onclick="return confirm('${_("Showing a big diff might take some time and resources, continue?")}')">${_('Show full diff')}</a>
281 </td>
281 </td>
282 </tr>
282 </tr>
283 %else:
283 %else:
284 %if over_lines_changed_limit:
284 %if over_lines_changed_limit:
285 <tr class="cb-warning cb-collapser">
285 <tr class="cb-warning cb-collapser">
286 <td class="cb-text" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=6')}>
286 <td class="cb-text" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=6')}>
287 ${_('This diff has been collapsed as it changes many lines, (%i lines changed)' % lines_changed)}
287 ${_('This diff has been collapsed as it changes many lines, (%i lines changed)' % lines_changed)}
288 <a href="#" class="cb-expand"
288 <a href="#" class="cb-expand"
289 onclick="$(this).closest('table').removeClass('cb-collapsed'); updateSticky(); return false;">${_('Show them')}
289 onclick="$(this).closest('table').removeClass('cb-collapsed'); updateSticky(); return false;">${_('Show them')}
290 </a>
290 </a>
291 <a href="#" class="cb-collapse"
291 <a href="#" class="cb-collapse"
292 onclick="$(this).closest('table').addClass('cb-collapsed'); updateSticky(); return false;">${_('Hide them')}
292 onclick="$(this).closest('table').addClass('cb-collapsed'); updateSticky(); return false;">${_('Hide them')}
293 </a>
293 </a>
294 </td>
294 </td>
295 </tr>
295 </tr>
296 %endif
296 %endif
297 %endif
297 %endif
298
298
299 % for hunk in filediff.hunks:
299 % for hunk in filediff.hunks:
300 <tr class="cb-hunk">
300 <tr class="cb-hunk">
301 <td ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=3' or '')}>
301 <td ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=3' or '')}>
302 ## TODO: dan: add ajax loading of more context here
302 ## TODO: dan: add ajax loading of more context here
303 ## <a href="#">
303 ## <a href="#">
304 <i class="icon-more"></i>
304 <i class="icon-more"></i>
305 ## </a>
305 ## </a>
306 </td>
306 </td>
307 <td ${(c.user_session_attrs["diffmode"] == 'sideside' and 'colspan=5' or '')}>
307 <td ${(c.user_session_attrs["diffmode"] == 'sideside' and 'colspan=5' or '')}>
308 @@
308 @@
309 -${hunk.source_start},${hunk.source_length}
309 -${hunk.source_start},${hunk.source_length}
310 +${hunk.target_start},${hunk.target_length}
310 +${hunk.target_start},${hunk.target_length}
311 ${hunk.section_header}
311 ${hunk.section_header}
312 </td>
312 </td>
313 </tr>
313 </tr>
314 ${render_hunk_lines(filediff, c.user_session_attrs["diffmode"], hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
314 ${render_hunk_lines(filediff, c.user_session_attrs["diffmode"], hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
315 % endfor
315 % endfor
316
316
317 <% unmatched_comments = (inline_comments or {}).get(filediff.patch['filename'], {}) %>
317 <% unmatched_comments = (inline_comments or {}).get(filediff.patch['filename'], {}) %>
318
318
319 ## outdated comments that do not fit into currently displayed lines
319 ## outdated comments that do not fit into currently displayed lines
320 % for lineno, comments in unmatched_comments.items():
320 % for lineno, comments in unmatched_comments.items():
321
321
322 %if c.user_session_attrs["diffmode"] == 'unified':
322 %if c.user_session_attrs["diffmode"] == 'unified':
323 % if loop.index == 0:
323 % if loop.index == 0:
324 <tr class="cb-hunk">
324 <tr class="cb-hunk">
325 <td colspan="3"></td>
325 <td colspan="3"></td>
326 <td>
326 <td>
327 <div>
327 <div>
328 ${_('Unmatched/outdated inline comments below')}
328 ${_('Unmatched/outdated inline comments below')}
329 </div>
329 </div>
330 </td>
330 </td>
331 </tr>
331 </tr>
332 % endif
332 % endif
333 <tr class="cb-line">
333 <tr class="cb-line">
334 <td class="cb-data cb-context"></td>
334 <td class="cb-data cb-context"></td>
335 <td class="cb-lineno cb-context"></td>
335 <td class="cb-lineno cb-context"></td>
336 <td class="cb-lineno cb-context"></td>
336 <td class="cb-lineno cb-context"></td>
337 <td class="cb-content cb-context">
337 <td class="cb-content cb-context">
338 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
338 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
339 </td>
339 </td>
340 </tr>
340 </tr>
341 %elif c.user_session_attrs["diffmode"] == 'sideside':
341 %elif c.user_session_attrs["diffmode"] == 'sideside':
342 % if loop.index == 0:
342 % if loop.index == 0:
343 <tr class="cb-comment-info">
343 <tr class="cb-comment-info">
344 <td colspan="2"></td>
344 <td colspan="2"></td>
345 <td class="cb-line">
345 <td class="cb-line">
346 <div>
346 <div>
347 ${_('Unmatched/outdated inline comments below')}
347 ${_('Unmatched/outdated inline comments below')}
348 </div>
348 </div>
349 </td>
349 </td>
350 <td colspan="2"></td>
350 <td colspan="2"></td>
351 <td class="cb-line">
351 <td class="cb-line">
352 <div>
352 <div>
353 ${_('Unmatched/outdated comments below')}
353 ${_('Unmatched/outdated comments below')}
354 </div>
354 </div>
355 </td>
355 </td>
356 </tr>
356 </tr>
357 % endif
357 % endif
358 <tr class="cb-line">
358 <tr class="cb-line">
359 <td class="cb-data cb-context"></td>
359 <td class="cb-data cb-context"></td>
360 <td class="cb-lineno cb-context"></td>
360 <td class="cb-lineno cb-context"></td>
361 <td class="cb-content cb-context">
361 <td class="cb-content cb-context">
362 % if lineno.startswith('o'):
362 % if lineno.startswith('o'):
363 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
363 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
364 % endif
364 % endif
365 </td>
365 </td>
366
366
367 <td class="cb-data cb-context"></td>
367 <td class="cb-data cb-context"></td>
368 <td class="cb-lineno cb-context"></td>
368 <td class="cb-lineno cb-context"></td>
369 <td class="cb-content cb-context">
369 <td class="cb-content cb-context">
370 % if lineno.startswith('n'):
370 % if lineno.startswith('n'):
371 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
371 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
372 % endif
372 % endif
373 </td>
373 </td>
374 </tr>
374 </tr>
375 %endif
375 %endif
376
376
377 % endfor
377 % endfor
378
378
379 </table>
379 </table>
380 </div>
380 </div>
381 %endfor
381 %endfor
382
382
383 ## outdated comments that are made for a file that has been deleted
383 ## outdated comments that are made for a file that has been deleted
384 % for filename, comments_dict in (deleted_files_comments or {}).items():
384 % for filename, comments_dict in (deleted_files_comments or {}).items():
385
385
386 <%
386 <%
387 display_state = 'display: none'
387 display_state = 'display: none'
388 open_comments_in_file = [x for x in comments_dict['comments'] if x.outdated is False]
388 open_comments_in_file = [x for x in comments_dict['comments'] if x.outdated is False]
389 if open_comments_in_file:
389 if open_comments_in_file:
390 display_state = ''
390 display_state = ''
391 fid = str(id(filename))
391 fid = str(id(filename))
392 %>
392 %>
393 <div class="filediffs filediff-outdated" style="${display_state}">
393 <div class="filediffs filediff-outdated" style="${display_state}">
394 <input ${(collapse_all and 'checked' or '')} class="filediff-collapse-state collapse-${diffset_container_id}" id="filediff-collapse-${id(filename)}" type="checkbox" onchange="updateSticky();">
394 <input ${(collapse_all and 'checked' or '')} class="filediff-collapse-state collapse-${diffset_container_id}" id="filediff-collapse-${id(filename)}" type="checkbox" onchange="updateSticky();">
395 <div class="filediff" data-f-path="${filename}" id="a_${h.FID(fid, filename)}">
395 <div class="filediff" data-f-path="${filename}" id="a_${h.FID(fid, filename)}">
396 <label for="filediff-collapse-${id(filename)}" class="filediff-heading">
396 <label for="filediff-collapse-${id(filename)}" class="filediff-heading">
397 <div class="filediff-collapse-indicator icon-"></div>
397 <div class="filediff-collapse-indicator icon-"></div>
398
398
399 <span class="pill">
399 <span class="pill">
400 ## file was deleted
400 ## file was deleted
401 ${filename}
401 ${filename}
402 </span>
402 </span>
403 <span class="pill-group pull-left" >
403 <span class="pill-group pull-left" >
404 ## file op, doesn't need translation
404 ## file op, doesn't need translation
405 <span class="pill" op="removed">unresolved comments</span>
405 <span class="pill" op="removed">unresolved comments</span>
406 </span>
406 </span>
407 <a class="pill filediff-anchor" href="#a_${h.FID(fid, filename)}">ΒΆ</a>
407 <a class="pill filediff-anchor" href="#a_${h.FID(fid, filename)}">ΒΆ</a>
408 <span class="pill-group pull-right">
408 <span class="pill-group pull-right">
409 <span class="pill" op="deleted">
409 <span class="pill" op="deleted">
410 % if comments_dict['stats'] >0:
410 % if comments_dict['stats'] >0:
411 -${comments_dict['stats']}
411 -${comments_dict['stats']}
412 % else:
412 % else:
413 ${comments_dict['stats']}
413 ${comments_dict['stats']}
414 % endif
414 % endif
415 </span>
415 </span>
416 </span>
416 </span>
417 </label>
417 </label>
418
418
419 <table class="cb cb-diff-${c.user_session_attrs["diffmode"]} code-highlight ${(over_lines_changed_limit and 'cb-collapsed' or '')}">
419 <table class="cb cb-diff-${c.user_session_attrs["diffmode"]} code-highlight ${(over_lines_changed_limit and 'cb-collapsed' or '')}">
420 <tr>
420 <tr>
421 % if c.user_session_attrs["diffmode"] == 'unified':
421 % if c.user_session_attrs["diffmode"] == 'unified':
422 <td></td>
422 <td></td>
423 %endif
423 %endif
424
424
425 <td></td>
425 <td></td>
426 <td class="cb-text cb-${op_class(BIN_FILENODE)}" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=5')}>
426 <td class="cb-text cb-${op_class(BIN_FILENODE)}" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=5')}>
427 <strong>${_('This file was removed from diff during updates to this pull-request.')}</strong><br/>
427 <strong>${_('This file was removed from diff during updates to this pull-request.')}</strong><br/>
428 ${_('There are still outdated/unresolved comments attached to it.')}
428 ${_('There are still outdated/unresolved comments attached to it.')}
429 </td>
429 </td>
430 </tr>
430 </tr>
431 %if c.user_session_attrs["diffmode"] == 'unified':
431 %if c.user_session_attrs["diffmode"] == 'unified':
432 <tr class="cb-line">
432 <tr class="cb-line">
433 <td class="cb-data cb-context"></td>
433 <td class="cb-data cb-context"></td>
434 <td class="cb-lineno cb-context"></td>
434 <td class="cb-lineno cb-context"></td>
435 <td class="cb-lineno cb-context"></td>
435 <td class="cb-lineno cb-context"></td>
436 <td class="cb-content cb-context">
436 <td class="cb-content cb-context">
437 ${inline_comments_container(comments_dict['comments'], active_pattern_entries=active_pattern_entries)}
437 ${inline_comments_container(comments_dict['comments'], active_pattern_entries=active_pattern_entries)}
438 </td>
438 </td>
439 </tr>
439 </tr>
440 %elif c.user_session_attrs["diffmode"] == 'sideside':
440 %elif c.user_session_attrs["diffmode"] == 'sideside':
441 <tr class="cb-line">
441 <tr class="cb-line">
442 <td class="cb-data cb-context"></td>
442 <td class="cb-data cb-context"></td>
443 <td class="cb-lineno cb-context"></td>
443 <td class="cb-lineno cb-context"></td>
444 <td class="cb-content cb-context"></td>
444 <td class="cb-content cb-context"></td>
445
445
446 <td class="cb-data cb-context"></td>
446 <td class="cb-data cb-context"></td>
447 <td class="cb-lineno cb-context"></td>
447 <td class="cb-lineno cb-context"></td>
448 <td class="cb-content cb-context">
448 <td class="cb-content cb-context">
449 ${inline_comments_container(comments_dict['comments'], active_pattern_entries=active_pattern_entries)}
449 ${inline_comments_container(comments_dict['comments'], active_pattern_entries=active_pattern_entries)}
450 </td>
450 </td>
451 </tr>
451 </tr>
452 %endif
452 %endif
453 </table>
453 </table>
454 </div>
454 </div>
455 </div>
455 </div>
456 % endfor
456 % endfor
457
457
458 </div>
458 </div>
459 </div>
459 </div>
460 </%def>
460 </%def>
461
461
462 <%def name="diff_ops(filediff)">
462 <%def name="diff_ops(filediff)">
463 <%
463 <%
464 from rhodecode.lib.diffs import NEW_FILENODE, DEL_FILENODE, \
464 from rhodecode.lib.diffs import NEW_FILENODE, DEL_FILENODE, \
465 MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE
465 MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE
466 %>
466 %>
467 <span class="pill">
467 <span class="pill">
468 <i class="icon-file-text"></i>
468 <i class="icon-file-text"></i>
469 %if filediff.source_file_path and filediff.target_file_path:
469 %if filediff.source_file_path and filediff.target_file_path:
470 %if filediff.source_file_path != filediff.target_file_path:
470 %if filediff.source_file_path != filediff.target_file_path:
471 ## file was renamed, or copied
471 ## file was renamed, or copied
472 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
472 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
473 ${filediff.target_file_path} β¬… <del>${filediff.source_file_path}</del>
473 ${filediff.target_file_path} β¬… <del>${filediff.source_file_path}</del>
474 <% final_path = filediff.target_file_path %>
474 <% final_path = filediff.target_file_path %>
475 %elif COPIED_FILENODE in filediff.patch['stats']['ops']:
475 %elif COPIED_FILENODE in filediff.patch['stats']['ops']:
476 ${filediff.target_file_path} β¬… ${filediff.source_file_path}
476 ${filediff.target_file_path} β¬… ${filediff.source_file_path}
477 <% final_path = filediff.target_file_path %>
477 <% final_path = filediff.target_file_path %>
478 %endif
478 %endif
479 %else:
479 %else:
480 ## file was modified
480 ## file was modified
481 ${filediff.source_file_path}
481 ${filediff.source_file_path}
482 <% final_path = filediff.source_file_path %>
482 <% final_path = filediff.source_file_path %>
483 %endif
483 %endif
484 %else:
484 %else:
485 %if filediff.source_file_path:
485 %if filediff.source_file_path:
486 ## file was deleted
486 ## file was deleted
487 ${filediff.source_file_path}
487 ${filediff.source_file_path}
488 <% final_path = filediff.source_file_path %>
488 <% final_path = filediff.source_file_path %>
489 %else:
489 %else:
490 ## file was added
490 ## file was added
491 ${filediff.target_file_path}
491 ${filediff.target_file_path}
492 <% final_path = filediff.target_file_path %>
492 <% final_path = filediff.target_file_path %>
493 %endif
493 %endif
494 %endif
494 %endif
495 <i style="color: #aaa" class="on-hover-icon icon-clipboard clipboard-action" data-clipboard-text="${final_path}" title="${_('Copy file path')}" onclick="return false;"></i>
495 <i style="color: #aaa" class="on-hover-icon icon-clipboard clipboard-action" data-clipboard-text="${final_path}" title="${_('Copy file path')}" onclick="return false;"></i>
496 </span>
496 </span>
497 ## anchor link
497 ## anchor link
498 <a class="pill filediff-anchor" href="#a_${h.FID(filediff.raw_id, filediff.patch['filename'])}">ΒΆ</a>
498 <a class="pill filediff-anchor" href="#a_${h.FID(filediff.raw_id, filediff.patch['filename'])}">ΒΆ</a>
499
499
500 <span class="pill-group pull-right">
500 <span class="pill-group pull-right">
501
501
502 ## ops pills
502 ## ops pills
503 %if filediff.limited_diff:
503 %if filediff.limited_diff:
504 <span class="pill tooltip" op="limited" title="The stats for this diff are not complete">limited diff</span>
504 <span class="pill tooltip" op="limited" title="The stats for this diff are not complete">limited diff</span>
505 %endif
505 %endif
506
506
507 %if NEW_FILENODE in filediff.patch['stats']['ops']:
507 %if NEW_FILENODE in filediff.patch['stats']['ops']:
508 <span class="pill" op="created">created</span>
508 <span class="pill" op="created">created</span>
509 %if filediff['target_mode'].startswith('120'):
509 %if filediff['target_mode'].startswith('120'):
510 <span class="pill" op="symlink">symlink</span>
510 <span class="pill" op="symlink">symlink</span>
511 %else:
511 %else:
512 <span class="pill" op="mode">${nice_mode(filediff['target_mode'])}</span>
512 <span class="pill" op="mode">${nice_mode(filediff['target_mode'])}</span>
513 %endif
513 %endif
514 %endif
514 %endif
515
515
516 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
516 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
517 <span class="pill" op="renamed">renamed</span>
517 <span class="pill" op="renamed">renamed</span>
518 %endif
518 %endif
519
519
520 %if COPIED_FILENODE in filediff.patch['stats']['ops']:
520 %if COPIED_FILENODE in filediff.patch['stats']['ops']:
521 <span class="pill" op="copied">copied</span>
521 <span class="pill" op="copied">copied</span>
522 %endif
522 %endif
523
523
524 %if DEL_FILENODE in filediff.patch['stats']['ops']:
524 %if DEL_FILENODE in filediff.patch['stats']['ops']:
525 <span class="pill" op="removed">removed</span>
525 <span class="pill" op="removed">removed</span>
526 %endif
526 %endif
527
527
528 %if CHMOD_FILENODE in filediff.patch['stats']['ops']:
528 %if CHMOD_FILENODE in filediff.patch['stats']['ops']:
529 <span class="pill" op="mode">
529 <span class="pill" op="mode">
530 ${nice_mode(filediff['source_mode'])} ➑ ${nice_mode(filediff['target_mode'])}
530 ${nice_mode(filediff['source_mode'])} ➑ ${nice_mode(filediff['target_mode'])}
531 </span>
531 </span>
532 %endif
532 %endif
533
533
534 %if BIN_FILENODE in filediff.patch['stats']['ops']:
534 %if BIN_FILENODE in filediff.patch['stats']['ops']:
535 <span class="pill" op="binary">binary</span>
535 <span class="pill" op="binary">binary</span>
536 %if MOD_FILENODE in filediff.patch['stats']['ops']:
536 %if MOD_FILENODE in filediff.patch['stats']['ops']:
537 <span class="pill" op="modified">modified</span>
537 <span class="pill" op="modified">modified</span>
538 %endif
538 %endif
539 %endif
539 %endif
540
540
541 <span class="pill" op="added">${('+' if filediff.patch['stats']['added'] else '')}${filediff.patch['stats']['added']}</span>
541 <span class="pill" op="added">${('+' if filediff.patch['stats']['added'] else '')}${filediff.patch['stats']['added']}</span>
542 <span class="pill" op="deleted">${((h.safe_int(filediff.patch['stats']['deleted']) or 0) * -1)}</span>
542 <span class="pill" op="deleted">${((h.safe_int(filediff.patch['stats']['deleted']) or 0) * -1)}</span>
543
543
544 </span>
544 </span>
545
545
546 </%def>
546 </%def>
547
547
548 <%def name="nice_mode(filemode)">
548 <%def name="nice_mode(filemode)">
549 ${(filemode.startswith('100') and filemode[3:] or filemode)}
549 ${(filemode.startswith('100') and filemode[3:] or filemode)}
550 </%def>
550 </%def>
551
551
552 <%def name="diff_menu(filediff, use_comments=False)">
552 <%def name="diff_menu(filediff, use_comments=False)">
553 <div class="filediff-menu">
553 <div class="filediff-menu">
554
554
555 %if filediff.diffset.source_ref:
555 %if filediff.diffset.source_ref:
556
556
557 ## FILE BEFORE CHANGES
557 ## FILE BEFORE CHANGES
558 %if filediff.operation in ['D', 'M']:
558 %if filediff.operation in ['D', 'M']:
559 <a
559 <a
560 class="tooltip"
560 class="tooltip"
561 href="${h.route_path('repo_files',repo_name=filediff.diffset.target_repo_name,commit_id=filediff.diffset.source_ref,f_path=filediff.source_file_path)}"
561 href="${h.route_path('repo_files',repo_name=filediff.diffset.target_repo_name,commit_id=filediff.diffset.source_ref,f_path=filediff.source_file_path)}"
562 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
562 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
563 >
563 >
564 ${_('Show file before')}
564 ${_('Show file before')}
565 </a> |
565 </a> |
566 %else:
566 %else:
567 <span
567 <span
568 class="tooltip"
568 class="tooltip"
569 title="${h.tooltip(_('File not present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
569 title="${h.tooltip(_('File not present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
570 >
570 >
571 ${_('Show file before')}
571 ${_('Show file before')}
572 </span> |
572 </span> |
573 %endif
573 %endif
574
574
575 ## FILE AFTER CHANGES
575 ## FILE AFTER CHANGES
576 %if filediff.operation in ['A', 'M']:
576 %if filediff.operation in ['A', 'M']:
577 <a
577 <a
578 class="tooltip"
578 class="tooltip"
579 href="${h.route_path('repo_files',repo_name=filediff.diffset.source_repo_name,commit_id=filediff.diffset.target_ref,f_path=filediff.target_file_path)}"
579 href="${h.route_path('repo_files',repo_name=filediff.diffset.source_repo_name,commit_id=filediff.diffset.target_ref,f_path=filediff.target_file_path)}"
580 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
580 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
581 >
581 >
582 ${_('Show file after')}
582 ${_('Show file after')}
583 </a>
583 </a>
584 %else:
584 %else:
585 <span
585 <span
586 class="tooltip"
586 class="tooltip"
587 title="${h.tooltip(_('File not present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
587 title="${h.tooltip(_('File not present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
588 >
588 >
589 ${_('Show file after')}
589 ${_('Show file after')}
590 </span>
590 </span>
591 %endif
591 %endif
592
592
593 % if use_comments:
593 % if use_comments:
594 |
594 |
595 <a href="#" onclick="return Rhodecode.comments.toggleComments(this);">
595 <a href="#" onclick="return Rhodecode.comments.toggleComments(this);">
596 <span class="show-comment-button">${_('Show comments')}</span><span class="hide-comment-button">${_('Hide comments')}</span>
596 <span class="show-comment-button">${_('Show comments')}</span><span class="hide-comment-button">${_('Hide comments')}</span>
597 </a>
597 </a>
598 % endif
598 % endif
599
599
600 %endif
600 %endif
601
601
602 </div>
602 </div>
603 </%def>
603 </%def>
604
604
605
605
606 <%def name="inline_comments_container(comments, active_pattern_entries=None)">
606 <%def name="inline_comments_container(comments, active_pattern_entries=None)">
607
607
608 <div class="inline-comments">
608 <div class="inline-comments">
609 %for comment in comments:
609 %for comment in comments:
610 ${commentblock.comment_block(comment, inline=True, active_pattern_entries=active_pattern_entries)}
610 ${commentblock.comment_block(comment, inline=True, active_pattern_entries=active_pattern_entries)}
611 %endfor
611 %endfor
612 % if comments and comments[-1].outdated:
612 % if comments and comments[-1].outdated:
613 <span class="btn btn-secondary cb-comment-add-button comment-outdated}" style="display: none;}">
613 <span class="btn btn-secondary cb-comment-add-button comment-outdated}" style="display: none;}">
614 ${_('Add another comment')}
614 ${_('Add another comment')}
615 </span>
615 </span>
616 % else:
616 % else:
617 <span onclick="return Rhodecode.comments.createComment(this)" class="btn btn-secondary cb-comment-add-button">
617 <span onclick="return Rhodecode.comments.createComment(this)" class="btn btn-secondary cb-comment-add-button">
618 ${_('Add another comment')}
618 ${_('Add another comment')}
619 </span>
619 </span>
620 % endif
620 % endif
621
621
622 </div>
622 </div>
623 </%def>
623 </%def>
624
624
625 <%!
625 <%!
626
626
627 def get_inline_comments(comments, filename):
627 def get_inline_comments(comments, filename):
628 if hasattr(filename, 'unicode_path'):
628 if hasattr(filename, 'unicode_path'):
629 filename = filename.unicode_path
629 filename = filename.unicode_path
630
630
631 if not isinstance(filename, (unicode, str)):
631 if not isinstance(filename, (unicode, str)):
632 return None
632 return None
633
633
634 if comments and filename in comments:
634 if comments and filename in comments:
635 return comments[filename]
635 return comments[filename]
636
636
637 return None
637 return None
638
638
639 def get_comments_for(diff_type, comments, filename, line_version, line_number):
639 def get_comments_for(diff_type, comments, filename, line_version, line_number):
640 if hasattr(filename, 'unicode_path'):
640 if hasattr(filename, 'unicode_path'):
641 filename = filename.unicode_path
641 filename = filename.unicode_path
642
642
643 if not isinstance(filename, (unicode, str)):
643 if not isinstance(filename, (unicode, str)):
644 return None
644 return None
645
645
646 file_comments = get_inline_comments(comments, filename)
646 file_comments = get_inline_comments(comments, filename)
647 if file_comments is None:
647 if file_comments is None:
648 return None
648 return None
649
649
650 line_key = '{}{}'.format(line_version, line_number) ## e.g o37, n12
650 line_key = '{}{}'.format(line_version, line_number) ## e.g o37, n12
651 if line_key in file_comments:
651 if line_key in file_comments:
652 data = file_comments.pop(line_key)
652 data = file_comments.pop(line_key)
653 return data
653 return data
654 %>
654 %>
655
655
656 <%def name="render_hunk_lines_sideside(filediff, hunk, use_comments=False, inline_comments=None, active_pattern_entries=None)">
656 <%def name="render_hunk_lines_sideside(filediff, hunk, use_comments=False, inline_comments=None, active_pattern_entries=None)">
657 %for i, line in enumerate(hunk.sideside):
657 %for i, line in enumerate(hunk.sideside):
658 <%
658 <%
659 old_line_anchor, new_line_anchor = None, None
659 old_line_anchor, new_line_anchor = None, None
660
660
661 if line.original.lineno:
661 if line.original.lineno:
662 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, line.original.lineno, 'o')
662 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, line.original.lineno, 'o')
663 if line.modified.lineno:
663 if line.modified.lineno:
664 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, line.modified.lineno, 'n')
664 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, line.modified.lineno, 'n')
665 %>
665 %>
666
666
667 <tr class="cb-line">
667 <tr class="cb-line">
668 <td class="cb-data ${action_class(line.original.action)}"
668 <td class="cb-data ${action_class(line.original.action)}"
669 data-line-no="${line.original.lineno}"
669 data-line-no="${line.original.lineno}"
670 >
670 >
671 <div>
671 <div>
672
672
673 <% line_old_comments = None %>
673 <% line_old_comments = None %>
674 %if line.original.get_comment_args:
674 %if line.original.get_comment_args:
675 <% line_old_comments = get_comments_for('side-by-side', inline_comments, *line.original.get_comment_args) %>
675 <% line_old_comments = get_comments_for('side-by-side', inline_comments, *line.original.get_comment_args) %>
676 %endif
676 %endif
677 %if line_old_comments:
677 %if line_old_comments:
678 <% has_outdated = any([x.outdated for x in line_old_comments]) %>
678 <% has_outdated = any([x.outdated for x in line_old_comments]) %>
679 % if has_outdated:
679 % if has_outdated:
680 <i title="${_('comments including outdated')}:${len(line_old_comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
680 <i class="tooltip" title="${_('comments including outdated, click to show them')}:${len(line_old_comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
681 % else:
681 % else:
682 <i title="${_('comments')}: ${len(line_old_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
682 <i class="tooltip" title="${_('comments')}: ${len(line_old_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
683 % endif
683 % endif
684 %endif
684 %endif
685 </div>
685 </div>
686 </td>
686 </td>
687 <td class="cb-lineno ${action_class(line.original.action)}"
687 <td class="cb-lineno ${action_class(line.original.action)}"
688 data-line-no="${line.original.lineno}"
688 data-line-no="${line.original.lineno}"
689 %if old_line_anchor:
689 %if old_line_anchor:
690 id="${old_line_anchor}"
690 id="${old_line_anchor}"
691 %endif
691 %endif
692 >
692 >
693 %if line.original.lineno:
693 %if line.original.lineno:
694 <a name="${old_line_anchor}" href="#${old_line_anchor}">${line.original.lineno}</a>
694 <a name="${old_line_anchor}" href="#${old_line_anchor}">${line.original.lineno}</a>
695 %endif
695 %endif
696 </td>
696 </td>
697 <td class="cb-content ${action_class(line.original.action)}"
697 <td class="cb-content ${action_class(line.original.action)}"
698 data-line-no="o${line.original.lineno}"
698 data-line-no="o${line.original.lineno}"
699 >
699 >
700 %if use_comments and line.original.lineno:
700 %if use_comments and line.original.lineno:
701 ${render_add_comment_button()}
701 ${render_add_comment_button()}
702 %endif
702 %endif
703 <span class="cb-code"><span class="cb-action ${action_class(line.original.action)}"></span>${line.original.content or '' | n}</span>
703 <span class="cb-code"><span class="cb-action ${action_class(line.original.action)}"></span>${line.original.content or '' | n}</span>
704
704
705 %if use_comments and line.original.lineno and line_old_comments:
705 %if use_comments and line.original.lineno and line_old_comments:
706 ${inline_comments_container(line_old_comments, active_pattern_entries=active_pattern_entries)}
706 ${inline_comments_container(line_old_comments, active_pattern_entries=active_pattern_entries)}
707 %endif
707 %endif
708
708
709 </td>
709 </td>
710 <td class="cb-data ${action_class(line.modified.action)}"
710 <td class="cb-data ${action_class(line.modified.action)}"
711 data-line-no="${line.modified.lineno}"
711 data-line-no="${line.modified.lineno}"
712 >
712 >
713 <div>
713 <div>
714
714
715 %if line.modified.get_comment_args:
715 %if line.modified.get_comment_args:
716 <% line_new_comments = get_comments_for('side-by-side', inline_comments, *line.modified.get_comment_args) %>
716 <% line_new_comments = get_comments_for('side-by-side', inline_comments, *line.modified.get_comment_args) %>
717 %else:
717 %else:
718 <% line_new_comments = None%>
718 <% line_new_comments = None%>
719 %endif
719 %endif
720 %if line_new_comments:
720 %if line_new_comments:
721 <% has_outdated = any([x.outdated for x in line_new_comments]) %>
721 <% has_outdated = any([x.outdated for x in line_new_comments]) %>
722 % if has_outdated:
722 % if has_outdated:
723 <i title="${_('comments including outdated')}:${len(line_new_comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
723 <i class="tooltip" title="${_('comments including outdated, click to show them')}:${len(line_new_comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
724 % else:
724 % else:
725 <i title="${_('comments')}: ${len(line_new_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
725 <i class="tooltip" title="${_('comments')}: ${len(line_new_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
726 % endif
726 % endif
727 %endif
727 %endif
728 </div>
728 </div>
729 </td>
729 </td>
730 <td class="cb-lineno ${action_class(line.modified.action)}"
730 <td class="cb-lineno ${action_class(line.modified.action)}"
731 data-line-no="${line.modified.lineno}"
731 data-line-no="${line.modified.lineno}"
732 %if new_line_anchor:
732 %if new_line_anchor:
733 id="${new_line_anchor}"
733 id="${new_line_anchor}"
734 %endif
734 %endif
735 >
735 >
736 %if line.modified.lineno:
736 %if line.modified.lineno:
737 <a name="${new_line_anchor}" href="#${new_line_anchor}">${line.modified.lineno}</a>
737 <a name="${new_line_anchor}" href="#${new_line_anchor}">${line.modified.lineno}</a>
738 %endif
738 %endif
739 </td>
739 </td>
740 <td class="cb-content ${action_class(line.modified.action)}"
740 <td class="cb-content ${action_class(line.modified.action)}"
741 data-line-no="n${line.modified.lineno}"
741 data-line-no="n${line.modified.lineno}"
742 >
742 >
743 %if use_comments and line.modified.lineno:
743 %if use_comments and line.modified.lineno:
744 ${render_add_comment_button()}
744 ${render_add_comment_button()}
745 %endif
745 %endif
746 <span class="cb-code"><span class="cb-action ${action_class(line.modified.action)}"></span>${line.modified.content or '' | n}</span>
746 <span class="cb-code"><span class="cb-action ${action_class(line.modified.action)}"></span>${line.modified.content or '' | n}</span>
747 %if use_comments and line.modified.lineno and line_new_comments:
747 %if use_comments and line.modified.lineno and line_new_comments:
748 ${inline_comments_container(line_new_comments, active_pattern_entries=active_pattern_entries)}
748 ${inline_comments_container(line_new_comments, active_pattern_entries=active_pattern_entries)}
749 %endif
749 %endif
750 </td>
750 </td>
751 </tr>
751 </tr>
752 %endfor
752 %endfor
753 </%def>
753 </%def>
754
754
755
755
756 <%def name="render_hunk_lines_unified(filediff, hunk, use_comments=False, inline_comments=None, active_pattern_entries=None)">
756 <%def name="render_hunk_lines_unified(filediff, hunk, use_comments=False, inline_comments=None, active_pattern_entries=None)">
757 %for old_line_no, new_line_no, action, content, comments_args in hunk.unified:
757 %for old_line_no, new_line_no, action, content, comments_args in hunk.unified:
758
758
759 <%
759 <%
760 old_line_anchor, new_line_anchor = None, None
760 old_line_anchor, new_line_anchor = None, None
761 if old_line_no:
761 if old_line_no:
762 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, old_line_no, 'o')
762 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, old_line_no, 'o')
763 if new_line_no:
763 if new_line_no:
764 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, new_line_no, 'n')
764 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, new_line_no, 'n')
765 %>
765 %>
766 <tr class="cb-line">
766 <tr class="cb-line">
767 <td class="cb-data ${action_class(action)}">
767 <td class="cb-data ${action_class(action)}">
768 <div>
768 <div>
769
769
770 %if comments_args:
770 %if comments_args:
771 <% comments = get_comments_for('unified', inline_comments, *comments_args) %>
771 <% comments = get_comments_for('unified', inline_comments, *comments_args) %>
772 %else:
772 %else:
773 <% comments = None %>
773 <% comments = None %>
774 %endif
774 %endif
775
775
776 % if comments:
776 % if comments:
777 <% has_outdated = any([x.outdated for x in comments]) %>
777 <% has_outdated = any([x.outdated for x in comments]) %>
778 % if has_outdated:
778 % if has_outdated:
779 <i title="${_('comments including outdated')}:${len(comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
779 <i class="tooltip" title="${_('comments including outdated, click to show them')}:${len(comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
780 % else:
780 % else:
781 <i title="${_('comments')}: ${len(comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
781 <i class="tooltip" title="${_('comments')}: ${len(comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
782 % endif
782 % endif
783 % endif
783 % endif
784 </div>
784 </div>
785 </td>
785 </td>
786 <td class="cb-lineno ${action_class(action)}"
786 <td class="cb-lineno ${action_class(action)}"
787 data-line-no="${old_line_no}"
787 data-line-no="${old_line_no}"
788 %if old_line_anchor:
788 %if old_line_anchor:
789 id="${old_line_anchor}"
789 id="${old_line_anchor}"
790 %endif
790 %endif
791 >
791 >
792 %if old_line_anchor:
792 %if old_line_anchor:
793 <a name="${old_line_anchor}" href="#${old_line_anchor}">${old_line_no}</a>
793 <a name="${old_line_anchor}" href="#${old_line_anchor}">${old_line_no}</a>
794 %endif
794 %endif
795 </td>
795 </td>
796 <td class="cb-lineno ${action_class(action)}"
796 <td class="cb-lineno ${action_class(action)}"
797 data-line-no="${new_line_no}"
797 data-line-no="${new_line_no}"
798 %if new_line_anchor:
798 %if new_line_anchor:
799 id="${new_line_anchor}"
799 id="${new_line_anchor}"
800 %endif
800 %endif
801 >
801 >
802 %if new_line_anchor:
802 %if new_line_anchor:
803 <a name="${new_line_anchor}" href="#${new_line_anchor}">${new_line_no}</a>
803 <a name="${new_line_anchor}" href="#${new_line_anchor}">${new_line_no}</a>
804 %endif
804 %endif
805 </td>
805 </td>
806 <td class="cb-content ${action_class(action)}"
806 <td class="cb-content ${action_class(action)}"
807 data-line-no="${(new_line_no and 'n' or 'o')}${(new_line_no or old_line_no)}"
807 data-line-no="${(new_line_no and 'n' or 'o')}${(new_line_no or old_line_no)}"
808 >
808 >
809 %if use_comments:
809 %if use_comments:
810 ${render_add_comment_button()}
810 ${render_add_comment_button()}
811 %endif
811 %endif
812 <span class="cb-code"><span class="cb-action ${action_class(action)}"></span> ${content or '' | n}</span>
812 <span class="cb-code"><span class="cb-action ${action_class(action)}"></span> ${content or '' | n}</span>
813 %if use_comments and comments:
813 %if use_comments and comments:
814 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
814 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries)}
815 %endif
815 %endif
816 </td>
816 </td>
817 </tr>
817 </tr>
818 %endfor
818 %endfor
819 </%def>
819 </%def>
820
820
821
821
822 <%def name="render_hunk_lines(filediff, diff_mode, hunk, use_comments, inline_comments, active_pattern_entries)">
822 <%def name="render_hunk_lines(filediff, diff_mode, hunk, use_comments, inline_comments, active_pattern_entries)">
823 % if diff_mode == 'unified':
823 % if diff_mode == 'unified':
824 ${render_hunk_lines_unified(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
824 ${render_hunk_lines_unified(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
825 % elif diff_mode == 'sideside':
825 % elif diff_mode == 'sideside':
826 ${render_hunk_lines_sideside(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
826 ${render_hunk_lines_sideside(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
827 % else:
827 % else:
828 <tr class="cb-line">
828 <tr class="cb-line">
829 <td>unknown diff mode</td>
829 <td>unknown diff mode</td>
830 </tr>
830 </tr>
831 % endif
831 % endif
832 </%def>file changes
832 </%def>file changes
833
833
834
834
835 <%def name="render_add_comment_button()">
835 <%def name="render_add_comment_button()">
836 <button class="btn btn-small btn-primary cb-comment-box-opener" onclick="return Rhodecode.comments.createComment(this)">
836 <button class="btn btn-small btn-primary cb-comment-box-opener" onclick="return Rhodecode.comments.createComment(this)">
837 <span><i class="icon-comment"></i></span>
837 <span><i class="icon-comment"></i></span>
838 </button>
838 </button>
839 </%def>
839 </%def>
840
840
841 <%def name="render_diffset_menu(diffset, range_diff_on=None)">
841 <%def name="render_diffset_menu(diffset, range_diff_on=None)">
842 <% diffset_container_id = h.md5(diffset.target_ref) %>
842 <% diffset_container_id = h.md5(diffset.target_ref) %>
843
843
844 <div id="diff-file-sticky" class="diffset-menu clearinner">
844 <div id="diff-file-sticky" class="diffset-menu clearinner">
845 ## auto adjustable
845 ## auto adjustable
846 <div class="sidebar__inner">
846 <div class="sidebar__inner">
847 <div class="sidebar__bar">
847 <div class="sidebar__bar">
848 <div class="pull-right">
848 <div class="pull-right">
849 <div class="btn-group">
849 <div class="btn-group">
850 <a class="btn tooltip toggle-wide-diff" href="#toggle-wide-diff" onclick="toggleWideDiff(this); return false" title="${h.tooltip(_('Toggle wide diff'))}">
850 <a class="btn tooltip toggle-wide-diff" href="#toggle-wide-diff" onclick="toggleWideDiff(this); return false" title="${h.tooltip(_('Toggle wide diff'))}">
851 <i class="icon-wide-mode"></i>
851 <i class="icon-wide-mode"></i>
852 </a>
852 </a>
853 </div>
853 </div>
854 <div class="btn-group">
854 <div class="btn-group">
855
855
856 <a
856 <a
857 class="btn ${(c.user_session_attrs["diffmode"] == 'sideside' and 'btn-active')} tooltip"
857 class="btn ${(c.user_session_attrs["diffmode"] == 'sideside' and 'btn-active')} tooltip"
858 title="${h.tooltip(_('View diff as side by side'))}"
858 title="${h.tooltip(_('View diff as side by side'))}"
859 href="${h.current_route_path(request, diffmode='sideside')}">
859 href="${h.current_route_path(request, diffmode='sideside')}">
860 <span>${_('Side by Side')}</span>
860 <span>${_('Side by Side')}</span>
861 </a>
861 </a>
862
862
863 <a
863 <a
864 class="btn ${(c.user_session_attrs["diffmode"] == 'unified' and 'btn-active')} tooltip"
864 class="btn ${(c.user_session_attrs["diffmode"] == 'unified' and 'btn-active')} tooltip"
865 title="${h.tooltip(_('View diff as unified'))}" href="${h.current_route_path(request, diffmode='unified')}">
865 title="${h.tooltip(_('View diff as unified'))}" href="${h.current_route_path(request, diffmode='unified')}">
866 <span>${_('Unified')}</span>
866 <span>${_('Unified')}</span>
867 </a>
867 </a>
868
868
869 % if range_diff_on is True:
869 % if range_diff_on is True:
870 <a
870 <a
871 title="${_('Turn off: Show the diff as commit range')}"
871 title="${_('Turn off: Show the diff as commit range')}"
872 class="btn btn-primary"
872 class="btn btn-primary"
873 href="${h.current_route_path(request, **{"range-diff":"0"})}">
873 href="${h.current_route_path(request, **{"range-diff":"0"})}">
874 <span>${_('Range Diff')}</span>
874 <span>${_('Range Diff')}</span>
875 </a>
875 </a>
876 % elif range_diff_on is False:
876 % elif range_diff_on is False:
877 <a
877 <a
878 title="${_('Show the diff as commit range')}"
878 title="${_('Show the diff as commit range')}"
879 class="btn"
879 class="btn"
880 href="${h.current_route_path(request, **{"range-diff":"1"})}">
880 href="${h.current_route_path(request, **{"range-diff":"1"})}">
881 <span>${_('Range Diff')}</span>
881 <span>${_('Range Diff')}</span>
882 </a>
882 </a>
883 % endif
883 % endif
884 </div>
884 </div>
885 <div class="btn-group">
885 <div class="btn-group">
886
886
887 <div class="pull-left">
887 <div class="pull-left">
888 ${h.hidden('diff_menu_{}'.format(diffset_container_id))}
888 ${h.hidden('diff_menu_{}'.format(diffset_container_id))}
889 </div>
889 </div>
890
890
891 </div>
891 </div>
892 </div>
892 </div>
893 <div class="pull-left">
893 <div class="pull-left">
894 <div class="btn-group">
894 <div class="btn-group">
895 <div class="pull-left">
895 <div class="pull-left">
896 ${h.hidden('file_filter_{}'.format(diffset_container_id))}
896 ${h.hidden('file_filter_{}'.format(diffset_container_id))}
897 </div>
897 </div>
898
898
899 </div>
899 </div>
900 </div>
900 </div>
901 </div>
901 </div>
902 <div class="fpath-placeholder">
902 <div class="fpath-placeholder">
903 <i class="icon-file-text"></i>
903 <i class="icon-file-text"></i>
904 <strong class="fpath-placeholder-text">
904 <strong class="fpath-placeholder-text">
905 Context file:
905 Context file:
906 </strong>
906 </strong>
907 </div>
907 </div>
908 <div class="sidebar_inner_shadow"></div>
908 <div class="sidebar_inner_shadow"></div>
909 </div>
909 </div>
910 </div>
910 </div>
911
911
912 % if diffset:
912 % if diffset:
913 %if diffset.limited_diff:
913 %if diffset.limited_diff:
914 <% file_placeholder = _ungettext('%(num)s file changed', '%(num)s files changed', diffset.changed_files) % {'num': diffset.changed_files} %>
914 <% file_placeholder = _ungettext('%(num)s file changed', '%(num)s files changed', diffset.changed_files) % {'num': diffset.changed_files} %>
915 %else:
915 %else:
916 <% file_placeholder = h.literal(_ungettext('%(num)s file changed: <span class="op-added">%(linesadd)s inserted</span>, <span class="op-deleted">%(linesdel)s deleted</span>', '%(num)s files changed: <span class="op-added">%(linesadd)s inserted</span>, <span class="op-deleted">%(linesdel)s deleted</span>',
916 <% file_placeholder = h.literal(_ungettext('%(num)s file changed: <span class="op-added">%(linesadd)s inserted</span>, <span class="op-deleted">%(linesdel)s deleted</span>', '%(num)s files changed: <span class="op-added">%(linesadd)s inserted</span>, <span class="op-deleted">%(linesdel)s deleted</span>',
917 diffset.changed_files) % {'num': diffset.changed_files, 'linesadd': diffset.lines_added, 'linesdel': diffset.lines_deleted}) %>
917 diffset.changed_files) % {'num': diffset.changed_files, 'linesadd': diffset.lines_added, 'linesdel': diffset.lines_deleted}) %>
918
918
919 %endif
919 %endif
920 ## case on range-diff placeholder needs to be updated
920 ## case on range-diff placeholder needs to be updated
921 % if range_diff_on is True:
921 % if range_diff_on is True:
922 <% file_placeholder = _('Disabled on range diff') %>
922 <% file_placeholder = _('Disabled on range diff') %>
923 % endif
923 % endif
924
924
925 <script type="text/javascript">
925 <script type="text/javascript">
926 var feedFilesOptions = function (query, initialData) {
926 var feedFilesOptions = function (query, initialData) {
927 var data = {results: []};
927 var data = {results: []};
928 var isQuery = typeof query.term !== 'undefined';
928 var isQuery = typeof query.term !== 'undefined';
929
929
930 var section = _gettext('Changed files');
930 var section = _gettext('Changed files');
931 var filteredData = [];
931 var filteredData = [];
932
932
933 //filter results
933 //filter results
934 $.each(initialData.results, function (idx, value) {
934 $.each(initialData.results, function (idx, value) {
935
935
936 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
936 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
937 filteredData.push({
937 filteredData.push({
938 'id': this.id,
938 'id': this.id,
939 'text': this.text,
939 'text': this.text,
940 "ops": this.ops,
940 "ops": this.ops,
941 })
941 })
942 }
942 }
943
943
944 });
944 });
945
945
946 data.results = filteredData;
946 data.results = filteredData;
947
947
948 query.callback(data);
948 query.callback(data);
949 };
949 };
950
950
951 var selectionFormatter = function(data, escapeMarkup) {
951 var selectionFormatter = function(data, escapeMarkup) {
952 var container = '<div class="filelist" style="padding-right:100px">{0}</div>';
952 var container = '<div class="filelist" style="padding-right:100px">{0}</div>';
953 var tmpl = '<div><strong>{0}</strong></div>'.format(escapeMarkup(data['text']));
953 var tmpl = '<div><strong>{0}</strong></div>'.format(escapeMarkup(data['text']));
954 var pill = '<div class="pill-group" style="position: absolute; top:7px; right: 0">' +
954 var pill = '<div class="pill-group" style="position: absolute; top:7px; right: 0">' +
955 '<span class="pill" op="added">{0}</span>' +
955 '<span class="pill" op="added">{0}</span>' +
956 '<span class="pill" op="deleted">{1}</span>' +
956 '<span class="pill" op="deleted">{1}</span>' +
957 '</div>'
957 '</div>'
958 ;
958 ;
959 var added = data['ops']['added'];
959 var added = data['ops']['added'];
960 if (added === 0) {
960 if (added === 0) {
961 // don't show +0
961 // don't show +0
962 added = 0;
962 added = 0;
963 } else {
963 } else {
964 added = '+' + added;
964 added = '+' + added;
965 }
965 }
966
966
967 var deleted = -1*data['ops']['deleted'];
967 var deleted = -1*data['ops']['deleted'];
968
968
969 tmpl += pill.format(added, deleted);
969 tmpl += pill.format(added, deleted);
970 return container.format(tmpl);
970 return container.format(tmpl);
971 };
971 };
972 var formatFileResult = function(result, container, query, escapeMarkup) {
972 var formatFileResult = function(result, container, query, escapeMarkup) {
973 return selectionFormatter(result, escapeMarkup);
973 return selectionFormatter(result, escapeMarkup);
974 };
974 };
975
975
976 var formatSelection = function (data, container) {
976 var formatSelection = function (data, container) {
977 return '${file_placeholder}'
977 return '${file_placeholder}'
978 };
978 };
979
979
980 if (window.preloadFileFilterData === undefined) {
980 if (window.preloadFileFilterData === undefined) {
981 window.preloadFileFilterData = {}
981 window.preloadFileFilterData = {}
982 }
982 }
983
983
984 preloadFileFilterData["${diffset_container_id}"] = {
984 preloadFileFilterData["${diffset_container_id}"] = {
985 results: [
985 results: [
986 % for filediff in diffset.files:
986 % for filediff in diffset.files:
987 {id:"a_${h.FID(filediff.raw_id, filediff.patch['filename'])}",
987 {id:"a_${h.FID(filediff.raw_id, filediff.patch['filename'])}",
988 text:"${filediff.patch['filename']}",
988 text:"${filediff.patch['filename']}",
989 ops:${h.json.dumps(filediff.patch['stats'])|n}}${('' if loop.last else ',')}
989 ops:${h.json.dumps(filediff.patch['stats'])|n}}${('' if loop.last else ',')}
990 % endfor
990 % endfor
991 ]
991 ]
992 };
992 };
993
993
994 var diffFileFilterId = "#file_filter_" + "${diffset_container_id}";
994 var diffFileFilterId = "#file_filter_" + "${diffset_container_id}";
995 var diffFileFilter = $(diffFileFilterId).select2({
995 var diffFileFilter = $(diffFileFilterId).select2({
996 'dropdownAutoWidth': true,
996 'dropdownAutoWidth': true,
997 'width': 'auto',
997 'width': 'auto',
998
998
999 containerCssClass: "drop-menu",
999 containerCssClass: "drop-menu",
1000 dropdownCssClass: "drop-menu-dropdown",
1000 dropdownCssClass: "drop-menu-dropdown",
1001 data: preloadFileFilterData["${diffset_container_id}"],
1001 data: preloadFileFilterData["${diffset_container_id}"],
1002 query: function(query) {
1002 query: function(query) {
1003 feedFilesOptions(query, preloadFileFilterData["${diffset_container_id}"]);
1003 feedFilesOptions(query, preloadFileFilterData["${diffset_container_id}"]);
1004 },
1004 },
1005 initSelection: function(element, callback) {
1005 initSelection: function(element, callback) {
1006 callback({'init': true});
1006 callback({'init': true});
1007 },
1007 },
1008 formatResult: formatFileResult,
1008 formatResult: formatFileResult,
1009 formatSelection: formatSelection
1009 formatSelection: formatSelection
1010 });
1010 });
1011
1011
1012 % if range_diff_on is True:
1012 % if range_diff_on is True:
1013 diffFileFilter.select2("enable", false);
1013 diffFileFilter.select2("enable", false);
1014 % endif
1014 % endif
1015
1015
1016 $(diffFileFilterId).on('select2-selecting', function (e) {
1016 $(diffFileFilterId).on('select2-selecting', function (e) {
1017 var idSelector = e.choice.id;
1017 var idSelector = e.choice.id;
1018
1018
1019 // expand the container if we quick-select the field
1019 // expand the container if we quick-select the field
1020 $('#'+idSelector).next().prop('checked', false);
1020 $('#'+idSelector).next().prop('checked', false);
1021 // hide the mast as we later do preventDefault()
1021 // hide the mast as we later do preventDefault()
1022 $("#select2-drop-mask").click();
1022 $("#select2-drop-mask").click();
1023
1023
1024 window.location.hash = '#'+idSelector;
1024 window.location.hash = '#'+idSelector;
1025 updateSticky();
1025 updateSticky();
1026
1026
1027 e.preventDefault();
1027 e.preventDefault();
1028 });
1028 });
1029
1029
1030 </script>
1030 </script>
1031 % endif
1031 % endif
1032
1032
1033 <script type="text/javascript">
1033 <script type="text/javascript">
1034 $(document).ready(function () {
1034 $(document).ready(function () {
1035
1035
1036 var contextPrefix = _gettext('Context file: ');
1036 var contextPrefix = _gettext('Context file: ');
1037 ## sticky sidebar
1037 ## sticky sidebar
1038 var sidebarElement = document.getElementById('diff-file-sticky');
1038 var sidebarElement = document.getElementById('diff-file-sticky');
1039 sidebar = new StickySidebar(sidebarElement, {
1039 sidebar = new StickySidebar(sidebarElement, {
1040 topSpacing: 0,
1040 topSpacing: 0,
1041 bottomSpacing: 0,
1041 bottomSpacing: 0,
1042 innerWrapperSelector: '.sidebar__inner'
1042 innerWrapperSelector: '.sidebar__inner'
1043 });
1043 });
1044 sidebarElement.addEventListener('affixed.static.stickySidebar', function () {
1044 sidebarElement.addEventListener('affixed.static.stickySidebar', function () {
1045 // reset our file so it's not holding new value
1045 // reset our file so it's not holding new value
1046 $('.fpath-placeholder-text').html(contextPrefix + ' - ')
1046 $('.fpath-placeholder-text').html(contextPrefix + ' - ')
1047 });
1047 });
1048
1048
1049 updateSticky = function () {
1049 updateSticky = function () {
1050 sidebar.updateSticky();
1050 sidebar.updateSticky();
1051 Waypoint.refreshAll();
1051 Waypoint.refreshAll();
1052 };
1052 };
1053
1053
1054 var animateText = function (fPath, anchorId) {
1054 var animateText = function (fPath, anchorId) {
1055 fPath = Select2.util.escapeMarkup(fPath);
1055 fPath = Select2.util.escapeMarkup(fPath);
1056 $('.fpath-placeholder-text').html(contextPrefix + '<a href="#a_' + anchorId + '">' + fPath + '</a>')
1056 $('.fpath-placeholder-text').html(contextPrefix + '<a href="#a_' + anchorId + '">' + fPath + '</a>')
1057 };
1057 };
1058
1058
1059 ## dynamic file waypoints
1059 ## dynamic file waypoints
1060 var setFPathInfo = function(fPath, anchorId){
1060 var setFPathInfo = function(fPath, anchorId){
1061 animateText(fPath, anchorId)
1061 animateText(fPath, anchorId)
1062 };
1062 };
1063
1063
1064 var codeBlock = $('.filediff');
1064 var codeBlock = $('.filediff');
1065
1065
1066 // forward waypoint
1066 // forward waypoint
1067 codeBlock.waypoint(
1067 codeBlock.waypoint(
1068 function(direction) {
1068 function(direction) {
1069 if (direction === "down"){
1069 if (direction === "down"){
1070 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
1070 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
1071 }
1071 }
1072 }, {
1072 }, {
1073 offset: function () {
1073 offset: function () {
1074 return 70;
1074 return 70;
1075 },
1075 },
1076 context: '.fpath-placeholder'
1076 context: '.fpath-placeholder'
1077 }
1077 }
1078 );
1078 );
1079
1079
1080 // backward waypoint
1080 // backward waypoint
1081 codeBlock.waypoint(
1081 codeBlock.waypoint(
1082 function(direction) {
1082 function(direction) {
1083 if (direction === "up"){
1083 if (direction === "up"){
1084 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
1084 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
1085 }
1085 }
1086 }, {
1086 }, {
1087 offset: function () {
1087 offset: function () {
1088 return -this.element.clientHeight + 90;
1088 return -this.element.clientHeight + 90;
1089 },
1089 },
1090 context: '.fpath-placeholder'
1090 context: '.fpath-placeholder'
1091 }
1091 }
1092 );
1092 );
1093
1093
1094 toggleWideDiff = function (el) {
1094 toggleWideDiff = function (el) {
1095 updateSticky();
1095 updateSticky();
1096 var wide = Rhodecode.comments.toggleWideMode(this);
1096 var wide = Rhodecode.comments.toggleWideMode(this);
1097 storeUserSessionAttr('rc_user_session_attr.wide_diff_mode', wide);
1097 storeUserSessionAttr('rc_user_session_attr.wide_diff_mode', wide);
1098 if (wide === true) {
1098 if (wide === true) {
1099 $(el).addClass('btn-active');
1099 $(el).addClass('btn-active');
1100 } else {
1100 } else {
1101 $(el).removeClass('btn-active');
1101 $(el).removeClass('btn-active');
1102 }
1102 }
1103 return null;
1103 return null;
1104 };
1104 };
1105
1105
1106 var preloadDiffMenuData = {
1106 var preloadDiffMenuData = {
1107 results: [
1107 results: [
1108
1108
1109 ## Whitespace change
1109 ## Whitespace change
1110 % if request.GET.get('ignorews', '') == '1':
1110 % if request.GET.get('ignorews', '') == '1':
1111 {
1111 {
1112 id: 2,
1112 id: 2,
1113 text: _gettext('Show whitespace changes'),
1113 text: _gettext('Show whitespace changes'),
1114 action: function () {},
1114 action: function () {},
1115 url: "${h.current_route_path(request, ignorews=0)|n}"
1115 url: "${h.current_route_path(request, ignorews=0)|n}"
1116 },
1116 },
1117 % else:
1117 % else:
1118 {
1118 {
1119 id: 2,
1119 id: 2,
1120 text: _gettext('Hide whitespace changes'),
1120 text: _gettext('Hide whitespace changes'),
1121 action: function () {},
1121 action: function () {},
1122 url: "${h.current_route_path(request, ignorews=1)|n}"
1122 url: "${h.current_route_path(request, ignorews=1)|n}"
1123 },
1123 },
1124 % endif
1124 % endif
1125
1125
1126 ## FULL CONTEXT
1126 ## FULL CONTEXT
1127 % if request.GET.get('fullcontext', '') == '1':
1127 % if request.GET.get('fullcontext', '') == '1':
1128 {
1128 {
1129 id: 3,
1129 id: 3,
1130 text: _gettext('Hide full context diff'),
1130 text: _gettext('Hide full context diff'),
1131 action: function () {},
1131 action: function () {},
1132 url: "${h.current_route_path(request, fullcontext=0)|n}"
1132 url: "${h.current_route_path(request, fullcontext=0)|n}"
1133 },
1133 },
1134 % else:
1134 % else:
1135 {
1135 {
1136 id: 3,
1136 id: 3,
1137 text: _gettext('Show full context diff'),
1137 text: _gettext('Show full context diff'),
1138 action: function () {},
1138 action: function () {},
1139 url: "${h.current_route_path(request, fullcontext=1)|n}"
1139 url: "${h.current_route_path(request, fullcontext=1)|n}"
1140 },
1140 },
1141 % endif
1141 % endif
1142
1142
1143 ]
1143 ]
1144 };
1144 };
1145
1145
1146 var diffMenuId = "#diff_menu_" + "${diffset_container_id}";
1146 var diffMenuId = "#diff_menu_" + "${diffset_container_id}";
1147 $(diffMenuId).select2({
1147 $(diffMenuId).select2({
1148 minimumResultsForSearch: -1,
1148 minimumResultsForSearch: -1,
1149 containerCssClass: "drop-menu-no-width",
1149 containerCssClass: "drop-menu-no-width",
1150 dropdownCssClass: "drop-menu-dropdown",
1150 dropdownCssClass: "drop-menu-dropdown",
1151 dropdownAutoWidth: true,
1151 dropdownAutoWidth: true,
1152 data: preloadDiffMenuData,
1152 data: preloadDiffMenuData,
1153 placeholder: "${_('...')}",
1153 placeholder: "${_('...')}",
1154 });
1154 });
1155 $(diffMenuId).on('select2-selecting', function (e) {
1155 $(diffMenuId).on('select2-selecting', function (e) {
1156 e.choice.action();
1156 e.choice.action();
1157 if (e.choice.url !== null) {
1157 if (e.choice.url !== null) {
1158 window.location = e.choice.url
1158 window.location = e.choice.url
1159 }
1159 }
1160 });
1160 });
1161 toggleExpand = function (el, diffsetEl) {
1161 toggleExpand = function (el, diffsetEl) {
1162 var el = $(el);
1162 var el = $(el);
1163 if (el.hasClass('collapsed')) {
1163 if (el.hasClass('collapsed')) {
1164 $('.filediff-collapse-state.collapse-{0}'.format(diffsetEl)).prop('checked', false);
1164 $('.filediff-collapse-state.collapse-{0}'.format(diffsetEl)).prop('checked', false);
1165 el.removeClass('collapsed');
1165 el.removeClass('collapsed');
1166 el.html(
1166 el.html(
1167 '<i class="icon-minus-squared-alt icon-no-margin"></i>' +
1167 '<i class="icon-minus-squared-alt icon-no-margin"></i>' +
1168 _gettext('Collapse all files'));
1168 _gettext('Collapse all files'));
1169 }
1169 }
1170 else {
1170 else {
1171 $('.filediff-collapse-state.collapse-{0}'.format(diffsetEl)).prop('checked', true);
1171 $('.filediff-collapse-state.collapse-{0}'.format(diffsetEl)).prop('checked', true);
1172 el.addClass('collapsed');
1172 el.addClass('collapsed');
1173 el.html(
1173 el.html(
1174 '<i class="icon-plus-squared-alt icon-no-margin"></i>' +
1174 '<i class="icon-plus-squared-alt icon-no-margin"></i>' +
1175 _gettext('Expand all files'));
1175 _gettext('Expand all files'));
1176 }
1176 }
1177 updateSticky()
1177 updateSticky()
1178 };
1178 };
1179
1179
1180 toggleCommitExpand = function (el) {
1180 toggleCommitExpand = function (el) {
1181 var $el = $(el);
1181 var $el = $(el);
1182 var commits = $el.data('toggleCommitsCnt');
1182 var commits = $el.data('toggleCommitsCnt');
1183 var collapseMsg = _ngettext('Collapse {0} commit', 'Collapse {0} commits', commits).format(commits);
1183 var collapseMsg = _ngettext('Collapse {0} commit', 'Collapse {0} commits', commits).format(commits);
1184 var expandMsg = _ngettext('Expand {0} commit', 'Expand {0} commits', commits).format(commits);
1184 var expandMsg = _ngettext('Expand {0} commit', 'Expand {0} commits', commits).format(commits);
1185
1185
1186 if ($el.hasClass('collapsed')) {
1186 if ($el.hasClass('collapsed')) {
1187 $('.compare_select').show();
1187 $('.compare_select').show();
1188 $('.compare_select_hidden').hide();
1188 $('.compare_select_hidden').hide();
1189
1189
1190 $el.removeClass('collapsed');
1190 $el.removeClass('collapsed');
1191 $el.html(
1191 $el.html(
1192 '<i class="icon-minus-squared-alt icon-no-margin"></i>' +
1192 '<i class="icon-minus-squared-alt icon-no-margin"></i>' +
1193 collapseMsg);
1193 collapseMsg);
1194 }
1194 }
1195 else {
1195 else {
1196 $('.compare_select').hide();
1196 $('.compare_select').hide();
1197 $('.compare_select_hidden').show();
1197 $('.compare_select_hidden').show();
1198 $el.addClass('collapsed');
1198 $el.addClass('collapsed');
1199 $el.html(
1199 $el.html(
1200 '<i class="icon-plus-squared-alt icon-no-margin"></i>' +
1200 '<i class="icon-plus-squared-alt icon-no-margin"></i>' +
1201 expandMsg);
1201 expandMsg);
1202 }
1202 }
1203 updateSticky();
1203 updateSticky();
1204 };
1204 };
1205
1205
1206 // get stored diff mode and pre-enable it
1206 // get stored diff mode and pre-enable it
1207 if (templateContext.session_attrs.wide_diff_mode === "true") {
1207 if (templateContext.session_attrs.wide_diff_mode === "true") {
1208 Rhodecode.comments.toggleWideMode(null);
1208 Rhodecode.comments.toggleWideMode(null);
1209 $('.toggle-wide-diff').addClass('btn-active');
1209 $('.toggle-wide-diff').addClass('btn-active');
1210 updateSticky();
1210 updateSticky();
1211 }
1211 }
1212 });
1212 });
1213 </script>
1213 </script>
1214
1214
1215 </%def>
1215 </%def>
General Comments 0
You need to be logged in to leave comments. Login now