##// END OF EJS Templates
diffs: fixed outdated files in pull-requests re-using the filediff raw_id for anchor generation....
marcink -
r3830:5bbd362b stable
parent child Browse files
Show More
@@ -1,1031 +1,1033 b''
1 1 <%namespace name="commentblock" file="/changeset/changeset_file_comment.mako"/>
2 2
3 3 <%def name="diff_line_anchor(commit, filename, line, type)"><%
4 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 changes are 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 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 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>
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 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 fid = str(id(filename))
293 294 %>
294 295 <div class="filediffs filediff-outdated" style="${display_state}">
295 296 <input ${(collapse_all and 'checked' or '')} class="filediff-collapse-state" id="filediff-collapse-${id(filename)}" type="checkbox" onchange="updateSticky();">
296 <div class="filediff" data-f-path="${filename}" id="a_${h.FID(filediff.raw_id, filename)}">
297 <div class="filediff" data-f-path="${filename}" id="a_${h.FID(fid, filename)}">
298
297 299 <label for="filediff-collapse-${id(filename)}" class="filediff-heading">
298 300 <div class="filediff-collapse-indicator"></div>
299 301 <span class="pill">
300 302 ## file was deleted
301 303 <strong>${filename}</strong>
302 304 </span>
303 305 <span class="pill-group" style="float: left">
304 306 ## file op, doesn't need translation
305 307 <span class="pill" op="removed">removed in this version</span>
306 308 </span>
307 <a class="pill filediff-anchor" href="#a_${h.FID(filediff.raw_id, filename)}">ΒΆ</a>
309 <a class="pill filediff-anchor" href="#a_${h.FID(fid, filename)}">ΒΆ</a>
308 310 <span class="pill-group" style="float: right">
309 311 <span class="pill" op="deleted">-${comments_dict['stats']}</span>
310 312 </span>
311 313 </label>
312 314
313 315 <table class="cb cb-diff-${c.user_session_attrs["diffmode"]} code-highlight ${over_lines_changed_limit and 'cb-collapsed' or ''}">
314 316 <tr>
315 317 % if c.user_session_attrs["diffmode"] == 'unified':
316 318 <td></td>
317 319 %endif
318 320
319 321 <td></td>
320 322 <td class="cb-text cb-${op_class(BIN_FILENODE)}" ${(c.user_session_attrs["diffmode"] == 'unified' and 'colspan=4' or 'colspan=5')}>
321 323 ${_('File was deleted in this version. There are still outdated/unresolved comments attached to it.')}
322 324 </td>
323 325 </tr>
324 326 %if c.user_session_attrs["diffmode"] == 'unified':
325 327 <tr class="cb-line">
326 328 <td class="cb-data cb-context"></td>
327 329 <td class="cb-lineno cb-context"></td>
328 330 <td class="cb-lineno cb-context"></td>
329 331 <td class="cb-content cb-context">
330 332 ${inline_comments_container(comments_dict['comments'], inline_comments)}
331 333 </td>
332 334 </tr>
333 335 %elif c.user_session_attrs["diffmode"] == 'sideside':
334 336 <tr class="cb-line">
335 337 <td class="cb-data cb-context"></td>
336 338 <td class="cb-lineno cb-context"></td>
337 339 <td class="cb-content cb-context"></td>
338 340
339 341 <td class="cb-data cb-context"></td>
340 342 <td class="cb-lineno cb-context"></td>
341 343 <td class="cb-content cb-context">
342 344 ${inline_comments_container(comments_dict['comments'], inline_comments)}
343 345 </td>
344 346 </tr>
345 347 %endif
346 348 </table>
347 349 </div>
348 350 </div>
349 351 % endfor
350 352
351 353 </div>
352 354 </div>
353 355 </%def>
354 356
355 357 <%def name="diff_ops(filediff)">
356 358 <%
357 359 from rhodecode.lib.diffs import NEW_FILENODE, DEL_FILENODE, \
358 360 MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE
359 361 %>
360 362 <span class="pill">
361 363 %if filediff.source_file_path and filediff.target_file_path:
362 364 %if filediff.source_file_path != filediff.target_file_path:
363 365 ## file was renamed, or copied
364 366 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
365 367 <strong>${filediff.target_file_path}</strong> β¬… <del>${filediff.source_file_path}</del>
366 368 <% final_path = filediff.target_file_path %>
367 369 %elif COPIED_FILENODE in filediff.patch['stats']['ops']:
368 370 <strong>${filediff.target_file_path}</strong> β¬… ${filediff.source_file_path}
369 371 <% final_path = filediff.target_file_path %>
370 372 %endif
371 373 %else:
372 374 ## file was modified
373 375 <strong>${filediff.source_file_path}</strong>
374 376 <% final_path = filediff.source_file_path %>
375 377 %endif
376 378 %else:
377 379 %if filediff.source_file_path:
378 380 ## file was deleted
379 381 <strong>${filediff.source_file_path}</strong>
380 382 <% final_path = filediff.source_file_path %>
381 383 %else:
382 384 ## file was added
383 385 <strong>${filediff.target_file_path}</strong>
384 386 <% final_path = filediff.target_file_path %>
385 387 %endif
386 388 %endif
387 389 <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 390 </span>
389 391 ## anchor link
390 392 <a class="pill filediff-anchor" href="#a_${h.FID(filediff.raw_id, filediff.patch['filename'])}">ΒΆ</a>
391 393
392 394 <span class="pill-group" style="float: right">
393 395
394 396 ## ops pills
395 397 %if filediff.limited_diff:
396 398 <span class="pill tooltip" op="limited" title="The stats for this diff are not complete">limited diff</span>
397 399 %endif
398 400
399 401 %if NEW_FILENODE in filediff.patch['stats']['ops']:
400 402 <span class="pill" op="created">created</span>
401 403 %if filediff['target_mode'].startswith('120'):
402 404 <span class="pill" op="symlink">symlink</span>
403 405 %else:
404 406 <span class="pill" op="mode">${nice_mode(filediff['target_mode'])}</span>
405 407 %endif
406 408 %endif
407 409
408 410 %if RENAMED_FILENODE in filediff.patch['stats']['ops']:
409 411 <span class="pill" op="renamed">renamed</span>
410 412 %endif
411 413
412 414 %if COPIED_FILENODE in filediff.patch['stats']['ops']:
413 415 <span class="pill" op="copied">copied</span>
414 416 %endif
415 417
416 418 %if DEL_FILENODE in filediff.patch['stats']['ops']:
417 419 <span class="pill" op="removed">removed</span>
418 420 %endif
419 421
420 422 %if CHMOD_FILENODE in filediff.patch['stats']['ops']:
421 423 <span class="pill" op="mode">
422 424 ${nice_mode(filediff['source_mode'])} ➑ ${nice_mode(filediff['target_mode'])}
423 425 </span>
424 426 %endif
425 427
426 428 %if BIN_FILENODE in filediff.patch['stats']['ops']:
427 429 <span class="pill" op="binary">binary</span>
428 430 %if MOD_FILENODE in filediff.patch['stats']['ops']:
429 431 <span class="pill" op="modified">modified</span>
430 432 %endif
431 433 %endif
432 434
433 435 <span class="pill" op="added">${('+' if filediff.patch['stats']['added'] else '')}${filediff.patch['stats']['added']}</span>
434 436 <span class="pill" op="deleted">${((h.safe_int(filediff.patch['stats']['deleted']) or 0) * -1)}</span>
435 437
436 438 </span>
437 439
438 440 </%def>
439 441
440 442 <%def name="nice_mode(filemode)">
441 443 ${(filemode.startswith('100') and filemode[3:] or filemode)}
442 444 </%def>
443 445
444 446 <%def name="diff_menu(filediff, use_comments=False)">
445 447 <div class="filediff-menu">
446 448
447 449 %if filediff.diffset.source_ref:
448 450
449 451 ## FILE BEFORE CHANGES
450 452 %if filediff.operation in ['D', 'M']:
451 453 <a
452 454 class="tooltip"
453 455 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)}"
454 456 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
455 457 >
456 458 ${_('Show file before')}
457 459 </a> |
458 460 %else:
459 461 <span
460 462 class="tooltip"
461 463 title="${h.tooltip(_('File not present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.source_ref[:12]})}"
462 464 >
463 465 ${_('Show file before')}
464 466 </span> |
465 467 %endif
466 468
467 469 ## FILE AFTER CHANGES
468 470 %if filediff.operation in ['A', 'M']:
469 471 <a
470 472 class="tooltip"
471 473 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)}"
472 474 title="${h.tooltip(_('Show file at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
473 475 >
474 476 ${_('Show file after')}
475 477 </a>
476 478 %else:
477 479 <span
478 480 class="tooltip"
479 481 title="${h.tooltip(_('File not present at commit: %(commit_id)s') % {'commit_id': filediff.diffset.target_ref[:12]})}"
480 482 >
481 483 ${_('Show file after')}
482 484 </span>
483 485 %endif
484 486
485 487 % if use_comments:
486 488 |
487 489 <a href="#" onclick="return Rhodecode.comments.toggleComments(this);">
488 490 <span class="show-comment-button">${_('Show comments')}</span><span class="hide-comment-button">${_('Hide comments')}</span>
489 491 </a>
490 492 % endif
491 493
492 494 %endif
493 495
494 496 </div>
495 497 </%def>
496 498
497 499
498 500 <%def name="inline_comments_container(comments, inline_comments)">
499 501 <div class="inline-comments">
500 502 %for comment in comments:
501 503 ${commentblock.comment_block(comment, inline=True)}
502 504 %endfor
503 505 % if comments and comments[-1].outdated:
504 506 <span class="btn btn-secondary cb-comment-add-button comment-outdated}"
505 507 style="display: none;}">
506 508 ${_('Add another comment')}
507 509 </span>
508 510 % else:
509 511 <span onclick="return Rhodecode.comments.createComment(this)"
510 512 class="btn btn-secondary cb-comment-add-button">
511 513 ${_('Add another comment')}
512 514 </span>
513 515 % endif
514 516
515 517 </div>
516 518 </%def>
517 519
518 520 <%!
519 521 def get_comments_for(diff_type, comments, filename, line_version, line_number):
520 522 if hasattr(filename, 'unicode_path'):
521 523 filename = filename.unicode_path
522 524
523 525 if not isinstance(filename, (unicode, str)):
524 526 return None
525 527
526 528 line_key = '{}{}'.format(line_version, line_number) ## e.g o37, n12
527 529
528 530 if comments and filename in comments:
529 531 file_comments = comments[filename]
530 532 if line_key in file_comments:
531 533 data = file_comments.pop(line_key)
532 534 return data
533 535 %>
534 536
535 537 <%def name="render_hunk_lines_sideside(filediff, hunk, use_comments=False, inline_comments=None)">
536 538 %for i, line in enumerate(hunk.sideside):
537 539 <%
538 540 old_line_anchor, new_line_anchor = None, None
539 541
540 542 if line.original.lineno:
541 543 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, line.original.lineno, 'o')
542 544 if line.modified.lineno:
543 545 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, line.modified.lineno, 'n')
544 546 %>
545 547
546 548 <tr class="cb-line">
547 549 <td class="cb-data ${action_class(line.original.action)}"
548 550 data-line-no="${line.original.lineno}"
549 551 >
550 552 <div>
551 553
552 554 <% line_old_comments = None %>
553 555 %if line.original.get_comment_args:
554 556 <% line_old_comments = get_comments_for('side-by-side', inline_comments, *line.original.get_comment_args) %>
555 557 %endif
556 558 %if line_old_comments:
557 559 <% has_outdated = any([x.outdated for x in line_old_comments]) %>
558 560 % if has_outdated:
559 561 <i title="${_('comments including outdated')}:${len(line_old_comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
560 562 % else:
561 563 <i title="${_('comments')}: ${len(line_old_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
562 564 % endif
563 565 %endif
564 566 </div>
565 567 </td>
566 568 <td class="cb-lineno ${action_class(line.original.action)}"
567 569 data-line-no="${line.original.lineno}"
568 570 %if old_line_anchor:
569 571 id="${old_line_anchor}"
570 572 %endif
571 573 >
572 574 %if line.original.lineno:
573 575 <a name="${old_line_anchor}" href="#${old_line_anchor}">${line.original.lineno}</a>
574 576 %endif
575 577 </td>
576 578 <td class="cb-content ${action_class(line.original.action)}"
577 579 data-line-no="o${line.original.lineno}"
578 580 >
579 581 %if use_comments and line.original.lineno:
580 582 ${render_add_comment_button()}
581 583 %endif
582 584 <span class="cb-code"><span class="cb-action ${action_class(line.original.action)}"></span>${line.original.content or '' | n}</span>
583 585
584 586 %if use_comments and line.original.lineno and line_old_comments:
585 587 ${inline_comments_container(line_old_comments, inline_comments)}
586 588 %endif
587 589
588 590 </td>
589 591 <td class="cb-data ${action_class(line.modified.action)}"
590 592 data-line-no="${line.modified.lineno}"
591 593 >
592 594 <div>
593 595
594 596 %if line.modified.get_comment_args:
595 597 <% line_new_comments = get_comments_for('side-by-side', inline_comments, *line.modified.get_comment_args) %>
596 598 %else:
597 599 <% line_new_comments = None%>
598 600 %endif
599 601 %if line_new_comments:
600 602 <% has_outdated = any([x.outdated for x in line_new_comments]) %>
601 603 % if has_outdated:
602 604 <i title="${_('comments including outdated')}:${len(line_new_comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
603 605 % else:
604 606 <i title="${_('comments')}: ${len(line_new_comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
605 607 % endif
606 608 %endif
607 609 </div>
608 610 </td>
609 611 <td class="cb-lineno ${action_class(line.modified.action)}"
610 612 data-line-no="${line.modified.lineno}"
611 613 %if new_line_anchor:
612 614 id="${new_line_anchor}"
613 615 %endif
614 616 >
615 617 %if line.modified.lineno:
616 618 <a name="${new_line_anchor}" href="#${new_line_anchor}">${line.modified.lineno}</a>
617 619 %endif
618 620 </td>
619 621 <td class="cb-content ${action_class(line.modified.action)}"
620 622 data-line-no="n${line.modified.lineno}"
621 623 >
622 624 %if use_comments and line.modified.lineno:
623 625 ${render_add_comment_button()}
624 626 %endif
625 627 <span class="cb-code"><span class="cb-action ${action_class(line.modified.action)}"></span>${line.modified.content or '' | n}</span>
626 628 %if use_comments and line.modified.lineno and line_new_comments:
627 629 ${inline_comments_container(line_new_comments, inline_comments)}
628 630 %endif
629 631 </td>
630 632 </tr>
631 633 %endfor
632 634 </%def>
633 635
634 636
635 637 <%def name="render_hunk_lines_unified(filediff, hunk, use_comments=False, inline_comments=None)">
636 638 %for old_line_no, new_line_no, action, content, comments_args in hunk.unified:
637 639
638 640 <%
639 641 old_line_anchor, new_line_anchor = None, None
640 642 if old_line_no:
641 643 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, old_line_no, 'o')
642 644 if new_line_no:
643 645 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, new_line_no, 'n')
644 646 %>
645 647 <tr class="cb-line">
646 648 <td class="cb-data ${action_class(action)}">
647 649 <div>
648 650
649 651 %if comments_args:
650 652 <% comments = get_comments_for('unified', inline_comments, *comments_args) %>
651 653 %else:
652 654 <% comments = None %>
653 655 %endif
654 656
655 657 % if comments:
656 658 <% has_outdated = any([x.outdated for x in comments]) %>
657 659 % if has_outdated:
658 660 <i title="${_('comments including outdated')}:${len(comments)}" class="icon-comment-toggle" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
659 661 % else:
660 662 <i title="${_('comments')}: ${len(comments)}" class="icon-comment" onclick="return Rhodecode.comments.toggleLineComments(this)"></i>
661 663 % endif
662 664 % endif
663 665 </div>
664 666 </td>
665 667 <td class="cb-lineno ${action_class(action)}"
666 668 data-line-no="${old_line_no}"
667 669 %if old_line_anchor:
668 670 id="${old_line_anchor}"
669 671 %endif
670 672 >
671 673 %if old_line_anchor:
672 674 <a name="${old_line_anchor}" href="#${old_line_anchor}">${old_line_no}</a>
673 675 %endif
674 676 </td>
675 677 <td class="cb-lineno ${action_class(action)}"
676 678 data-line-no="${new_line_no}"
677 679 %if new_line_anchor:
678 680 id="${new_line_anchor}"
679 681 %endif
680 682 >
681 683 %if new_line_anchor:
682 684 <a name="${new_line_anchor}" href="#${new_line_anchor}">${new_line_no}</a>
683 685 %endif
684 686 </td>
685 687 <td class="cb-content ${action_class(action)}"
686 688 data-line-no="${(new_line_no and 'n' or 'o')}${(new_line_no or old_line_no)}"
687 689 >
688 690 %if use_comments:
689 691 ${render_add_comment_button()}
690 692 %endif
691 693 <span class="cb-code"><span class="cb-action ${action_class(action)}"></span> ${content or '' | n}</span>
692 694 %if use_comments and comments:
693 695 ${inline_comments_container(comments, inline_comments)}
694 696 %endif
695 697 </td>
696 698 </tr>
697 699 %endfor
698 700 </%def>
699 701
700 702
701 703 <%def name="render_hunk_lines(filediff, diff_mode, hunk, use_comments, inline_comments)">
702 704 % if diff_mode == 'unified':
703 705 ${render_hunk_lines_unified(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments)}
704 706 % elif diff_mode == 'sideside':
705 707 ${render_hunk_lines_sideside(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments)}
706 708 % else:
707 709 <tr class="cb-line">
708 710 <td>unknown diff mode</td>
709 711 </tr>
710 712 % endif
711 713 </%def>file changes
712 714
713 715
714 716 <%def name="render_add_comment_button()">
715 717 <button class="btn btn-small btn-primary cb-comment-box-opener" onclick="return Rhodecode.comments.createComment(this)">
716 718 <span><i class="icon-comment"></i></span>
717 719 </button>
718 720 </%def>
719 721
720 722 <%def name="render_diffset_menu(diffset=None, range_diff_on=None)">
721 723
722 724 <div id="diff-file-sticky" class="diffset-menu clearinner">
723 725 ## auto adjustable
724 726 <div class="sidebar__inner">
725 727 <div class="sidebar__bar">
726 728 <div class="pull-right">
727 729 <div class="btn-group">
728 730
729 731 ## DIFF OPTIONS via Select2
730 732 <div class="pull-left">
731 733 ${h.hidden('diff_menu')}
732 734 </div>
733 735
734 736 <a
735 737 class="btn ${(c.user_session_attrs["diffmode"] == 'sideside' and 'btn-primary')} tooltip"
736 738 title="${h.tooltip(_('View side by side'))}"
737 739 href="${h.current_route_path(request, diffmode='sideside')}">
738 740 <span>${_('Side by Side')}</span>
739 741 </a>
740 742
741 743 <a
742 744 class="btn ${(c.user_session_attrs["diffmode"] == 'unified' and 'btn-primary')} tooltip"
743 745 title="${h.tooltip(_('View unified'))}" href="${h.current_route_path(request, diffmode='unified')}">
744 746 <span>${_('Unified')}</span>
745 747 </a>
746 748
747 749 % if range_diff_on is True:
748 750 <a
749 751 title="${_('Turn off: Show the diff as commit range')}"
750 752 class="btn btn-primary"
751 753 href="${h.current_route_path(request, **{"range-diff":"0"})}">
752 754 <span>${_('Range Diff')}</span>
753 755 </a>
754 756 % elif range_diff_on is False:
755 757 <a
756 758 title="${_('Show the diff as commit range')}"
757 759 class="btn"
758 760 href="${h.current_route_path(request, **{"range-diff":"1"})}">
759 761 <span>${_('Range Diff')}</span>
760 762 </a>
761 763 % endif
762 764 </div>
763 765 </div>
764 766 <div class="pull-left">
765 767 <div class="btn-group">
766 768 <div class="pull-left">
767 769 ${h.hidden('file_filter')}
768 770 </div>
769 771 <a
770 772 class="btn"
771 773 href="#"
772 774 onclick="$('input[class=filediff-collapse-state]').prop('checked', false); updateSticky(); return false">${_('Expand All Files')}</a>
773 775 <a
774 776 class="btn"
775 777 href="#"
776 778 onclick="$('input[class=filediff-collapse-state]').prop('checked', true); updateSticky(); return false">${_('Collapse All Files')}</a>
777 779 </div>
778 780 </div>
779 781 </div>
780 782 <div class="fpath-placeholder">
781 783 <i class="icon-file-text"></i>
782 784 <strong class="fpath-placeholder-text">
783 785 Context file:
784 786 </strong>
785 787 </div>
786 788 <div class="sidebar_inner_shadow"></div>
787 789 </div>
788 790 </div>
789 791
790 792 % if diffset:
791 793
792 794 %if diffset.limited_diff:
793 795 <% file_placeholder = _ungettext('%(num)s file changed', '%(num)s files changed', diffset.changed_files) % {'num': diffset.changed_files} %>
794 796 %else:
795 797 <% 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}%>
796 798 %endif
797 799 ## case on range-diff placeholder needs to be updated
798 800 % if range_diff_on is True:
799 801 <% file_placeholder = _('Disabled on range diff') %>
800 802 % endif
801 803
802 804 <script>
803 805
804 806 var feedFilesOptions = function (query, initialData) {
805 807 var data = {results: []};
806 808 var isQuery = typeof query.term !== 'undefined';
807 809
808 810 var section = _gettext('Changed files');
809 811 var filteredData = [];
810 812
811 813 //filter results
812 814 $.each(initialData.results, function (idx, value) {
813 815
814 816 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
815 817 filteredData.push({
816 818 'id': this.id,
817 819 'text': this.text,
818 820 "ops": this.ops,
819 821 })
820 822 }
821 823
822 824 });
823 825
824 826 data.results = filteredData;
825 827
826 828 query.callback(data);
827 829 };
828 830
829 831 var formatFileResult = function(result, container, query, escapeMarkup) {
830 832 return function(data, escapeMarkup) {
831 833 var container = '<div class="filelist" style="padding-right:100px">{0}</div>';
832 834 var tmpl = '<span style="margin-right:-50px"><strong>{0}</strong></span>'.format(escapeMarkup(data['text']));
833 835 var pill = '<span class="pill-group" style="float: right;margin-right: -100px">' +
834 836 '<span class="pill" op="added">{0}</span>' +
835 837 '<span class="pill" op="deleted">{1}</span>' +
836 838 '</span>'
837 839 ;
838 840 var added = data['ops']['added'];
839 841 if (added === 0) {
840 842 // don't show +0
841 843 added = 0;
842 844 } else {
843 845 added = '+' + added;
844 846 }
845 847
846 848 var deleted = -1*data['ops']['deleted'];
847 849
848 850 tmpl += pill.format(added, deleted);
849 851 return container.format(tmpl);
850 852
851 853 }(result, escapeMarkup);
852 854 };
853 855
854 856 var preloadFileFilterData = {
855 857 results: [
856 858 % for filediff in diffset.files:
857 859 {id:"a_${h.FID(filediff.raw_id, filediff.patch['filename'])}",
858 860 text:"${filediff.patch['filename']}",
859 861 ops:${h.json.dumps(filediff.patch['stats'])|n}}${('' if loop.last else ',')}
860 862 % endfor
861 863 ]
862 864 };
863 865
864 866 $(document).ready(function () {
865 867
866 868 var fileFilter = $("#file_filter").select2({
867 869 'dropdownAutoWidth': true,
868 870 'width': 'auto',
869 871 'placeholder': "${file_placeholder}",
870 872 containerCssClass: "drop-menu",
871 873 dropdownCssClass: "drop-menu-dropdown",
872 874 data: preloadFileFilterData,
873 875 query: function(query) {
874 876 feedFilesOptions(query, preloadFileFilterData);
875 877 },
876 878 formatResult: formatFileResult
877 879 });
878 880
879 881 % if range_diff_on is True:
880 882 fileFilter.select2("enable", false);
881 883 % endif
882 884
883 885 $("#file_filter").on('click', function (e) {
884 886 e.preventDefault();
885 887 var selected = $('#file_filter').select2('data');
886 888 var idSelector = "#"+selected.id;
887 889 window.location.hash = idSelector;
888 890 // expand the container if we quick-select the field
889 891 $(idSelector).next().prop('checked', false);
890 892 updateSticky()
891 893 });
892 894
893 895 var contextPrefix = _gettext('Context file: ');
894 896 ## sticky sidebar
895 897 var sidebarElement = document.getElementById('diff-file-sticky');
896 898 sidebar = new StickySidebar(sidebarElement, {
897 899 topSpacing: 0,
898 900 bottomSpacing: 0,
899 901 innerWrapperSelector: '.sidebar__inner'
900 902 });
901 903 sidebarElement.addEventListener('affixed.static.stickySidebar', function () {
902 904 // reset our file so it's not holding new value
903 905 $('.fpath-placeholder-text').html(contextPrefix)
904 906 });
905 907
906 908 updateSticky = function () {
907 909 sidebar.updateSticky();
908 910 Waypoint.refreshAll();
909 911 };
910 912
911 913 var animateText = $.debounce(100, function(fPath, anchorId) {
912 914 fPath = Select2.util.escapeMarkup(fPath);
913 915
914 916 // animate setting the text
915 917 var callback = function () {
916 918 $('.fpath-placeholder-text').animate({'opacity': 1.00}, 200)
917 919 $('.fpath-placeholder-text').html(contextPrefix + '<a href="#a_' + anchorId + '">' + fPath + '</a>')
918 920 };
919 921 $('.fpath-placeholder-text').animate({'opacity': 0.15}, 200, callback);
920 922 });
921 923
922 924 ## dynamic file waypoints
923 925 var setFPathInfo = function(fPath, anchorId){
924 926 animateText(fPath, anchorId)
925 927 };
926 928
927 929 var codeBlock = $('.filediff');
928 930 // forward waypoint
929 931 codeBlock.waypoint(
930 932 function(direction) {
931 933 if (direction === "down"){
932 934 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
933 935 }
934 936 }, {
935 937 offset: 70,
936 938 context: '.fpath-placeholder'
937 939 }
938 940 );
939 941
940 942 // backward waypoint
941 943 codeBlock.waypoint(
942 944 function(direction) {
943 945 if (direction === "up"){
944 946 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
945 947 }
946 948 }, {
947 949 offset: function () {
948 950 return -this.element.clientHeight + 90
949 951 },
950 952 context: '.fpath-placeholder'
951 953 }
952 954 );
953 955
954 956 var preloadDiffMenuData = {
955 957 results: [
956 958 ## Wide diff mode
957 959 {
958 960 id: 1,
959 961 text: _gettext('Toggle Wide Mode diff'),
960 962 action: function () {
961 963 updateSticky();
962 964 var wide = Rhodecode.comments.toggleWideMode(this);
963 965 storeUserSessionAttr('rc_user_session_attr.wide_diff_mode', wide);
964 966 return null;
965 967 },
966 968 url: null,
967 969 },
968 970
969 971 ## Whitespace change
970 972 % if request.GET.get('ignorews', '') == '1':
971 973 {
972 974 id: 2,
973 975 text: _gettext('Show whitespace changes'),
974 976 action: function () {},
975 977 url: "${h.current_route_path(request, ignorews=0)|n}"
976 978 },
977 979 % else:
978 980 {
979 981 id: 2,
980 982 text: _gettext('Hide whitespace changes'),
981 983 action: function () {},
982 984 url: "${h.current_route_path(request, ignorews=1)|n}"
983 985 },
984 986 % endif
985 987
986 988 ## FULL CONTEXT
987 989 % if request.GET.get('fullcontext', '') == '1':
988 990 {
989 991 id: 3,
990 992 text: _gettext('Hide full context diff'),
991 993 action: function () {},
992 994 url: "${h.current_route_path(request, fullcontext=0)|n}"
993 995 },
994 996 % else:
995 997 {
996 998 id: 3,
997 999 text: _gettext('Show full context diff'),
998 1000 action: function () {},
999 1001 url: "${h.current_route_path(request, fullcontext=1)|n}"
1000 1002 },
1001 1003 % endif
1002 1004
1003 1005 ]
1004 1006 };
1005 1007
1006 1008 // get stored diff mode and pre-enable it
1007 1009 if (templateContext.session_attrs.wide_diff_mode === "true") {
1008 1010 Rhodecode.comments.toggleWideMode(null);
1009 1011 }
1010 1012
1011 1013 $("#diff_menu").select2({
1012 1014 minimumResultsForSearch: -1,
1013 1015 containerCssClass: "drop-menu",
1014 1016 dropdownCssClass: "drop-menu-dropdown",
1015 1017 dropdownAutoWidth: true,
1016 1018 data: preloadDiffMenuData,
1017 1019 placeholder: "${_('Diff Options')}",
1018 1020 });
1019 1021 $("#diff_menu").on('select2-selecting', function (e) {
1020 1022 e.choice.action();
1021 1023 if (e.choice.url !== null) {
1022 1024 window.location = e.choice.url
1023 1025 }
1024 1026 });
1025 1027
1026 1028 });
1027 1029
1028 1030 </script>
1029 1031 % endif
1030 1032
1031 1033 </%def>
General Comments 0
You need to be logged in to leave comments. Login now