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