##// END OF EJS Templates
js: refactor js and move logic to files.js
ergo -
r3713:d94ac941 new-ui
parent child Browse files
Show More
@@ -1,330 +1,411 b''
1 1 // # Copyright (C) 2010-2019 RhodeCode GmbH
2 2 // #
3 3 // # This program is free software: you can redistribute it and/or modify
4 4 // # it under the terms of the GNU Affero General Public License, version 3
5 5 // # (only), as published by the Free Software Foundation.
6 6 // #
7 7 // # This program is distributed in the hope that it will be useful,
8 8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 // # GNU General Public License for more details.
11 11 // #
12 12 // # You should have received a copy of the GNU Affero General Public License
13 13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 // #
15 15 // # This program is dual-licensed. If you wish to learn more about the
16 16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 19 /**
20 20 * Search file list
21 21 */
22 22
23 23 var NodeFilter = {};
24 24
25 25 var fileBrowserListeners = function (node_list_url, url_base) {
26 26 var $filterInput = $('#node_filter');
27 27 var n_filter = $filterInput.get(0);
28 28
29 29 NodeFilter.filterTimeout = null;
30 30 var nodes = null;
31 31
32 32 NodeFilter.focus = function () {
33 33 $filterInput.focus()
34 34 };
35 35
36 36 NodeFilter.fetchNodes = function (callback) {
37 37 $.ajax(
38 38 {url: node_list_url, headers: {'X-PARTIAL-XHR': true}})
39 39 .done(function (data) {
40 40 nodes = data.nodes;
41 41 if (callback) {
42 42 callback();
43 43 }
44 44 })
45 45 .fail(function (data) {
46 46 console.log('failed to load');
47 47 });
48 48 };
49 49
50 50 NodeFilter.initFilter = function (e) {
51 51 if ($filterInput.hasClass('loading')) {
52 52 return
53 53 }
54 54
55 55 // in case we are already loaded, do nothing
56 56 if (!$filterInput.hasClass('init')) {
57 57 return NodeFilter.handleKey(e);
58 58 }
59 59 var iconLoading = 'icon-spin animate-spin';
60 60 var iconSearch = 'icon-search';
61 61 $('.files-filter-box-path i').removeClass(iconSearch).addClass(iconLoading);
62 62 $filterInput.addClass('loading');
63 63
64 64 var callback = function (org) {
65 65 return function () {
66 66 if ($filterInput.hasClass('init')) {
67 67 $filterInput.removeClass('init');
68 68 $filterInput.removeClass('loading');
69 69 }
70 70 $('.files-filter-box-path i').removeClass(iconLoading).addClass(iconSearch);
71 71
72 72 // auto re-filter if we filled in the input
73 73 if (n_filter.value !== "") {
74 74 NodeFilter.updateFilter(n_filter, e)()
75 75 }
76 76
77 77 }
78 78 };
79 79 // load node data
80 80 NodeFilter.fetchNodes(callback());
81 81
82 82 };
83 83
84 84 NodeFilter.resetFilter = function () {
85 85 $('#tbody').show();
86 86 $('#tbody_filtered').hide();
87 87 $filterInput.val('');
88 88 };
89 89
90 90 NodeFilter.handleKey = function (e) {
91 91 var scrollDown = function (element) {
92 92 var elementBottom = element.offset().top + $(element).outerHeight();
93 93 var windowBottom = window.innerHeight + $(window).scrollTop();
94 94 if (elementBottom > windowBottom) {
95 95 var offset = elementBottom - window.innerHeight;
96 96 $('html,body').scrollTop(offset);
97 97 return false;
98 98 }
99 99 return true;
100 100 };
101 101
102 102 var scrollUp = function (element) {
103 103 if (element.offset().top < $(window).scrollTop()) {
104 104 $('html,body').scrollTop(element.offset().top);
105 105 return false;
106 106 }
107 107 return true;
108 108 };
109 109 var $hlElem = $('.browser-highlight');
110 110
111 111 if (e.keyCode === 40) { // Down
112 112 if ($hlElem.length === 0) {
113 113 $('.browser-result').first().addClass('browser-highlight');
114 114 } else {
115 115 var next = $hlElem.next();
116 116 if (next.length !== 0) {
117 117 $hlElem.removeClass('browser-highlight');
118 118 next.addClass('browser-highlight');
119 119 }
120 120 }
121 121
122 122 if ($hlElem.get(0) !== undefined){
123 123 scrollDown($hlElem);
124 124 }
125 125 }
126 126 if (e.keyCode === 38) { // Up
127 127 e.preventDefault();
128 128 if ($hlElem.length !== 0) {
129 129 var next = $hlElem.prev();
130 130 if (next.length !== 0) {
131 131 $('.browser-highlight').removeClass('browser-highlight');
132 132 next.addClass('browser-highlight');
133 133 }
134 134 }
135 135
136 136 if ($hlElem.get(0) !== undefined){
137 137 scrollUp($hlElem);
138 138 }
139 139
140 140 }
141 141 if (e.keyCode === 13) { // Enter
142 142 if ($('.browser-highlight').length !== 0) {
143 143 var url = $('.browser-highlight').find('.match-link').attr('href');
144 144 window.location = url;
145 145 }
146 146 }
147 147 if (e.keyCode === 27) { // Esc
148 148 NodeFilter.resetFilter();
149 149 $('html,body').scrollTop(0);
150 150 }
151 151
152 152 var capture_keys = [
153 153 40, // ArrowDown
154 154 38, // ArrowUp
155 155 39, // ArrowRight
156 156 37, // ArrowLeft
157 157 13, // Enter
158 158 27 // Esc
159 159 ];
160 160
161 161 if ($.inArray(e.keyCode, capture_keys) === -1) {
162 162 clearTimeout(NodeFilter.filterTimeout);
163 163 NodeFilter.filterTimeout = setTimeout(NodeFilter.updateFilter(n_filter, e), 200);
164 164 }
165 165
166 166 };
167 167
168 168 NodeFilter.fuzzy_match = function (filepath, query) {
169 169 var highlight = [];
170 170 var order = 0;
171 171 for (var i = 0; i < query.length; i++) {
172 172 var match_position = filepath.indexOf(query[i]);
173 173 if (match_position !== -1) {
174 174 var prev_match_position = highlight[highlight.length - 1];
175 175 if (prev_match_position === undefined) {
176 176 highlight.push(match_position);
177 177 } else {
178 178 var current_match_position = prev_match_position + match_position + 1;
179 179 highlight.push(current_match_position);
180 180 order = order + current_match_position - prev_match_position;
181 181 }
182 182 filepath = filepath.substring(match_position + 1);
183 183 } else {
184 184 return false;
185 185 }
186 186 }
187 187 return {
188 188 'order': order,
189 189 'highlight': highlight
190 190 };
191 191 };
192 192
193 193 NodeFilter.sortPredicate = function (a, b) {
194 194 if (a.order < b.order) return -1;
195 195 if (a.order > b.order) return 1;
196 196 if (a.filepath < b.filepath) return -1;
197 197 if (a.filepath > b.filepath) return 1;
198 198 return 0;
199 199 };
200 200
201 201 NodeFilter.updateFilter = function (elem, e) {
202 202 return function () {
203 203 // Reset timeout
204 204 NodeFilter.filterTimeout = null;
205 205 var query = elem.value.toLowerCase();
206 206 var match = [];
207 207 var matches_max = 20;
208 208 if (query !== "") {
209 209 var results = [];
210 210 for (var k = 0; k < nodes.length; k++) {
211 211 var result = NodeFilter.fuzzy_match(
212 212 nodes[k].name.toLowerCase(), query);
213 213 if (result) {
214 214 result.type = nodes[k].type;
215 215 result.filepath = nodes[k].name;
216 216 results.push(result);
217 217 }
218 218 }
219 219 results = results.sort(NodeFilter.sortPredicate);
220 220 var limit = matches_max;
221 221 if (results.length < matches_max) {
222 222 limit = results.length;
223 223 }
224 224 for (var i = 0; i < limit; i++) {
225 225 if (query && results.length > 0) {
226 226 var n = results[i].filepath;
227 227 var t = results[i].type;
228 228 var n_hl = n.split("");
229 229 var pos = results[i].highlight;
230 230 for (var j = 0; j < pos.length; j++) {
231 231 n_hl[pos[j]] = "<em>" + n_hl[pos[j]] + "</em>";
232 232 }
233 233 n_hl = n_hl.join("");
234 234 var new_url = url_base.replace('__FPATH__', n);
235 235
236 236 var typeObj = {
237 237 dir: 'icon-directory browser-dir',
238 238 file: 'icon-file-text browser-file'
239 239 };
240 240
241 241 var typeIcon = '<i class="{0}"></i>'.format(typeObj[t]);
242 242 match.push('<tr class="browser-result"><td><a class="match-link" href="{0}">{1}{2}</a></td><td colspan="5"></td></tr>'.format(new_url, typeIcon, n_hl));
243 243 }
244 244 }
245 245 if (results.length > limit) {
246 246 var truncated_count = results.length - matches_max;
247 247 if (truncated_count === 1) {
248 248 match.push('<tr><td>{0} {1}</td><td colspan="5"></td></tr>'.format(truncated_count, _gettext('truncated result')));
249 249 } else {
250 250 match.push('<tr><td>{0} {1}</td><td colspan="5"></td></tr>'.format(truncated_count, _gettext('truncated results')));
251 251 }
252 252 }
253 253 }
254 254 if (query !== "") {
255 255 $('#tbody').hide();
256 256 $('#tbody_filtered').show();
257 257
258 258 if (match.length === 0) {
259 259 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_gettext('No matching files')));
260 260 }
261 261 $('#tbody_filtered').html(match.join(""));
262 262 } else {
263 263 $('#tbody').show();
264 264 $('#tbody_filtered').hide();
265 265 }
266 266
267 267 };
268 268 };
269 269
270 270 };
271 271
272 272 var getIdentNode = function(n){
273 273 // iterate through nodes until matched interesting node
274 274 if (typeof n === 'undefined'){
275 275 return -1;
276 276 }
277 277 if(typeof n.id !== "undefined" && n.id.match('L[0-9]+')){
278 278 return n;
279 279 }
280 280 else{
281 281 return getIdentNode(n.parentNode);
282 282 }
283 283 };
284 284
285 285 var getSelectionLink = function(e) {
286 286 // get selection from start/to nodes
287 287 if (typeof window.getSelection !== "undefined") {
288 288 s = window.getSelection();
289 289
290 290 from = getIdentNode(s.anchorNode);
291 291 till = getIdentNode(s.focusNode);
292 292
293 293 f_int = parseInt(from.id.replace('L',''));
294 294 t_int = parseInt(till.id.replace('L',''));
295 295
296 296 if (f_int > t_int){
297 297 // highlight from bottom
298 298 offset = -35;
299 299 ranges = [t_int,f_int];
300 300 }
301 301 else{
302 302 // highligth from top
303 303 offset = 35;
304 304 ranges = [f_int,t_int];
305 305 }
306 306 // if we select more than 2 lines
307 307 if (ranges[0] !== ranges[1]){
308 308 if($('#linktt').length === 0){
309 309 hl_div = document.createElement('div');
310 310 hl_div.id = 'linktt';
311 311 }
312 312 hl_div.innerHTML = '';
313 313
314 314 anchor = '#L'+ranges[0]+'-'+ranges[1];
315 315 var link = document.createElement('a');
316 316 link.href = location.href.substring(0,location.href.indexOf('#'))+anchor;
317 317 link.innerHTML = _gettext('Selection link');
318 318 hl_div.appendChild(link);
319 319 $('#codeblock').append(hl_div);
320 320
321 321 var xy = $(till).offset();
322 322 $('#linktt').addClass('hl-tip-box tip-box');
323 323 $('#linktt').offset({top: xy.top + offset, left: xy.left});
324 324 $('#linktt').css('visibility','visible');
325 325 }
326 326 else{
327 327 $('#linktt').css('visibility','hidden');
328 328 }
329 329 }
330 330 };
331
332 var getFileState = function() {
333 // relies on a global set filesUrlData
334 var f_path = filesUrlData['f_path'];
335 var commit_id = filesUrlData['commit_id'];
336
337 var url_params = {
338 repo_name: templateContext.repo_name,
339 commit_id: commit_id,
340 f_path:'__FPATH__'
341 };
342 if (atRef !== '') {
343 url_params['at'] = atRef
344 }
345
346 var _url_base = pyroutes.url('repo_files', url_params);
347 var _node_list_url = pyroutes.url('repo_files_nodelist',
348 {repo_name: templateContext.repo_name,
349 commit_id: commit_id, f_path: f_path});
350
351 return {
352 f_path: f_path,
353 commit_id: commit_id,
354 node_list_url: _node_list_url,
355 url_base: _url_base
356 };
357 };
358
359 var getFilesMetadata = function() {
360 // relies on metadataRequest global state
361 if (metadataRequest && metadataRequest.readyState != 4) {
362 metadataRequest.abort();
363 }
364
365 if ($('#file-tree-wrapper').hasClass('full-load')) {
366 // in case our HTML wrapper has full-load class we don't
367 // trigger the async load of metadata
368 return false;
369 }
370
371 var state = getFileState();
372 var url_data = {
373 'repo_name': templateContext.repo_name,
374 'commit_id': state.commit_id,
375 'f_path': state.f_path
376 };
377
378 var url = pyroutes.url('repo_nodetree_full', url_data);
379
380 metadataRequest = $.ajax({url: url});
381
382 metadataRequest.done(function(data) {
383 $('#file-tree').html(data);
384 timeagoActivate();
385 });
386 metadataRequest.fail(function (data, textStatus, errorThrown) {
387 if (data.status != 0) {
388 alert("Error while fetching metadata.\nError code {0} ({1}).Please consider reloading the page".format(data.status,data.statusText));
389 }
390 });
391 };
392
393 // show more authors
394 var showAuthors = function(elem, annotate) {
395 var state = getFileState('callbacks');
396
397 var url = pyroutes.url('repo_file_authors',
398 {'repo_name': templateContext.repo_name,
399 'commit_id': state.commit_id, 'f_path': state.f_path});
400
401 $.pjax({
402 url: url,
403 data: 'annotate={0}'.format(annotate),
404 container: '#file_authors',
405 push: false,
406 timeout: 5000
407 }).complete(function(){
408 $(elem).hide();
409 $('#file_authors_title').html(_gettext('All Authors'))
410 })
411 };
@@ -1,35 +1,35 b''
1 1 <%namespace name="base" file="/base/base.mako"/>
2 2
3 3 % if c.authors:
4 4
5 5 <table class="sidebar-right-content">
6 6 % for email, user, commits in sorted(c.authors, key=lambda e: c.file_last_commit.author_email!=e[0]):
7 7 <tr class="file_author tooltip" title="${h.tooltip(h.author_string(email))}">
8 8
9 9 <td>
10 10 <span class="user commit-author">${h.link_to_user(user)}</span>
11 11 % if c.file_author:
12 12 <span class="commit-date">- ${h.age_component(c.file_last_commit.date)}</span>
13 <a href="#ShowAuthors" id="show_authors" class="action_link"> - ${_('Load All Authors')}</a>
13 <a href="#ShowAuthors" onclick="showAuthors(this, ${("1" if c.annotate else "0")}); return false" class="action_link"> - ${_('Load All Authors')}</a>
14 14 % elif c.file_last_commit.author_email==email:
15 15 <span> (${_('last author')})</span>
16 16 % endif
17 17 </td>
18 18
19 19 <td>
20 20 % if not c.file_author:
21 21 <code>
22 22 % if commits == 1:
23 23 ${commits} ${_('Commit')}
24 24 % else:
25 25 ${commits} ${_('Commits')}
26 26 % endif
27 27 </code>
28 28 % endif
29 29 </td>
30 30 </tr>
31 31
32 32 % endfor
33 33 </table>
34 34 % endif
35 35
@@ -1,467 +1,369 b''
1 1 <%inherit file="/base/base.mako"/>
2 2
3 3 <%def name="title(*args)">
4 4 ${_('{} Files').format(c.repo_name)}
5 5 %if hasattr(c,'file'):
6 6 &middot; ${(h.safe_unicode(c.file.path) or '\\')}
7 7 %endif
8 8
9 9 %if c.rhodecode_name:
10 10 &middot; ${h.branding(c.rhodecode_name)}
11 11 %endif
12 12 </%def>
13 13
14 14 <%def name="breadcrumbs_links()">
15 15 ${_('Files')}
16 16 %if c.file:
17 17 @ ${h.show_id(c.commit)}
18 18 %endif
19 19 </%def>
20 20
21 21 <%def name="menu_bar_nav()">
22 22 ${self.menu_items(active='repositories')}
23 23 </%def>
24 24
25 25 <%def name="menu_bar_subnav()">
26 26 ${self.repo_menu(active='files')}
27 27 </%def>
28 28
29 29 <%def name="main()">
30 <script type="text/javascript">
31 var fileSourcePage = ${c.file_source_page};
32 var atRef = '${request.GET.get('at', '')}';
33
34 // global state for fetching metadata
35 metadataRequest = null;
36
37 // global metadata about URL
38 filesUrlData = ${h.json.dumps(request.matchdict)|n};
39 </script>
40
30 41 <div>
31 42 <div id="files_data">
32 43 <%include file='files_pjax.mako'/>
33 44 </div>
34 45 </div>
35 <script>
36 46
37 var metadataRequest = null;
38 var fileSourcePage = ${c.file_source_page};
39 var atRef = '${request.GET.get('at', '')}';
40
41 var getState = function(context) {
42 var url = $(location).attr('href');
43 var _base_url = '${h.route_path("repo_files",repo_name=c.repo_name,commit_id='',f_path='')}';
44 var _annotate_url = '${h.route_path("repo_files:annotated",repo_name=c.repo_name,commit_id='',f_path='')}';
45 _base_url = _base_url.replace('//', '/');
46 _annotate_url = _annotate_url.replace('//', '/');
47
48 //extract f_path from url.
49 var parts = url.split(_base_url);
50 if (parts.length != 2) {
51 parts = url.split(_annotate_url);
52 if (parts.length != 2) {
53 var rev = "tip";
54 var f_path = "";
55 } else {
56 var parts2 = parts[1].split('/');
57 var rev = parts2.shift(); // pop the first element which is the revision
58 var f_path = parts2.join('/');
59 }
60
61 } else {
62 var parts2 = parts[1].split('/');
63 var rev = parts2.shift(); // pop the first element which is the revision
64 var f_path = parts2.join('/');
65 }
66
67 var url_params = {
68 repo_name: templateContext.repo_name,
69 commit_id: rev,
70 f_path:'__FPATH__'
71 };
72 if (atRef !== '') {
73 url_params['at'] = atRef
74 }
75
76 var _url_base = pyroutes.url('repo_files', url_params);
77 var _node_list_url = pyroutes.url('repo_files_nodelist',
78 {repo_name: templateContext.repo_name,
79 commit_id: rev, f_path: f_path});
80
81 return {
82 url: url,
83 f_path: f_path,
84 rev: rev,
85 commit_id: "${c.commit.raw_id}",
86 node_list_url: _node_list_url,
87 url_base: _url_base
88 };
89 };
90
91 var getFilesMetadata = function() {
92 if (metadataRequest && metadataRequest.readyState != 4) {
93 metadataRequest.abort();
94 }
95 if (fileSourcePage) {
96 return false;
97 }
98
99 if ($('#file-tree-wrapper').hasClass('full-load')) {
100 // in case our HTML wrapper has full-load class we don't
101 // trigger the async load of metadata
102 return false;
103 }
104
105 var state = getState('metadata');
106 var url_data = {
107 'repo_name': templateContext.repo_name,
108 'commit_id': state.commit_id,
109 'f_path': state.f_path
110 };
111
112 var url = pyroutes.url('repo_nodetree_full', url_data);
113
114 metadataRequest = $.ajax({url: url});
115
116 metadataRequest.done(function(data) {
117 $('#file-tree').html(data);
118 timeagoActivate();
119 });
120 metadataRequest.fail(function (data, textStatus, errorThrown) {
121 if (data.status != 0) {
122 alert("Error while fetching metadata.\nError code {0} ({1}).Please consider reloading the page".format(data.status,data.statusText));
123 }
124 });
125 };
47 <script type="text/javascript">
126 48
127 49 var initFileJS = function () {
128 var state = getState('callbacks');
50 var state = getFileState();
129 51
130 52 // select code link event
131 53 $("#hlcode").mouseup(getSelectionLink);
132 54
133 55 // file history select2 used for history of file, and switch to
134 56 var initialCommitData = {
135 57 at_ref: atRef,
136 58 id: null,
137 59 text: '${c.commit.raw_id}',
138 60 type: 'sha',
139 61 raw_id: '${c.commit.raw_id}',
140 62 idx: ${c.commit.idx},
141 63 files_url: null,
142 64 };
143 65
144 66 // check if we have ref info.
145 67 var selectedRef = fileTreeRefs[atRef];
146 68 if (selectedRef !== undefined) {
147 69 $.extend(initialCommitData, selectedRef)
148 70 }
149 71
150 var loadUrl = pyroutes.url('repo_file_history', {'repo_name': templateContext.repo_name, 'commit_id': state.rev,'f_path': state.f_path});
72 var loadUrl = pyroutes.url('repo_file_history', {'repo_name': templateContext.repo_name, 'commit_id': state.commit_id,'f_path': state.f_path});
151 73 var cacheKey = '__SINGLE_FILE_REFS__';
152 74 var cachedDataSource = {};
153 75
154 76 var loadRefsData = function (query) {
155 77 $.ajax({
156 78 url: loadUrl,
157 79 data: {},
158 80 dataType: 'json',
159 81 type: 'GET',
160 82 success: function (data) {
161 83 cachedDataSource[cacheKey] = data;
162 84 query.callback({results: data.results});
163 85 }
164 86 });
165 87 };
166 88
167 89 var feedRefsData = function (query, cachedData) {
168 90 var data = {results: []};
169 91 //filter results
170 92 $.each(cachedData.results, function () {
171 93 var section = this.text;
172 94 var children = [];
173 95 $.each(this.children, function () {
174 96 if (query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
175 97 children.push(this)
176 98 }
177 99 });
178 100 data.results.push({
179 101 'text': section,
180 102 'children': children
181 103 })
182 104 });
183 105
184 106 query.callback(data);
185 107 };
186 108
187 109 var select2FileHistorySwitcher = function (targetElement, loadUrl, initialData) {
188 110 var formatResult = function (result, container, query) {
189 111 return formatSelect2SelectionRefs(result);
190 112 };
191 113
192 114 var formatSelection = function (data, container) {
193 115 var commit_ref = data;
194 116
195 117 var tmpl = '';
196 118 if (commit_ref.type === 'sha') {
197 119 tmpl = (commit_ref.raw_id || "").substr(0,8);
198 120 } else if (commit_ref.type === 'branch') {
199 121 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
200 122 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
201 123 } else if (commit_ref.type === 'tag') {
202 124 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
203 125 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
204 126 } else if (commit_ref.type === 'book') {
205 127 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
206 128 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
207 129 }
208 130 var idx = commit_ref.idx || 0;
209 131 if (idx !== 0) {
210 132 tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx));
211 133 }
212 134 return tmpl
213 135 };
214 136
215 137 $(targetElement).select2({
216 138 dropdownAutoWidth: true,
217 139 width: "resolve",
218 140 containerCssClass: "drop-menu",
219 141 dropdownCssClass: "drop-menu-dropdown",
220 142 query: function(query) {
221 143 var cachedData = cachedDataSource[cacheKey];
222 144 if (cachedData) {
223 145 feedRefsData(query, cachedData)
224 146 } else {
225 147 loadRefsData(query)
226 148 }
227 149 },
228 150 initSelection: function(element, callback) {
229 151 callback(initialData);
230 152 },
231 153 formatResult: formatResult,
232 154 formatSelection: formatSelection
233 155 });
234 156
235 157 };
236 158
237 159 select2FileHistorySwitcher('#file_refs_filter', loadUrl, initialCommitData);
238 160
239 161 $('#file_refs_filter').on('change', function(e) {
240 162 var data = $('#file_refs_filter').select2('data');
241 163 var commit_id = data.id;
242 164
243 165 if ("${c.annotate}" === "True") {
244 166 var url = pyroutes.url('repo_files:annotated',
245 167 {'repo_name': templateContext.repo_name,
246 168 'commit_id': commit_id, 'f_path': state.f_path});
247 169 } else {
248 170 var url = pyroutes.url('repo_files',
249 171 {'repo_name': templateContext.repo_name,
250 172 'commit_id': commit_id, 'f_path': state.f_path});
251 173 }
252 174 window.location = url;
253 175
254 176 });
255 177
256 // show more authors
257 $('#show_authors').on('click', function(e) {
258 e.preventDefault();
259 var url = pyroutes.url('repo_file_authors',
260 {'repo_name': templateContext.repo_name,
261 'commit_id': state.rev, 'f_path': state.f_path});
262
263 $.pjax({
264 url: url,
265 data: 'annotate=${("1" if c.annotate else "0")}',
266 container: '#file_authors',
267 push: false,
268 timeout: 5000
269 }).complete(function(){
270 $('#show_authors').hide();
271 $('#file_authors_title').html(_gettext('All Authors'))
272 })
273 });
274
275 178 // load file short history
276 179 $('#file_history_overview').on('click', function(e) {
277 180 e.preventDefault();
278 181 path = state.f_path;
279 182 if (path.indexOf("#") >= 0) {
280 183 path = path.slice(0, path.indexOf("#"));
281 184 }
282 185 var url = pyroutes.url('repo_changelog_file',
283 186 {'repo_name': templateContext.repo_name,
284 'commit_id': state.rev, 'f_path': path, 'limit': 6});
187 'commit_id': state.commit_id, 'f_path': path, 'limit': 6});
285 188 $('#file_history_container').show();
286 189 $('#file_history_container').html('<div class="file-history-inner">{0}</div>'.format(_gettext('Loading ...')));
287 190
288 191 $.pjax({
289 192 url: url,
290 193 container: '#file_history_container',
291 194 push: false,
292 195 timeout: 5000
293 196 });
294 197 });
295 198
296
297 199 };
298 200
299 201 var initTreeJS = function () {
300 var state = getState('callbacks');
202 var state = getFileState();
301 203 getFilesMetadata();
302 204
303 205 // fuzzy file filter
304 206 fileBrowserListeners(state.node_list_url, state.url_base);
305 207
306 208 // switch to widget
307 209 var initialCommitData = {
308 210 at_ref: atRef,
309 211 id: null,
310 212 text: '${c.commit.raw_id}',
311 213 type: 'sha',
312 214 raw_id: '${c.commit.raw_id}',
313 215 idx: ${c.commit.idx},
314 216 files_url: null,
315 217 };
316 218
317 219 // check if we have ref info.
318 220 var selectedRef = fileTreeRefs[atRef];
319 221 if (selectedRef !== undefined) {
320 222 $.extend(initialCommitData, selectedRef)
321 223 }
322 224
323 225 var loadUrl = pyroutes.url('repo_refs_data', {'repo_name': templateContext.repo_name});
324 226 var cacheKey = '__ALL_FILE_REFS__';
325 227 var cachedDataSource = {};
326 228
327 229 var loadRefsData = function (query) {
328 230 $.ajax({
329 231 url: loadUrl,
330 232 data: {},
331 233 dataType: 'json',
332 234 type: 'GET',
333 235 success: function (data) {
334 236 cachedDataSource[cacheKey] = data;
335 237 query.callback({results: data.results});
336 238 }
337 239 });
338 240 };
339 241
340 242 var feedRefsData = function (query, cachedData) {
341 243 var data = {results: []};
342 244 //filter results
343 245 $.each(cachedData.results, function () {
344 246 var section = this.text;
345 247 var children = [];
346 248 $.each(this.children, function () {
347 249 if (query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
348 250 children.push(this)
349 251 }
350 252 });
351 253 data.results.push({
352 254 'text': section,
353 255 'children': children
354 256 })
355 257 });
356 258
357 259 //push the typed in commit idx
358 260 if (!isNaN(query.term)) {
359 261 var files_url = pyroutes.url('repo_files',
360 262 {'repo_name': templateContext.repo_name,
361 263 'commit_id': query.term, 'f_path': state.f_path});
362 264
363 265 data.results.push({
364 266 'text': _gettext('go to numeric commit'),
365 267 'children': [{
366 268 at_ref: null,
367 269 id: null,
368 270 text: 'r{0}'.format(query.term),
369 271 type: 'sha',
370 272 raw_id: query.term,
371 273 idx: query.term,
372 274 files_url: files_url,
373 275 }]
374 276 });
375 277 }
376 278 query.callback(data);
377 279 };
378 280
379 281 var select2RefFileSwitcher = function (targetElement, loadUrl, initialData) {
380 282 var formatResult = function (result, container, query) {
381 283 return formatSelect2SelectionRefs(result);
382 284 };
383 285
384 286 var formatSelection = function (data, container) {
385 287 var commit_ref = data;
386 288
387 289 var tmpl = '';
388 290 if (commit_ref.type === 'sha') {
389 291 tmpl = (commit_ref.raw_id || "").substr(0,8);
390 292 } else if (commit_ref.type === 'branch') {
391 293 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
392 294 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
393 295 } else if (commit_ref.type === 'tag') {
394 296 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
395 297 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
396 298 } else if (commit_ref.type === 'book') {
397 299 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
398 300 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
399 301 }
400 302
401 303 var idx = commit_ref.idx || 0;
402 304 if (idx !== 0) {
403 305 tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx));
404 306 }
405 307 return tmpl
406 308 };
407 309
408 310 $(targetElement).select2({
409 311 dropdownAutoWidth: true,
410 312 width: "resolve",
411 313 containerCssClass: "drop-menu",
412 314 dropdownCssClass: "drop-menu-dropdown",
413 315 query: function(query) {
414 316
415 317 var cachedData = cachedDataSource[cacheKey];
416 318 if (cachedData) {
417 319 feedRefsData(query, cachedData)
418 320 } else {
419 321 loadRefsData(query)
420 322 }
421 323 },
422 324 initSelection: function(element, callback) {
423 325 callback(initialData);
424 326 },
425 327 formatResult: formatResult,
426 328 formatSelection: formatSelection
427 329 });
428 330
429 331 };
430 332
431 333 select2RefFileSwitcher('#refs_filter', loadUrl, initialCommitData);
432 334
433 335 $('#refs_filter').on('change', function(e) {
434 336 var data = $('#refs_filter').select2('data');
435 337 window.location = data.files_url
436 338 });
437 339
438 340 };
439 341
440 342 $(document).ready(function() {
441 343 timeagoActivate();
442 344
443 345 if ($('#trimmed_message_box').height() < 50) {
444 346 $('#message_expand').hide();
445 347 }
446 348
447 349 $('#message_expand').on('click', function(e) {
448 350 $('#trimmed_message_box').css('max-height', 'none');
449 351 $(this).hide();
450 352 });
451 353
452 354 if (fileSourcePage) {
453 355 initFileJS()
454 356 } else {
455 357 initTreeJS()
456 358 }
457 359
458 360 var search_GET = "${request.GET.get('search','')}";
459 361 if (search_GET === "1") {
460 362 NodeFilter.initFilter();
461 363 NodeFilter.focus();
462 364 }
463 365 });
464 366
465 367 </script>
466 368
467 369 </%def> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now