##// END OF EJS Templates
diffs: make line anchors commit aware. This fixes duplicate anchor problem on range diffs.
marcink -
r3131:5d8c725f default
parent child Browse files
Show More
@@ -1,970 +1,971 b''
1 1 <%namespace name="commentblock" file="/changeset/changeset_file_comment.mako"/>
2 2
3 <%def name="diff_line_anchor(filename, line, type)"><%
4 return '%s_%s_%i' % (h.safeid(filename), type, line)
3 <%def name="diff_line_anchor(commit, filename, line, type)"><%
4 return '%s_%s_%i' % (h.md5_safe(commit+filename), type, line)
5 5 %></%def>
6 6
7 7 <%def name="action_class(action)">
8 8 <%
9 9 return {
10 10 '-': 'cb-deletion',
11 11 '+': 'cb-addition',
12 12 ' ': 'cb-context',
13 13 }.get(action, 'cb-empty')
14 14 %>
15 15 </%def>
16 16
17 17 <%def name="op_class(op_id)">
18 18 <%
19 19 return {
20 20 DEL_FILENODE: 'deletion', # file deleted
21 21 BIN_FILENODE: 'warning' # binary diff hidden
22 22 }.get(op_id, 'addition')
23 23 %>
24 24 </%def>
25 25
26 26
27 27
28 28 <%def name="render_diffset(diffset, commit=None,
29 29
30 30 # collapse all file diff entries when there are more than this amount of files in the diff
31 31 collapse_when_files_over=20,
32 32
33 33 # collapse lines in the diff when more than this amount of lines changed in the file diff
34 34 lines_changed_limit=500,
35 35
36 36 # add a ruler at to the output
37 37 ruler_at_chars=0,
38 38
39 39 # show inline comments
40 40 use_comments=False,
41 41
42 42 # disable new comments
43 43 disable_new_comments=False,
44 44
45 45 # special file-comments that were deleted in previous versions
46 46 # it's used for showing outdated comments for deleted files in a PR
47 47 deleted_files_comments=None,
48 48
49 49 # for cache purpose
50 50 inline_comments=None,
51 51
52 52 )">
53 53 %if use_comments:
54 54 <div id="cb-comments-inline-container-template" class="js-template">
55 55 ${inline_comments_container([], inline_comments)}
56 56 </div>
57 57 <div class="js-template" id="cb-comment-inline-form-template">
58 58 <div class="comment-inline-form ac">
59 59
60 60 %if c.rhodecode_user.username != h.DEFAULT_USER:
61 61 ## render template for inline comments
62 62 ${commentblock.comment_form(form_type='inline')}
63 63 %else:
64 64 ${h.form('', class_='inline-form comment-form-login', method='get')}
65 65 <div class="pull-left">
66 66 <div class="comment-help pull-right">
67 67 ${_('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>
68 68 </div>
69 69 </div>
70 70 <div class="comment-button pull-right">
71 71 <button type="button" class="cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
72 72 ${_('Cancel')}
73 73 </button>
74 74 </div>
75 75 <div class="clearfix"></div>
76 76 ${h.end_form()}
77 77 %endif
78 78 </div>
79 79 </div>
80 80
81 81 %endif
82 82 <%
83 83 collapse_all = len(diffset.files) > collapse_when_files_over
84 84 %>
85 85
86 86 %if c.user_session_attrs["diffmode"] == 'sideside':
87 87 <style>
88 88 .wrapper {
89 89 max-width: 1600px !important;
90 90 }
91 91 </style>
92 92 %endif
93 93
94 94 %if ruler_at_chars:
95 95 <style>
96 96 .diff table.cb .cb-content:after {
97 97 content: "";
98 98 border-left: 1px solid blue;
99 99 position: absolute;
100 100 top: 0;
101 101 height: 18px;
102 102 opacity: .2;
103 103 z-index: 10;
104 104 //## +5 to account for diff action (+/-)
105 105 left: ${ruler_at_chars + 5}ch;
106 106 </style>
107 107 %endif
108 108
109 109 <div class="diffset ${disable_new_comments and 'diffset-comments-disabled'}">
110 110 <div class="diffset-heading ${diffset.limited_diff and 'diffset-heading-warning' or ''}">
111 111 %if commit:
112 112 <div class="pull-right">
113 113 <a class="btn tooltip" title="${h.tooltip(_('Browse Files at revision {}').format(commit.raw_id))}" href="${h.route_path('repo_files',repo_name=diffset.repo_name, commit_id=commit.raw_id, f_path='')}">
114 114 ${_('Browse Files')}
115 115 </a>
116 116 </div>
117 117 %endif
118 118 <h2 class="clearinner">
119 119 ## invidual commit
120 120 % if commit:
121 121 <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> -
122 122 ${h.age_component(commit.date)}
123 123 % if diffset.limited_diff:
124 124 - ${_('The requested commit is too big and content was truncated.')}
125 125 ${_ungettext('%(num)s file changed.', '%(num)s files changed.', diffset.changed_files) % {'num': diffset.changed_files}}
126 126 <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>
127 127 % elif hasattr(c, 'commit_ranges') and len(c.commit_ranges) > 1:
128 128 ## compare diff, has no file-selector and we want to show stats anyway
129 129 ${_ungettext('{num} file changed: {linesadd} inserted, ''{linesdel} deleted',
130 130 '{num} files changed: {linesadd} inserted, {linesdel} deleted', diffset.changed_files) \
131 131 .format(num=diffset.changed_files, linesadd=diffset.lines_added, linesdel=diffset.lines_deleted)}
132 132 % endif
133 133 % else:
134 134 ## pull requests/compare
135 135 ${_('File Changes')}
136 136 % endif
137 137
138 138 </h2>
139 139 </div>
140 140
141 141 %if diffset.has_hidden_changes:
142 142 <p class="empty_data">${_('Some changes may be hidden')}</p>
143 143 %elif not diffset.files:
144 144 <p class="empty_data">${_('No files')}</p>
145 145 %endif
146 146
147 147 <div class="filediffs">
148 148
149 149 ## initial value could be marked as False later on
150 150 <% over_lines_changed_limit = False %>
151 151 %for i, filediff in enumerate(diffset.files):
152 152
153 153 <%
154 154 lines_changed = filediff.patch['stats']['added'] + filediff.patch['stats']['deleted']
155 155 over_lines_changed_limit = lines_changed > lines_changed_limit
156 156 %>
157 157 ## anchor with support of sticky header
158 158 <div class="anchor" id="a_${h.FID(filediff.raw_id, filediff.patch['filename'])}"></div>
159 159
160 160 <input ${(collapse_all and 'checked' or '')} class="filediff-collapse-state" id="filediff-collapse-${id(filediff)}" type="checkbox" onchange="updateSticky();">
161 161 <div
162 162 class="filediff"
163 163 data-f-path="${filediff.patch['filename']}"
164 164 data-anchor-id="${h.FID(filediff.raw_id, filediff.patch['filename'])}"
165 165 >
166 166 <label for="filediff-collapse-${id(filediff)}" class="filediff-heading">
167 167 <div class="filediff-collapse-indicator"></div>
168 168 ${diff_ops(filediff)}
169 169 </label>
170 170
171 171 ${diff_menu(filediff, use_comments=use_comments)}
172 172 <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 '')}">
173 173
174 174 ## new/deleted/empty content case
175 175 % if not filediff.hunks:
176 176 ## Comment container, on "fakes" hunk that contains all data to render comments
177 ${render_hunk_lines(c.user_session_attrs["diffmode"], filediff.hunk_ops, use_comments=use_comments, inline_comments=inline_comments)}
177 ${render_hunk_lines(filediff, c.user_session_attrs["diffmode"], filediff.hunk_ops, use_comments=use_comments, inline_comments=inline_comments)}
178 178 % endif
179 179
180 180 %if filediff.limited_diff:
181 181 <tr class="cb-warning cb-collapser">
182 182 <td class="cb-text" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=6')}>
183 183 ${_('The requested commit 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>
184 184 </td>
185 185 </tr>
186 186 %else:
187 187 %if over_lines_changed_limit:
188 188 <tr class="cb-warning cb-collapser">
189 189 <td class="cb-text" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=6')}>
190 190 ${_('This diff has been collapsed as it changes many lines, (%i lines changed)' % lines_changed)}
191 191 <a href="#" class="cb-expand"
192 192 onclick="$(this).closest('table').removeClass('cb-collapsed'); updateSticky(); return false;">${_('Show them')}
193 193 </a>
194 194 <a href="#" class="cb-collapse"
195 195 onclick="$(this).closest('table').addClass('cb-collapsed'); updateSticky(); return false;">${_('Hide them')}
196 196 </a>
197 197 </td>
198 198 </tr>
199 199 %endif
200 200 %endif
201 201
202 202 % for hunk in filediff.hunks:
203 203 <tr class="cb-hunk">
204 204 <td ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=3' or '')}>
205 205 ## TODO: dan: add ajax loading of more context here
206 206 ## <a href="#">
207 207 <i class="icon-more"></i>
208 208 ## </a>
209 209 </td>
210 210 <td ${(c.user_session_attrs["diffmode"] == 'sideside' and 'colspan=5' or '')}>
211 211 @@
212 212 -${hunk.source_start},${hunk.source_length}
213 213 +${hunk.target_start},${hunk.target_length}
214 214 ${hunk.section_header}
215 215 </td>
216 216 </tr>
217 ${render_hunk_lines(c.user_session_attrs["diffmode"], hunk, use_comments=use_comments, inline_comments=inline_comments)}
217 ${render_hunk_lines(filediff, c.user_session_attrs["diffmode"], hunk, use_comments=use_comments, inline_comments=inline_comments)}
218 218 % endfor
219 219
220 220 <% unmatched_comments = (inline_comments or {}).get(filediff.patch['filename'], {}) %>
221 221
222 222 ## outdated comments that do not fit into currently displayed lines
223 223 % for lineno, comments in unmatched_comments.items():
224 224
225 225 %if c.user_session_attrs["diffmode"] == 'unified':
226 226 % if loop.index == 0:
227 227 <tr class="cb-hunk">
228 228 <td colspan="3"></td>
229 229 <td>
230 230 <div>
231 231 ${_('Unmatched inline comments below')}
232 232 </div>
233 233 </td>
234 234 </tr>
235 235 % endif
236 236 <tr class="cb-line">
237 237 <td class="cb-data cb-context"></td>
238 238 <td class="cb-lineno cb-context"></td>
239 239 <td class="cb-lineno cb-context"></td>
240 240 <td class="cb-content cb-context">
241 241 ${inline_comments_container(comments, inline_comments)}
242 242 </td>
243 243 </tr>
244 244 %elif c.user_session_attrs["diffmode"] == 'sideside':
245 245 % if loop.index == 0:
246 246 <tr class="cb-comment-info">
247 247 <td colspan="2"></td>
248 248 <td class="cb-line">
249 249 <div>
250 250 ${_('Unmatched inline comments below')}
251 251 </div>
252 252 </td>
253 253 <td colspan="2"></td>
254 254 <td class="cb-line">
255 255 <div>
256 256 ${_('Unmatched comments below')}
257 257 </div>
258 258 </td>
259 259 </tr>
260 260 % endif
261 261 <tr class="cb-line">
262 262 <td class="cb-data cb-context"></td>
263 263 <td class="cb-lineno cb-context"></td>
264 264 <td class="cb-content cb-context">
265 265 % if lineno.startswith('o'):
266 266 ${inline_comments_container(comments, inline_comments)}
267 267 % endif
268 268 </td>
269 269
270 270 <td class="cb-data cb-context"></td>
271 271 <td class="cb-lineno cb-context"></td>
272 272 <td class="cb-content cb-context">
273 273 % if lineno.startswith('n'):
274 274 ${inline_comments_container(comments, inline_comments)}
275 275 % endif
276 276 </td>
277 277 </tr>
278 278 %endif
279 279
280 280 % endfor
281 281
282 282 </table>
283 283 </div>
284 284 %endfor
285 285
286 286 ## outdated comments that are made for a file that has been deleted
287 287 % for filename, comments_dict in (deleted_files_comments or {}).items():
288 288 <%
289 289 display_state = 'display: none'
290 290 open_comments_in_file = [x for x in comments_dict['comments'] if x.outdated is False]
291 291 if open_comments_in_file:
292 292 display_state = ''
293 293 %>
294 294 <div class="filediffs filediff-outdated" style="${display_state}">
295 295 <input ${(collapse_all and 'checked' or '')} class="filediff-collapse-state" id="filediff-collapse-${id(filename)}" type="checkbox" onchange="updateSticky();">
296 296 <div class="filediff" data-f-path="${filename}" id="a_${h.FID(filediff.raw_id, filename)}">
297 297 <label for="filediff-collapse-${id(filename)}" class="filediff-heading">
298 298 <div class="filediff-collapse-indicator"></div>
299 299 <span class="pill">
300 300 ## file was deleted
301 301 <strong>${filename}</strong>
302 302 </span>
303 303 <span class="pill-group" style="float: left">
304 304 ## file op, doesn't need translation
305 305 <span class="pill" op="removed">removed in this version</span>
306 306 </span>
307 307 <a class="pill filediff-anchor" href="#a_${h.FID(filediff.raw_id, filename)}">ΒΆ</a>
308 308 <span class="pill-group" style="float: right">
309 309 <span class="pill" op="deleted">-${comments_dict['stats']}</span>
310 310 </span>
311 311 </label>
312 312
313 313 <table class="cb cb-diff-${c.user_session_attrs["diffmode"]} code-highlight ${over_lines_changed_limit and 'cb-collapsed' or ''}">
314 314 <tr>
315 315 % if c.user_session_attrs["diffmode"] == 'unified':
316 316 <td></td>
317 317 %endif
318 318
319 319 <td></td>
320 320 <td class="cb-text cb-${op_class(BIN_FILENODE)}" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=5')}>
321 321 ${_('File was deleted in this version. There are still outdated/unresolved comments attached to it.')}
322 322 </td>
323 323 </tr>
324 324 %if c.user_session_attrs["diffmode"] == 'unified':
325 325 <tr class="cb-line">
326 326 <td class="cb-data cb-context"></td>
327 327 <td class="cb-lineno cb-context"></td>
328 328 <td class="cb-lineno cb-context"></td>
329 329 <td class="cb-content cb-context">
330 330 ${inline_comments_container(comments_dict['comments'], inline_comments)}
331 331 </td>
332 332 </tr>
333 333 %elif c.user_session_attrs["diffmode"] == 'sideside':
334 334 <tr class="cb-line">
335 335 <td class="cb-data cb-context"></td>
336 336 <td class="cb-lineno cb-context"></td>
337 337 <td class="cb-content cb-context"></td>
338 338
339 339 <td class="cb-data cb-context"></td>
340 340 <td class="cb-lineno cb-context"></td>
341 341 <td class="cb-content cb-context">
342 342 ${inline_comments_container(comments_dict['comments'], inline_comments)}
343 343 </td>
344 344 </tr>
345 345 %endif
346 346 </table>
347 347 </div>
348 348 </div>
349 349 % endfor
350 350
351 351 </div>
352 352 </div>
353 353 </%def>
354 354
355 355 <%def name="diff_ops(filediff)">
356 356 <%
357 357 from rhodecode.lib.diffs import NEW_FILENODE, DEL_FILENODE, \
358 358 MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE
359 359 %>
360 360 <span class="pill">
361 361 %if filediff.source_file_path and filediff.target_file_path:
362 362 %if filediff.source_file_path != filediff.target_file_path:
363 363 ## file was renamed, or copied
364 364 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
365 365 <strong>${filediff.target_file_path}</strong> β¬… <del>${filediff.source_file_path}</del>
366 366 <% final_path = filediff.target_file_path %>
367 367 %elif COPIED_FILENODE in filediff.patch['stats']['ops']:
368 368 <strong>${filediff.target_file_path}</strong> β¬… ${filediff.source_file_path}
369 369 <% final_path = filediff.target_file_path %>
370 370 %endif
371 371 %else:
372 372 ## file was modified
373 373 <strong>${filediff.source_file_path}</strong>
374 374 <% final_path = filediff.source_file_path %>
375 375 %endif
376 376 %else:
377 377 %if filediff.source_file_path:
378 378 ## file was deleted
379 379 <strong>${filediff.source_file_path}</strong>
380 380 <% final_path = filediff.source_file_path %>
381 381 %else:
382 382 ## file was added
383 383 <strong>${filediff.target_file_path}</strong>
384 384 <% final_path = filediff.target_file_path %>
385 385 %endif
386 386 %endif
387 387 <i style="color: #aaa" class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${final_path}" title="${_('Copy the full path')}" onclick="return false;"></i>
388 388 </span>
389 389 ## anchor link
390 390 <a class="pill filediff-anchor" href="#a_${h.FID(filediff.raw_id, filediff.patch['filename'])}">ΒΆ</a>
391 391
392 392 <span class="pill-group" style="float: right">
393 393
394 394 ## ops pills
395 395 %if filediff.limited_diff:
396 396 <span class="pill tooltip" op="limited" title="The stats for this diff are not complete">limited diff</span>
397 397 %endif
398 398
399 399 %if NEW_FILENODE in filediff.patch['stats']['ops']:
400 400 <span class="pill" op="created">created</span>
401 401 %if filediff['target_mode'].startswith('120'):
402 402 <span class="pill" op="symlink">symlink</span>
403 403 %else:
404 404 <span class="pill" op="mode">${nice_mode(filediff['target_mode'])}</span>
405 405 %endif
406 406 %endif
407 407
408 408 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
409 409 <span class="pill" op="renamed">renamed</span>
410 410 %endif
411 411
412 412 %if COPIED_FILENODE in filediff.patch['stats']['ops']:
413 413 <span class="pill" op="copied">copied</span>
414 414 %endif
415 415
416 416 %if DEL_FILENODE in filediff.patch['stats']['ops']:
417 417 <span class="pill" op="removed">removed</span>
418 418 %endif
419 419
420 420 %if CHMOD_FILENODE in filediff.patch['stats']['ops']:
421 421 <span class="pill" op="mode">
422 422 ${nice_mode(filediff['source_mode'])} ➑ ${nice_mode(filediff['target_mode'])}
423 423 </span>
424 424 %endif
425 425
426 426 %if BIN_FILENODE in filediff.patch['stats']['ops']:
427 427 <span class="pill" op="binary">binary</span>
428 428 %if MOD_FILENODE in filediff.patch['stats']['ops']:
429 429 <span class="pill" op="modified">modified</span>
430 430 %endif
431 431 %endif
432 432
433 433 <span class="pill" op="added">${('+' if filediff.patch['stats']['added'] else '')}${filediff.patch['stats']['added']}</span>
434 434 <span class="pill" op="deleted">${((h.safe_int(filediff.patch['stats']['deleted']) or 0) * -1)}</span>
435 435
436 436 </span>
437 437
438 438 </%def>
439 439
440 440 <%def name="nice_mode(filemode)">
441 441 ${(filemode.startswith('100') and filemode[3:] or filemode)}
442 442 </%def>
443 443
444 444 <%def name="diff_menu(filediff, use_comments=False)">
445 445 <div class="filediff-menu">
446 446 %if filediff.diffset.source_ref:
447 447 %if filediff.operation in ['D', 'M']:
448 448 <a
449 449 class="tooltip"
450 450 href="${h.route_path('repo_files',repo_name=filediff.diffset.repo_name,commit_id=filediff.diffset.source_ref,f_path=filediff.source_file_path)}"
451 451 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
452 452 >
453 453 ${_('Show file before')}
454 454 </a> |
455 455 %else:
456 456 <span
457 457 class="tooltip"
458 458 title="${h.tooltip(_('File no longer present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
459 459 >
460 460 ${_('Show file before')}
461 461 </span> |
462 462 %endif
463 463 %if filediff.operation in ['A', 'M']:
464 464 <a
465 465 class="tooltip"
466 466 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)}"
467 467 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
468 468 >
469 469 ${_('Show file after')}
470 470 </a> |
471 471 %else:
472 472 <span
473 473 class="tooltip"
474 474 title="${h.tooltip(_('File no longer present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
475 475 >
476 476 ${_('Show file after')}
477 477 </span> |
478 478 %endif
479 479 <a
480 480 class="tooltip"
481 481 title="${h.tooltip(_('Raw diff'))}"
482 482 href="${h.route_path('repo_files_diff',repo_name=filediff.diffset.repo_name,f_path=filediff.target_file_path, _query=dict(diff2=filediff.diffset.target_ref,diff1=filediff.diffset.source_ref,diff='raw'))}"
483 483 >
484 484 ${_('Raw diff')}
485 485 </a> |
486 486 <a
487 487 class="tooltip"
488 488 title="${h.tooltip(_('Download diff'))}"
489 489 href="${h.route_path('repo_files_diff',repo_name=filediff.diffset.repo_name,f_path=filediff.target_file_path, _query=dict(diff2=filediff.diffset.target_ref,diff1=filediff.diffset.source_ref,diff='download'))}"
490 490 >
491 491 ${_('Download diff')}
492 492 </a>
493 493 % if use_comments:
494 494 |
495 495 % endif
496 496
497 497 ## 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)
498 498 %if hasattr(c, 'ignorews_url'):
499 499 ${c.ignorews_url(request, h.FID(filediff.raw_id, filediff.patch['filename']))}
500 500 %endif
501 501 %if hasattr(c, 'context_url'):
502 502 ${c.context_url(request, h.FID(filediff.raw_id, filediff.patch['filename']))}
503 503 %endif
504 504
505 505 %if use_comments:
506 506 <a href="#" onclick="return Rhodecode.comments.toggleComments(this);">
507 507 <span class="show-comment-button">${_('Show comments')}</span><span class="hide-comment-button">${_('Hide comments')}</span>
508 508 </a>
509 509 %endif
510 510 %endif
511 511 </div>
512 512 </%def>
513 513
514 514
515 515 <%def name="inline_comments_container(comments, inline_comments)">
516 516 <div class="inline-comments">
517 517 %for comment in comments:
518 518 ${commentblock.comment_block(comment, inline=True)}
519 519 %endfor
520 520 % if comments and comments[-1].outdated:
521 521 <span class="btn btn-secondary cb-comment-add-button comment-outdated}"
522 522 style="display: none;}">
523 523 ${_('Add another comment')}
524 524 </span>
525 525 % else:
526 526 <span onclick="return Rhodecode.comments.createComment(this)"
527 527 class="btn btn-secondary cb-comment-add-button">
528 528 ${_('Add another comment')}
529 529 </span>
530 530 % endif
531 531
532 532 </div>
533 533 </%def>
534 534
535 535 <%!
536 536 def get_comments_for(diff_type, comments, filename, line_version, line_number):
537 537 if hasattr(filename, 'unicode_path'):
538 538 filename = filename.unicode_path
539 539
540 540 if not isinstance(filename, basestring):
541 541 return None
542 542
543 543 line_key = '{}{}'.format(line_version, line_number) ## e.g o37, n12
544 544
545 545 if comments and filename in comments:
546 546 file_comments = comments[filename]
547 547 if line_key in file_comments:
548 548 data = file_comments.pop(line_key)
549 549 return data
550 550 %>
551 551
552 <%def name="render_hunk_lines_sideside(hunk, use_comments=False, inline_comments=None)">
553
552 <%def name="render_hunk_lines_sideside(filediff, hunk, use_comments=False, inline_comments=None)">
554 553 %for i, line in enumerate(hunk.sideside):
555 554 <%
556 555 old_line_anchor, new_line_anchor = None, None
556
557 557 if line.original.lineno:
558 old_line_anchor = diff_line_anchor(hunk.source_file_path, line.original.lineno, 'o')
558 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, line.original.lineno, 'o')
559 559 if line.modified.lineno:
560 new_line_anchor = diff_line_anchor(hunk.target_file_path, line.modified.lineno, 'n')
560 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, line.modified.lineno, 'n')
561 561 %>
562 562
563 563 <tr class="cb-line">
564 564 <td class="cb-data ${action_class(line.original.action)}"
565 565 data-line-no="${line.original.lineno}"
566 566 >
567 567 <div>
568 568
569 569 <% line_old_comments = None %>
570 570 %if line.original.get_comment_args:
571 571 <% line_old_comments = get_comments_for('side-by-side', inline_comments, *line.original.get_comment_args) %>
572 572 %endif
573 573 %if line_old_comments:
574 574 <% has_outdated = any([x.outdated for x in line_old_comments]) %>
575 575 % if has_outdated:
576 576 <i title="${_('comments including outdated')}:${len(line_old_comments)}" class="icon-comment_toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
577 577 % else:
578 578 <i title="${_('comments')}: ${len(line_old_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
579 579 % endif
580 580 %endif
581 581 </div>
582 582 </td>
583 583 <td class="cb-lineno ${action_class(line.original.action)}"
584 584 data-line-no="${line.original.lineno}"
585 585 %if old_line_anchor:
586 586 id="${old_line_anchor}"
587 587 %endif
588 588 >
589 589 %if line.original.lineno:
590 590 <a name="${old_line_anchor}" href="#${old_line_anchor}">${line.original.lineno}</a>
591 591 %endif
592 592 </td>
593 593 <td class="cb-content ${action_class(line.original.action)}"
594 594 data-line-no="o${line.original.lineno}"
595 595 >
596 596 %if use_comments and line.original.lineno:
597 597 ${render_add_comment_button()}
598 598 %endif
599 599 <span class="cb-code">${line.original.action} ${line.original.content or '' | n}</span>
600 600
601 601 %if use_comments and line.original.lineno and line_old_comments:
602 602 ${inline_comments_container(line_old_comments, inline_comments)}
603 603 %endif
604 604
605 605 </td>
606 606 <td class="cb-data ${action_class(line.modified.action)}"
607 607 data-line-no="${line.modified.lineno}"
608 608 >
609 609 <div>
610 610
611 611 %if line.modified.get_comment_args:
612 612 <% line_new_comments = get_comments_for('side-by-side', inline_comments, *line.modified.get_comment_args) %>
613 613 %else:
614 614 <% line_new_comments = None%>
615 615 %endif
616 616 %if line_new_comments:
617 617 <% has_outdated = any([x.outdated for x in line_new_comments]) %>
618 618 % if has_outdated:
619 619 <i title="${_('comments including outdated')}:${len(line_new_comments)}" class="icon-comment_toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
620 620 % else:
621 621 <i title="${_('comments')}: ${len(line_new_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
622 622 % endif
623 623 %endif
624 624 </div>
625 625 </td>
626 626 <td class="cb-lineno ${action_class(line.modified.action)}"
627 627 data-line-no="${line.modified.lineno}"
628 628 %if new_line_anchor:
629 629 id="${new_line_anchor}"
630 630 %endif
631 631 >
632 632 %if line.modified.lineno:
633 633 <a name="${new_line_anchor}" href="#${new_line_anchor}">${line.modified.lineno}</a>
634 634 %endif
635 635 </td>
636 636 <td class="cb-content ${action_class(line.modified.action)}"
637 637 data-line-no="n${line.modified.lineno}"
638 638 >
639 639 %if use_comments and line.modified.lineno:
640 640 ${render_add_comment_button()}
641 641 %endif
642 642 <span class="cb-code">${line.modified.action} ${line.modified.content or '' | n}</span>
643 643 %if use_comments and line.modified.lineno and line_new_comments:
644 644 ${inline_comments_container(line_new_comments, inline_comments)}
645 645 %endif
646 646 </td>
647 647 </tr>
648 648 %endfor
649 649 </%def>
650 650
651 651
652 <%def name="render_hunk_lines_unified(hunk, use_comments=False, inline_comments=None)">
652 <%def name="render_hunk_lines_unified(filediff, hunk, use_comments=False, inline_comments=None)">
653 653 %for old_line_no, new_line_no, action, content, comments_args in hunk.unified:
654
654 655 <%
655 656 old_line_anchor, new_line_anchor = None, None
656 657 if old_line_no:
657 old_line_anchor = diff_line_anchor(hunk.source_file_path, old_line_no, 'o')
658 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, old_line_no, 'o')
658 659 if new_line_no:
659 new_line_anchor = diff_line_anchor(hunk.target_file_path, new_line_no, 'n')
660 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, new_line_no, 'n')
660 661 %>
661 662 <tr class="cb-line">
662 663 <td class="cb-data ${action_class(action)}">
663 664 <div>
664 665
665 666 %if comments_args:
666 667 <% comments = get_comments_for('unified', inline_comments, *comments_args) %>
667 668 %else:
668 669 <% comments = None %>
669 670 %endif
670 671
671 672 % if comments:
672 673 <% has_outdated = any([x.outdated for x in comments]) %>
673 674 % if has_outdated:
674 675 <i title="${_('comments including outdated')}:${len(comments)}" class="icon-comment_toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
675 676 % else:
676 677 <i title="${_('comments')}: ${len(comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
677 678 % endif
678 679 % endif
679 680 </div>
680 681 </td>
681 682 <td class="cb-lineno ${action_class(action)}"
682 683 data-line-no="${old_line_no}"
683 684 %if old_line_anchor:
684 685 id="${old_line_anchor}"
685 686 %endif
686 687 >
687 688 %if old_line_anchor:
688 689 <a name="${old_line_anchor}" href="#${old_line_anchor}">${old_line_no}</a>
689 690 %endif
690 691 </td>
691 692 <td class="cb-lineno ${action_class(action)}"
692 693 data-line-no="${new_line_no}"
693 694 %if new_line_anchor:
694 695 id="${new_line_anchor}"
695 696 %endif
696 697 >
697 698 %if new_line_anchor:
698 699 <a name="${new_line_anchor}" href="#${new_line_anchor}">${new_line_no}</a>
699 700 %endif
700 701 </td>
701 702 <td class="cb-content ${action_class(action)}"
702 703 data-line-no="${(new_line_no and 'n' or 'o')}${(new_line_no or old_line_no)}"
703 704 >
704 705 %if use_comments:
705 706 ${render_add_comment_button()}
706 707 %endif
707 708 <span class="cb-code">${action} ${content or '' | n}</span>
708 709 %if use_comments and comments:
709 710 ${inline_comments_container(comments, inline_comments)}
710 711 %endif
711 712 </td>
712 713 </tr>
713 714 %endfor
714 715 </%def>
715 716
716 717
717 <%def name="render_hunk_lines(diff_mode, hunk, use_comments, inline_comments)">
718 <%def name="render_hunk_lines(filediff, diff_mode, hunk, use_comments, inline_comments)">
718 719 % if diff_mode == 'unified':
719 ${render_hunk_lines_unified(hunk, use_comments=use_comments, inline_comments=inline_comments)}
720 ${render_hunk_lines_unified(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments)}
720 721 % elif diff_mode == 'sideside':
721 ${render_hunk_lines_sideside(hunk, use_comments=use_comments, inline_comments=inline_comments)}
722 ${render_hunk_lines_sideside(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments)}
722 723 % else:
723 724 <tr class="cb-line">
724 725 <td>unknown diff mode</td>
725 726 </tr>
726 727 % endif
727 728 </%def>file changes
728 729
729 730
730 731 <%def name="render_add_comment_button()">
731 732 <button class="btn btn-small btn-primary cb-comment-box-opener" onclick="return Rhodecode.comments.createComment(this)">
732 733 <span><i class="icon-comment"></i></span>
733 734 </button>
734 735 </%def>
735 736
736 737 <%def name="render_diffset_menu(diffset=None, range_diff_on=None)">
737 738
738 739 <div id="diff-file-sticky" class="diffset-menu clearinner">
739 740 ## auto adjustable
740 741 <div class="sidebar__inner">
741 742 <div class="sidebar__bar">
742 743 <div class="pull-right">
743 744 <div class="btn-group">
744 745
745 746 <a
746 747 class="btn ${(c.user_session_attrs["diffmode"] == 'sideside' and 'btn-primary')} tooltip"
747 748 title="${h.tooltip(_('View side by side'))}"
748 749 href="${h.current_route_path(request, diffmode='sideside')}">
749 750 <span>${_('Side by Side')}</span>
750 751 </a>
751 752 <a
752 753 class="btn ${(c.user_session_attrs["diffmode"] == 'unified' and 'btn-primary')} tooltip"
753 754 title="${h.tooltip(_('View unified'))}" href="${h.current_route_path(request, diffmode='unified')}">
754 755 <span>${_('Unified')}</span>
755 756 </a>
756 757 % if range_diff_on is True:
757 758 <a
758 759 title="${_('Turn off: Show the diff as commit range')}"
759 760 class="btn btn-primary"
760 761 href="${h.current_route_path(request, **{"range-diff":"0"})}">
761 762 <span>${_('Range Diff')}</span>
762 763 </a>
763 764 % elif range_diff_on is False:
764 765 <a
765 766 title="${_('Show the diff as commit range')}"
766 767 class="btn"
767 768 href="${h.current_route_path(request, **{"range-diff":"1"})}">
768 769 <span>${_('Range Diff')}</span>
769 770 </a>
770 771 % endif
771 772 </div>
772 773 </div>
773 774 <div class="pull-left">
774 775 <div class="btn-group">
775 776 <div class="pull-left">
776 777 ${h.hidden('file_filter')}
777 778 </div>
778 779 <a
779 780 class="btn"
780 781 href="#"
781 782 onclick="$('input[class=filediff-collapse-state]').prop('checked', false); updateSticky(); return false">${_('Expand All Files')}</a>
782 783 <a
783 784 class="btn"
784 785 href="#"
785 786 onclick="$('input[class=filediff-collapse-state]').prop('checked', true); updateSticky(); return false">${_('Collapse All Files')}</a>
786 787 <a
787 788 class="btn"
788 789 href="#"
789 790 onclick="updateSticky();return Rhodecode.comments.toggleWideMode(this)">${_('Wide Mode Diff')}</a>
790 791
791 792 </div>
792 793 </div>
793 794 </div>
794 795 <div class="fpath-placeholder">
795 796 <i class="icon-file-text"></i>
796 797 <strong class="fpath-placeholder-text">
797 798 Context file:
798 799 </strong>
799 800 </div>
800 801 <div class="sidebar_inner_shadow"></div>
801 802 </div>
802 803 </div>
803 804
804 805 % if diffset:
805 806
806 807 %if diffset.limited_diff:
807 808 <% file_placeholder = _ungettext('%(num)s file changed', '%(num)s files changed', diffset.changed_files) % {'num': diffset.changed_files} %>
808 809 %else:
809 810 <% file_placeholder = _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}%>
810 811 %endif
811 812 ## case on range-diff placeholder needs to be updated
812 813 % if range_diff_on is True:
813 814 <% file_placeholder = _('Disabled on range diff') %>
814 815 % endif
815 816
816 817 <script>
817 818
818 819 var feedFilesOptions = function (query, initialData) {
819 820 var data = {results: []};
820 821 var isQuery = typeof query.term !== 'undefined';
821 822
822 823 var section = _gettext('Changed files');
823 824 var filteredData = [];
824 825
825 826 //filter results
826 827 $.each(initialData.results, function (idx, value) {
827 828
828 829 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
829 830 filteredData.push({
830 831 'id': this.id,
831 832 'text': this.text,
832 833 "ops": this.ops,
833 834 })
834 835 }
835 836
836 837 });
837 838
838 839 data.results = filteredData;
839 840
840 841 query.callback(data);
841 842 };
842 843
843 844 var formatFileResult = function(result, container, query, escapeMarkup) {
844 845 return function(data, escapeMarkup) {
845 846 var container = '<div class="filelist" style="padding-right:100px">{0}</div>';
846 847 var tmpl = '<span style="margin-right:-50px"><strong>{0}</strong></span>'.format(escapeMarkup(data['text']));
847 848 var pill = '<span class="pill-group" style="float: right;margin-right: -100px">' +
848 849 '<span class="pill" op="added">{0}</span>' +
849 850 '<span class="pill" op="deleted">{1}</span>' +
850 851 '</span>'
851 852 ;
852 853 var added = data['ops']['added'];
853 854 if (added === 0) {
854 855 // don't show +0
855 856 added = 0;
856 857 } else {
857 858 added = '+' + added;
858 859 }
859 860
860 861 var deleted = -1*data['ops']['deleted'];
861 862
862 863 tmpl += pill.format(added, deleted);
863 864 return container.format(tmpl);
864 865
865 866 }(result, escapeMarkup);
866 867 };
867 868 var preloadData = {
868 869 results: [
869 870 % for filediff in diffset.files:
870 871 {id:"a_${h.FID(filediff.raw_id, filediff.patch['filename'])}",
871 872 text:"${filediff.patch['filename']}",
872 873 ops:${h.json.dumps(filediff.patch['stats'])|n}}${('' if loop.last else ',')}
873 874 % endfor
874 875 ]
875 876 };
876 877
877 878 $(document).ready(function () {
878 879
879 880 var fileFilter = $("#file_filter").select2({
880 881 'dropdownAutoWidth': true,
881 882 'width': 'auto',
882 883 'placeholder': "${file_placeholder}",
883 884 containerCssClass: "drop-menu",
884 885 dropdownCssClass: "drop-menu-dropdown",
885 886 data: preloadData,
886 887 query: function(query) {
887 888 feedFilesOptions(query, preloadData);
888 889 },
889 890 formatResult: formatFileResult
890 891 });
891 892 % if range_diff_on is True:
892 893 fileFilter.select2("enable", false);
893 894
894 895 % endif
895 896
896 897 $("#file_filter").on('click', function (e) {
897 898 e.preventDefault();
898 899 var selected = $('#file_filter').select2('data');
899 900 var idSelector = "#"+selected.id;
900 901 window.location.hash = idSelector;
901 902 // expand the container if we quick-select the field
902 903 $(idSelector).next().prop('checked', false);
903 904 updateSticky()
904 905 });
905 906
906 907 var contextPrefix = _gettext('Context file: ');
907 908 ## sticky sidebar
908 909 var sidebarElement = document.getElementById('diff-file-sticky');
909 910 sidebar = new StickySidebar(sidebarElement, {
910 911 topSpacing: 0,
911 912 bottomSpacing: 0,
912 913 innerWrapperSelector: '.sidebar__inner'
913 914 });
914 915 sidebarElement.addEventListener('affixed.static.stickySidebar', function () {
915 916 // reset our file so it's not holding new value
916 917 $('.fpath-placeholder-text').html(contextPrefix)
917 918 });
918 919
919 920 updateSticky = function () {
920 921 sidebar.updateSticky();
921 922 Waypoint.refreshAll();
922 923 };
923 924
924 925 var animateText = $.debounce(100, function(fPath, anchorId) {
925 926 // animate setting the text
926 927 var callback = function () {
927 928 $('.fpath-placeholder-text').animate({'opacity': 1.00}, 200)
928 929 $('.fpath-placeholder-text').html(contextPrefix + '<a href="#a_' + anchorId + '">' + fPath + '</a>')
929 930 };
930 931 $('.fpath-placeholder-text').animate({'opacity': 0.15}, 200, callback);
931 932 });
932 933
933 934 ## dynamic file waypoints
934 935 var setFPathInfo = function(fPath, anchorId){
935 936 animateText(fPath, anchorId)
936 937 };
937 938
938 939 var codeBlock = $('.filediff');
939 940 // forward waypoint
940 941 codeBlock.waypoint(
941 942 function(direction) {
942 943 if (direction === "down"){
943 944 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
944 945 }
945 946 }, {
946 947 offset: 70,
947 948 context: '.fpath-placeholder'
948 949 }
949 950 );
950 951
951 952 // backward waypoint
952 953 codeBlock.waypoint(
953 954 function(direction) {
954 955 if (direction === "up"){
955 956 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
956 957 }
957 958 }, {
958 959 offset: function () {
959 960 return -this.element.clientHeight + 90
960 961 },
961 962 context: '.fpath-placeholder'
962 963 }
963 964 );
964 965
965 966 });
966 967
967 968 </script>
968 969 % endif
969 970
970 971 </%def> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now