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