##// END OF EJS Templates
comments: fix UX for not logged users when they try to comment.
milka -
r4572:629b4bc9 stable
parent child Browse files
Show More
@@ -1,1416 +1,1422 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 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 645 <div class="reply-thread-container-wrapper${extra_class}" style="${extra_style}">
646 646 <div class="reply-thread-container${extra_class}">
647 647 <div class="reply-thread-gravatar">
648 % if c.rhodecode_user.username != h.DEFAULT_USER:
648 649 ${base.gravatar(c.rhodecode_user.email, 20, tooltip=True, user=c.rhodecode_user)}
650 % endif
649 651 </div>
652
650 653 <div class="reply-thread-reply-button">
654 % if c.rhodecode_user.username != h.DEFAULT_USER:
651 655 ## initial reply button, some JS logic can append here a FORM to leave a first comment.
652 656 <button class="cb-comment-add-button" onclick="return Rhodecode.comments.createComment(this, '${f_path}', '${line_no}', null)">Reply...</button>
657 % endif
653 658 </div>
659 ##% endif
654 660 <div class="reply-thread-last"></div>
655 661 </div>
656 662 </div>
657 663 </div>
658 664
659 665 </%def>
660 666
661 667 <%!
662 668
663 669 def get_inline_comments(comments, filename):
664 670 if hasattr(filename, 'unicode_path'):
665 671 filename = filename.unicode_path
666 672
667 673 if not isinstance(filename, (unicode, str)):
668 674 return None
669 675
670 676 if comments and filename in comments:
671 677 return comments[filename]
672 678
673 679 return None
674 680
675 681 def get_comments_for(diff_type, comments, filename, line_version, line_number):
676 682 if hasattr(filename, 'unicode_path'):
677 683 filename = filename.unicode_path
678 684
679 685 if not isinstance(filename, (unicode, str)):
680 686 return None
681 687
682 688 file_comments = get_inline_comments(comments, filename)
683 689 if file_comments is None:
684 690 return None
685 691
686 692 line_key = '{}{}'.format(line_version, line_number) ## e.g o37, n12
687 693 if line_key in file_comments:
688 694 data = file_comments.pop(line_key)
689 695 return data
690 696 %>
691 697
692 698 <%def name="render_hunk_lines_sideside(filediff, hunk, use_comments=False, inline_comments=None, active_pattern_entries=None)">
693 699
694 700 <% chunk_count = 1 %>
695 701 %for loop_obj, item in h.looper(hunk.sideside):
696 702 <%
697 703 line = item
698 704 i = loop_obj.index
699 705 prev_line = loop_obj.previous
700 706 old_line_anchor, new_line_anchor = None, None
701 707
702 708 if line.original.lineno:
703 709 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, line.original.lineno, 'o')
704 710 if line.modified.lineno:
705 711 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, line.modified.lineno, 'n')
706 712
707 713 line_action = line.modified.action or line.original.action
708 714 prev_line_action = prev_line and (prev_line.modified.action or prev_line.original.action)
709 715 %>
710 716
711 717 <tr class="cb-line">
712 718 <td class="cb-data ${action_class(line.original.action)}"
713 719 data-line-no="${line.original.lineno}"
714 720 >
715 721
716 722 <% line_old_comments, line_old_comments_no_drafts = None, None %>
717 723 %if line.original.get_comment_args:
718 724 <%
719 725 line_old_comments = get_comments_for('side-by-side', inline_comments, *line.original.get_comment_args)
720 726 line_old_comments_no_drafts = [c for c in line_old_comments if not c.draft] if line_old_comments else []
721 727 has_outdated = any([x.outdated for x in line_old_comments_no_drafts])
722 728 %>
723 729 %endif
724 730 %if line_old_comments_no_drafts:
725 731 % if has_outdated:
726 732 <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>
727 733 % else:
728 734 <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>
729 735 % endif
730 736 %endif
731 737 </td>
732 738 <td class="cb-lineno ${action_class(line.original.action)}"
733 739 data-line-no="${line.original.lineno}"
734 740 %if old_line_anchor:
735 741 id="${old_line_anchor}"
736 742 %endif
737 743 >
738 744 %if line.original.lineno:
739 745 <a name="${old_line_anchor}" href="#${old_line_anchor}">${line.original.lineno}</a>
740 746 %endif
741 747 </td>
742 748
743 749 <% line_no = 'o{}'.format(line.original.lineno) %>
744 750 <td class="cb-content ${action_class(line.original.action)}"
745 751 data-line-no="${line_no}"
746 752 >
747 753 %if use_comments and line.original.lineno:
748 754 ${render_add_comment_button(line_no=line_no, f_path=filediff.patch['filename'])}
749 755 %endif
750 756 <span class="cb-code"><span class="cb-action ${action_class(line.original.action)}"></span>${line.original.content or '' | n}</span>
751 757
752 758 %if use_comments and line.original.lineno and line_old_comments:
753 759 ${inline_comments_container(line_old_comments, active_pattern_entries=active_pattern_entries, line_no=line_no, f_path=filediff.patch['filename'])}
754 760 %endif
755 761
756 762 </td>
757 763 <td class="cb-data ${action_class(line.modified.action)}"
758 764 data-line-no="${line.modified.lineno}"
759 765 >
760 766 <div>
761 767
762 768 <% line_new_comments, line_new_comments_no_drafts = None, None %>
763 769 %if line.modified.get_comment_args:
764 770 <%
765 771 line_new_comments = get_comments_for('side-by-side', inline_comments, *line.modified.get_comment_args)
766 772 line_new_comments_no_drafts = [c for c in line_new_comments if not c.draft] if line_new_comments else []
767 773 has_outdated = any([x.outdated for x in line_new_comments_no_drafts])
768 774 %>
769 775 %endif
770 776
771 777 %if line_new_comments_no_drafts:
772 778 % if has_outdated:
773 779 <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>
774 780 % else:
775 781 <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>
776 782 % endif
777 783 %endif
778 784 </div>
779 785 </td>
780 786 <td class="cb-lineno ${action_class(line.modified.action)}"
781 787 data-line-no="${line.modified.lineno}"
782 788 %if new_line_anchor:
783 789 id="${new_line_anchor}"
784 790 %endif
785 791 >
786 792 %if line.modified.lineno:
787 793 <a name="${new_line_anchor}" href="#${new_line_anchor}">${line.modified.lineno}</a>
788 794 %endif
789 795 </td>
790 796
791 797 <% line_no = 'n{}'.format(line.modified.lineno) %>
792 798 <td class="cb-content ${action_class(line.modified.action)}"
793 799 data-line-no="${line_no}"
794 800 >
795 801 %if use_comments and line.modified.lineno:
796 802 ${render_add_comment_button(line_no=line_no, f_path=filediff.patch['filename'])}
797 803 %endif
798 804 <span class="cb-code"><span class="cb-action ${action_class(line.modified.action)}"></span>${line.modified.content or '' | n}</span>
799 805 % if line_action in ['+', '-'] and prev_line_action not in ['+', '-']:
800 806 <div class="nav-chunk" style="visibility: hidden">
801 807 <i class="icon-eye" title="viewing diff hunk-${hunk.index}-${chunk_count}"></i>
802 808 </div>
803 809 <% chunk_count +=1 %>
804 810 % endif
805 811 %if use_comments and line.modified.lineno and line_new_comments:
806 812 ${inline_comments_container(line_new_comments, active_pattern_entries=active_pattern_entries, line_no=line_no, f_path=filediff.patch['filename'])}
807 813 %endif
808 814
809 815 </td>
810 816 </tr>
811 817 %endfor
812 818 </%def>
813 819
814 820
815 821 <%def name="render_hunk_lines_unified(filediff, hunk, use_comments=False, inline_comments=None, active_pattern_entries=None)">
816 822 %for old_line_no, new_line_no, action, content, comments_args in hunk.unified:
817 823
818 824 <%
819 825 old_line_anchor, new_line_anchor = None, None
820 826 if old_line_no:
821 827 old_line_anchor = diff_line_anchor(filediff.raw_id, hunk.source_file_path, old_line_no, 'o')
822 828 if new_line_no:
823 829 new_line_anchor = diff_line_anchor(filediff.raw_id, hunk.target_file_path, new_line_no, 'n')
824 830 %>
825 831 <tr class="cb-line">
826 832 <td class="cb-data ${action_class(action)}">
827 833 <div>
828 834
829 835 <% comments, comments_no_drafts = None, None %>
830 836 %if comments_args:
831 837 <%
832 838 comments = get_comments_for('unified', inline_comments, *comments_args)
833 839 comments_no_drafts = [c for c in line_new_comments if not c.draft] if line_new_comments else []
834 840 has_outdated = any([x.outdated for x in comments_no_drafts])
835 841 %>
836 842 %endif
837 843
838 844 % if comments_no_drafts:
839 845 % if has_outdated:
840 846 <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>
841 847 % else:
842 848 <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>
843 849 % endif
844 850 % endif
845 851 </div>
846 852 </td>
847 853 <td class="cb-lineno ${action_class(action)}"
848 854 data-line-no="${old_line_no}"
849 855 %if old_line_anchor:
850 856 id="${old_line_anchor}"
851 857 %endif
852 858 >
853 859 %if old_line_anchor:
854 860 <a name="${old_line_anchor}" href="#${old_line_anchor}">${old_line_no}</a>
855 861 %endif
856 862 </td>
857 863 <td class="cb-lineno ${action_class(action)}"
858 864 data-line-no="${new_line_no}"
859 865 %if new_line_anchor:
860 866 id="${new_line_anchor}"
861 867 %endif
862 868 >
863 869 %if new_line_anchor:
864 870 <a name="${new_line_anchor}" href="#${new_line_anchor}">${new_line_no}</a>
865 871 %endif
866 872 </td>
867 873 <% line_no = '{}{}'.format(new_line_no and 'n' or 'o', new_line_no or old_line_no) %>
868 874 <td class="cb-content ${action_class(action)}"
869 875 data-line-no="${line_no}"
870 876 >
871 877 %if use_comments:
872 878 ${render_add_comment_button(line_no=line_no, f_path=filediff.patch['filename'])}
873 879 %endif
874 880 <span class="cb-code"><span class="cb-action ${action_class(action)}"></span> ${content or '' | n}</span>
875 881 %if use_comments and comments:
876 882 ${inline_comments_container(comments, active_pattern_entries=active_pattern_entries, line_no=line_no, f_path=filediff.patch['filename'])}
877 883 %endif
878 884 </td>
879 885 </tr>
880 886 %endfor
881 887 </%def>
882 888
883 889
884 890 <%def name="render_hunk_lines(filediff, diff_mode, hunk, use_comments, inline_comments, active_pattern_entries)">
885 891 % if diff_mode == 'unified':
886 892 ${render_hunk_lines_unified(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
887 893 % elif diff_mode == 'sideside':
888 894 ${render_hunk_lines_sideside(filediff, hunk, use_comments=use_comments, inline_comments=inline_comments, active_pattern_entries=active_pattern_entries)}
889 895 % else:
890 896 <tr class="cb-line">
891 897 <td>unknown diff mode</td>
892 898 </tr>
893 899 % endif
894 900 </%def>file changes
895 901
896 902
897 903 <%def name="render_add_comment_button(line_no='', f_path='')">
898 904 % if not c.rhodecode_user.is_default:
899 905 <button class="btn btn-small btn-primary cb-comment-box-opener" onclick="return Rhodecode.comments.createComment(this, '${f_path}', '${line_no}', null)">
900 906 <span><i class="icon-comment"></i></span>
901 907 </button>
902 908 % endif
903 909 </%def>
904 910
905 911 <%def name="render_diffset_menu(diffset, range_diff_on=None, commit=None, pull_request_menu=None)">
906 912 <% diffset_container_id = h.md5(diffset.target_ref) %>
907 913
908 914 <div id="diff-file-sticky" class="diffset-menu clearinner">
909 915 ## auto adjustable
910 916 <div class="sidebar__inner">
911 917 <div class="sidebar__bar">
912 918 <div class="pull-right">
913 919 <div class="btn-group">
914 920 <a class="btn tooltip toggle-wide-diff" href="#toggle-wide-diff" onclick="toggleWideDiff(this); return false" title="${h.tooltip(_('Toggle wide diff'))}">
915 921 <i class="icon-wide-mode"></i>
916 922 </a>
917 923 </div>
918 924 <div class="btn-group">
919 925
920 926 <a
921 927 class="btn ${(c.user_session_attrs["diffmode"] == 'sideside' and 'btn-active')} tooltip"
922 928 title="${h.tooltip(_('View diff as side by side'))}"
923 929 href="${h.current_route_path(request, diffmode='sideside')}">
924 930 <span>${_('Side by Side')}</span>
925 931 </a>
926 932
927 933 <a
928 934 class="btn ${(c.user_session_attrs["diffmode"] == 'unified' and 'btn-active')} tooltip"
929 935 title="${h.tooltip(_('View diff as unified'))}" href="${h.current_route_path(request, diffmode='unified')}">
930 936 <span>${_('Unified')}</span>
931 937 </a>
932 938
933 939 % if range_diff_on is True:
934 940 <a
935 941 title="${_('Turn off: Show the diff as commit range')}"
936 942 class="btn btn-primary"
937 943 href="${h.current_route_path(request, **{"range-diff":"0"})}">
938 944 <span>${_('Range Diff')}</span>
939 945 </a>
940 946 % elif range_diff_on is False:
941 947 <a
942 948 title="${_('Show the diff as commit range')}"
943 949 class="btn"
944 950 href="${h.current_route_path(request, **{"range-diff":"1"})}">
945 951 <span>${_('Range Diff')}</span>
946 952 </a>
947 953 % endif
948 954 </div>
949 955 <div class="btn-group">
950 956
951 957 <div class="pull-left">
952 958 ${h.hidden('diff_menu_{}'.format(diffset_container_id))}
953 959 </div>
954 960
955 961 </div>
956 962 </div>
957 963 <div class="pull-left">
958 964 <div class="btn-group">
959 965 <div class="pull-left">
960 966 ${h.hidden('file_filter_{}'.format(diffset_container_id))}
961 967 </div>
962 968
963 969 </div>
964 970 </div>
965 971 </div>
966 972 <div class="fpath-placeholder pull-left">
967 973 <i class="icon-file-text"></i>
968 974 <strong class="fpath-placeholder-text">
969 975 Context file:
970 976 </strong>
971 977 </div>
972 978 <div class="pull-right noselect">
973 979
974 980 %if commit:
975 981 <span>
976 982 <code>${h.show_id(commit)}</code>
977 983 </span>
978 984 %elif pull_request_menu and pull_request_menu.get('pull_request'):
979 985 <span>
980 986 <code>!${pull_request_menu['pull_request'].pull_request_id}</code>
981 987 </span>
982 988 %endif
983 989 % if commit or pull_request_menu:
984 990 <span class="tooltip" title="Navigate to previous or next change inside files." id="diff_nav">Loading diff...:</span>
985 991 <span class="cursor-pointer" onclick="scrollToPrevChunk(); return false">
986 992 <i class="icon-angle-up"></i>
987 993 </span>
988 994 <span class="cursor-pointer" onclick="scrollToNextChunk(); return false">
989 995 <i class="icon-angle-down"></i>
990 996 </span>
991 997 % endif
992 998 </div>
993 999 <div class="sidebar_inner_shadow"></div>
994 1000 </div>
995 1001 </div>
996 1002
997 1003 % if diffset:
998 1004 %if diffset.limited_diff:
999 1005 <% file_placeholder = _ungettext('%(num)s file changed', '%(num)s files changed', diffset.changed_files) % {'num': diffset.changed_files} %>
1000 1006 %else:
1001 1007 <% 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>',
1002 1008 diffset.changed_files) % {'num': diffset.changed_files, 'linesadd': diffset.lines_added, 'linesdel': diffset.lines_deleted}) %>
1003 1009
1004 1010 %endif
1005 1011 ## case on range-diff placeholder needs to be updated
1006 1012 % if range_diff_on is True:
1007 1013 <% file_placeholder = _('Disabled on range diff') %>
1008 1014 % endif
1009 1015
1010 1016 <script type="text/javascript">
1011 1017 var feedFilesOptions = function (query, initialData) {
1012 1018 var data = {results: []};
1013 1019 var isQuery = typeof query.term !== 'undefined';
1014 1020
1015 1021 var section = _gettext('Changed files');
1016 1022 var filteredData = [];
1017 1023
1018 1024 //filter results
1019 1025 $.each(initialData.results, function (idx, value) {
1020 1026
1021 1027 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
1022 1028 filteredData.push({
1023 1029 'id': this.id,
1024 1030 'text': this.text,
1025 1031 "ops": this.ops,
1026 1032 })
1027 1033 }
1028 1034
1029 1035 });
1030 1036
1031 1037 data.results = filteredData;
1032 1038
1033 1039 query.callback(data);
1034 1040 };
1035 1041
1036 1042 var selectionFormatter = function(data, escapeMarkup) {
1037 1043 var container = '<div class="filelist" style="padding-right:100px">{0}</div>';
1038 1044 var tmpl = '<div><strong>{0}</strong></div>'.format(escapeMarkup(data['text']));
1039 1045 var pill = '<div class="pill-group" style="position: absolute; top:7px; right: 0">' +
1040 1046 '<span class="pill" op="added">{0}</span>' +
1041 1047 '<span class="pill" op="deleted">{1}</span>' +
1042 1048 '</div>'
1043 1049 ;
1044 1050 var added = data['ops']['added'];
1045 1051 if (added === 0) {
1046 1052 // don't show +0
1047 1053 added = 0;
1048 1054 } else {
1049 1055 added = '+' + added;
1050 1056 }
1051 1057
1052 1058 var deleted = -1*data['ops']['deleted'];
1053 1059
1054 1060 tmpl += pill.format(added, deleted);
1055 1061 return container.format(tmpl);
1056 1062 };
1057 1063 var formatFileResult = function(result, container, query, escapeMarkup) {
1058 1064 return selectionFormatter(result, escapeMarkup);
1059 1065 };
1060 1066
1061 1067 var formatSelection = function (data, container) {
1062 1068 return '${file_placeholder}'
1063 1069 };
1064 1070
1065 1071 if (window.preloadFileFilterData === undefined) {
1066 1072 window.preloadFileFilterData = {}
1067 1073 }
1068 1074
1069 1075 preloadFileFilterData["${diffset_container_id}"] = {
1070 1076 results: [
1071 1077 % for filediff in diffset.files:
1072 1078 {id:"a_${h.FID(filediff.raw_id, filediff.patch['filename'])}",
1073 1079 text:"${filediff.patch['filename']}",
1074 1080 ops:${h.json.dumps(filediff.patch['stats'])|n}}${('' if loop.last else ',')}
1075 1081 % endfor
1076 1082 ]
1077 1083 };
1078 1084
1079 1085 var diffFileFilterId = "#file_filter_" + "${diffset_container_id}";
1080 1086 var diffFileFilter = $(diffFileFilterId).select2({
1081 1087 'dropdownAutoWidth': true,
1082 1088 'width': 'auto',
1083 1089
1084 1090 containerCssClass: "drop-menu",
1085 1091 dropdownCssClass: "drop-menu-dropdown",
1086 1092 data: preloadFileFilterData["${diffset_container_id}"],
1087 1093 query: function(query) {
1088 1094 feedFilesOptions(query, preloadFileFilterData["${diffset_container_id}"]);
1089 1095 },
1090 1096 initSelection: function(element, callback) {
1091 1097 callback({'init': true});
1092 1098 },
1093 1099 formatResult: formatFileResult,
1094 1100 formatSelection: formatSelection
1095 1101 });
1096 1102
1097 1103 % if range_diff_on is True:
1098 1104 diffFileFilter.select2("enable", false);
1099 1105 % endif
1100 1106
1101 1107 $(diffFileFilterId).on('select2-selecting', function (e) {
1102 1108 var idSelector = e.choice.id;
1103 1109
1104 1110 // expand the container if we quick-select the field
1105 1111 $('#'+idSelector).next().prop('checked', false);
1106 1112 // hide the mast as we later do preventDefault()
1107 1113 $("#select2-drop-mask").click();
1108 1114
1109 1115 window.location.hash = '#'+idSelector;
1110 1116 updateSticky();
1111 1117
1112 1118 e.preventDefault();
1113 1119 });
1114 1120
1115 1121 diffNavText = 'diff navigation:'
1116 1122
1117 1123 getCurrentChunk = function () {
1118 1124
1119 1125 var chunksAll = $('.nav-chunk').filter(function () {
1120 1126 return $(this).parents('.filediff').prev().get(0).checked !== true
1121 1127 })
1122 1128 var chunkSelected = $('.nav-chunk.selected');
1123 1129 var initial = false;
1124 1130
1125 1131 if (chunkSelected.length === 0) {
1126 1132 // no initial chunk selected, we pick first
1127 1133 chunkSelected = $(chunksAll.get(0));
1128 1134 var initial = true;
1129 1135 }
1130 1136
1131 1137 return {
1132 1138 'all': chunksAll,
1133 1139 'selected': chunkSelected,
1134 1140 'initial': initial,
1135 1141 }
1136 1142 }
1137 1143
1138 1144 animateDiffNavText = function () {
1139 1145 var $diffNav = $('#diff_nav')
1140 1146
1141 1147 var callback = function () {
1142 1148 $diffNav.animate({'opacity': 1.00}, 200)
1143 1149 };
1144 1150 $diffNav.animate({'opacity': 0.15}, 200, callback);
1145 1151 }
1146 1152
1147 1153 scrollToChunk = function (moveBy) {
1148 1154 var chunk = getCurrentChunk();
1149 1155 var all = chunk.all
1150 1156 var selected = chunk.selected
1151 1157
1152 1158 var curPos = all.index(selected);
1153 1159 var newPos = curPos;
1154 1160 if (!chunk.initial) {
1155 1161 var newPos = curPos + moveBy;
1156 1162 }
1157 1163
1158 1164 var curElem = all.get(newPos);
1159 1165
1160 1166 if (curElem === undefined) {
1161 1167 // end or back
1162 1168 $('#diff_nav').html('no next diff element:')
1163 1169 animateDiffNavText()
1164 1170 return
1165 1171 } else if (newPos < 0) {
1166 1172 $('#diff_nav').html('no previous diff element:')
1167 1173 animateDiffNavText()
1168 1174 return
1169 1175 } else {
1170 1176 $('#diff_nav').html(diffNavText)
1171 1177 }
1172 1178
1173 1179 curElem = $(curElem)
1174 1180 var offset = 100;
1175 1181 $(window).scrollTop(curElem.position().top - offset);
1176 1182
1177 1183 //clear selection
1178 1184 all.removeClass('selected')
1179 1185 curElem.addClass('selected')
1180 1186 }
1181 1187
1182 1188 scrollToPrevChunk = function () {
1183 1189 scrollToChunk(-1)
1184 1190 }
1185 1191 scrollToNextChunk = function () {
1186 1192 scrollToChunk(1)
1187 1193 }
1188 1194
1189 1195 </script>
1190 1196 % endif
1191 1197
1192 1198 <script type="text/javascript">
1193 1199 $('#diff_nav').html('loading diff...') // wait until whole page is loaded
1194 1200
1195 1201 $(document).ready(function () {
1196 1202
1197 1203 var contextPrefix = _gettext('Context file: ');
1198 1204 ## sticky sidebar
1199 1205 var sidebarElement = document.getElementById('diff-file-sticky');
1200 1206 sidebar = new StickySidebar(sidebarElement, {
1201 1207 topSpacing: 0,
1202 1208 bottomSpacing: 0,
1203 1209 innerWrapperSelector: '.sidebar__inner'
1204 1210 });
1205 1211 sidebarElement.addEventListener('affixed.static.stickySidebar', function () {
1206 1212 // reset our file so it's not holding new value
1207 1213 $('.fpath-placeholder-text').html(contextPrefix + ' - ')
1208 1214 });
1209 1215
1210 1216 updateSticky = function () {
1211 1217 sidebar.updateSticky();
1212 1218 Waypoint.refreshAll();
1213 1219 };
1214 1220
1215 1221 var animateText = function (fPath, anchorId) {
1216 1222 fPath = Select2.util.escapeMarkup(fPath);
1217 1223 $('.fpath-placeholder-text').html(contextPrefix + '<a href="#a_' + anchorId + '">' + fPath + '</a>')
1218 1224 };
1219 1225
1220 1226 ## dynamic file waypoints
1221 1227 var setFPathInfo = function(fPath, anchorId){
1222 1228 animateText(fPath, anchorId)
1223 1229 };
1224 1230
1225 1231 var codeBlock = $('.filediff');
1226 1232
1227 1233 // forward waypoint
1228 1234 codeBlock.waypoint(
1229 1235 function(direction) {
1230 1236 if (direction === "down"){
1231 1237 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
1232 1238 }
1233 1239 }, {
1234 1240 offset: function () {
1235 1241 return 70;
1236 1242 },
1237 1243 context: '.fpath-placeholder'
1238 1244 }
1239 1245 );
1240 1246
1241 1247 // backward waypoint
1242 1248 codeBlock.waypoint(
1243 1249 function(direction) {
1244 1250 if (direction === "up"){
1245 1251 setFPathInfo($(this.element).data('fPath'), $(this.element).data('anchorId'))
1246 1252 }
1247 1253 }, {
1248 1254 offset: function () {
1249 1255 return -this.element.clientHeight + 90;
1250 1256 },
1251 1257 context: '.fpath-placeholder'
1252 1258 }
1253 1259 );
1254 1260
1255 1261 toggleWideDiff = function (el) {
1256 1262 updateSticky();
1257 1263 var wide = Rhodecode.comments.toggleWideMode(this);
1258 1264 storeUserSessionAttr('rc_user_session_attr.wide_diff_mode', wide);
1259 1265 if (wide === true) {
1260 1266 $(el).addClass('btn-active');
1261 1267 } else {
1262 1268 $(el).removeClass('btn-active');
1263 1269 }
1264 1270 return null;
1265 1271 };
1266 1272
1267 1273 var preloadDiffMenuData = {
1268 1274 results: [
1269 1275
1270 1276 ## Whitespace change
1271 1277 % if request.GET.get('ignorews', '') == '1':
1272 1278 {
1273 1279 id: 2,
1274 1280 text: _gettext('Show whitespace changes'),
1275 1281 action: function () {},
1276 1282 url: "${h.current_route_path(request, ignorews=0)|n}"
1277 1283 },
1278 1284 % else:
1279 1285 {
1280 1286 id: 2,
1281 1287 text: _gettext('Hide whitespace changes'),
1282 1288 action: function () {},
1283 1289 url: "${h.current_route_path(request, ignorews=1)|n}"
1284 1290 },
1285 1291 % endif
1286 1292
1287 1293 ## FULL CONTEXT
1288 1294 % if request.GET.get('fullcontext', '') == '1':
1289 1295 {
1290 1296 id: 3,
1291 1297 text: _gettext('Hide full context diff'),
1292 1298 action: function () {},
1293 1299 url: "${h.current_route_path(request, fullcontext=0)|n}"
1294 1300 },
1295 1301 % else:
1296 1302 {
1297 1303 id: 3,
1298 1304 text: _gettext('Show full context diff'),
1299 1305 action: function () {},
1300 1306 url: "${h.current_route_path(request, fullcontext=1)|n}"
1301 1307 },
1302 1308 % endif
1303 1309
1304 1310 ]
1305 1311 };
1306 1312
1307 1313 var diffMenuId = "#diff_menu_" + "${diffset_container_id}";
1308 1314 $(diffMenuId).select2({
1309 1315 minimumResultsForSearch: -1,
1310 1316 containerCssClass: "drop-menu-no-width",
1311 1317 dropdownCssClass: "drop-menu-dropdown",
1312 1318 dropdownAutoWidth: true,
1313 1319 data: preloadDiffMenuData,
1314 1320 placeholder: "${_('...')}",
1315 1321 });
1316 1322 $(diffMenuId).on('select2-selecting', function (e) {
1317 1323 e.choice.action();
1318 1324 if (e.choice.url !== null) {
1319 1325 window.location = e.choice.url
1320 1326 }
1321 1327 });
1322 1328 toggleExpand = function (el, diffsetEl) {
1323 1329 var el = $(el);
1324 1330 if (el.hasClass('collapsed')) {
1325 1331 $('.filediff-collapse-state.collapse-{0}'.format(diffsetEl)).prop('checked', false);
1326 1332 el.removeClass('collapsed');
1327 1333 el.html(
1328 1334 '<i class="icon-minus-squared-alt icon-no-margin"></i>' +
1329 1335 _gettext('Collapse all files'));
1330 1336 }
1331 1337 else {
1332 1338 $('.filediff-collapse-state.collapse-{0}'.format(diffsetEl)).prop('checked', true);
1333 1339 el.addClass('collapsed');
1334 1340 el.html(
1335 1341 '<i class="icon-plus-squared-alt icon-no-margin"></i>' +
1336 1342 _gettext('Expand all files'));
1337 1343 }
1338 1344 updateSticky()
1339 1345 };
1340 1346
1341 1347 toggleCommitExpand = function (el) {
1342 1348 var $el = $(el);
1343 1349 var commits = $el.data('toggleCommitsCnt');
1344 1350 var collapseMsg = _ngettext('Collapse {0} commit', 'Collapse {0} commits', commits).format(commits);
1345 1351 var expandMsg = _ngettext('Expand {0} commit', 'Expand {0} commits', commits).format(commits);
1346 1352
1347 1353 if ($el.hasClass('collapsed')) {
1348 1354 $('.compare_select').show();
1349 1355 $('.compare_select_hidden').hide();
1350 1356
1351 1357 $el.removeClass('collapsed');
1352 1358 $el.html(
1353 1359 '<i class="icon-minus-squared-alt icon-no-margin"></i>' +
1354 1360 collapseMsg);
1355 1361 }
1356 1362 else {
1357 1363 $('.compare_select').hide();
1358 1364 $('.compare_select_hidden').show();
1359 1365 $el.addClass('collapsed');
1360 1366 $el.html(
1361 1367 '<i class="icon-plus-squared-alt icon-no-margin"></i>' +
1362 1368 expandMsg);
1363 1369 }
1364 1370 updateSticky();
1365 1371 };
1366 1372
1367 1373 // get stored diff mode and pre-enable it
1368 1374 if (templateContext.session_attrs.wide_diff_mode === "true") {
1369 1375 Rhodecode.comments.toggleWideMode(null);
1370 1376 $('.toggle-wide-diff').addClass('btn-active');
1371 1377 updateSticky();
1372 1378 }
1373 1379
1374 1380 // DIFF NAV //
1375 1381
1376 1382 // element to detect scroll direction of
1377 1383 var $window = $(window);
1378 1384
1379 1385 // initialize last scroll position
1380 1386 var lastScrollY = $window.scrollTop();
1381 1387
1382 1388 $window.on('resize scrollstop', {latency: 350}, function () {
1383 1389 var visibleChunks = $('.nav-chunk').withinviewport({top: 75});
1384 1390
1385 1391 // get current scroll position
1386 1392 var currentScrollY = $window.scrollTop();
1387 1393
1388 1394 // determine current scroll direction
1389 1395 if (currentScrollY > lastScrollY) {
1390 1396 var y = 'down'
1391 1397 } else if (currentScrollY !== lastScrollY) {
1392 1398 var y = 'up';
1393 1399 }
1394 1400
1395 1401 var pos = -1; // by default we use last element in viewport
1396 1402 if (y === 'down') {
1397 1403 pos = -1;
1398 1404 } else if (y === 'up') {
1399 1405 pos = 0;
1400 1406 }
1401 1407
1402 1408 if (visibleChunks.length > 0) {
1403 1409 $('.nav-chunk').removeClass('selected');
1404 1410 $(visibleChunks.get(pos)).addClass('selected');
1405 1411 }
1406 1412
1407 1413 // update last scroll position to current position
1408 1414 lastScrollY = currentScrollY;
1409 1415
1410 1416 });
1411 1417 $('#diff_nav').html(diffNavText);
1412 1418
1413 1419 });
1414 1420 </script>
1415 1421
1416 1422 </%def>
General Comments 0
You need to be logged in to leave comments. Login now