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