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