##// END OF EJS Templates
files-source: allow making a range selection with shift on file lines.
ergo -
r2483:aae8d716 default
parent child Browse files
Show More
@@ -1,560 +1,591 b''
1 // # Copyright (C) 2010-2017 RhodeCode GmbH
1 // # Copyright (C) 2010-2017 RhodeCode GmbH
2 // #
2 // #
3 // # This program is free software: you can redistribute it and/or modify
3 // # This program is free software: you can redistribute it and/or modify
4 // # it under the terms of the GNU Affero General Public License, version 3
4 // # it under the terms of the GNU Affero General Public License, version 3
5 // # (only), as published by the Free Software Foundation.
5 // # (only), as published by the Free Software Foundation.
6 // #
6 // #
7 // # This program is distributed in the hope that it will be useful,
7 // # This program is distributed in the hope that it will be useful,
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // # GNU General Public License for more details.
10 // # GNU General Public License for more details.
11 // #
11 // #
12 // # You should have received a copy of the GNU Affero General Public License
12 // # You should have received a copy of the GNU Affero General Public License
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 // #
14 // #
15 // # This program is dual-licensed. If you wish to learn more about the
15 // # This program is dual-licensed. If you wish to learn more about the
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 /**
19 /**
20 RhodeCode JS Files
20 RhodeCode JS Files
21 **/
21 **/
22
22
23 if (typeof console == "undefined" || typeof console.log == "undefined"){
23 if (typeof console == "undefined" || typeof console.log == "undefined"){
24 console = { log: function() {} }
24 console = { log: function() {} }
25 }
25 }
26
26
27 // TODO: move the following function to submodules
27 // TODO: move the following function to submodules
28
28
29 /**
29 /**
30 * show more
30 * show more
31 */
31 */
32 var show_more_event = function(){
32 var show_more_event = function(){
33 $('table .show_more').click(function(e) {
33 $('table .show_more').click(function(e) {
34 var cid = e.target.id.substring(1);
34 var cid = e.target.id.substring(1);
35 var button = $(this);
35 var button = $(this);
36 if (button.hasClass('open')) {
36 if (button.hasClass('open')) {
37 $('#'+cid).hide();
37 $('#'+cid).hide();
38 button.removeClass('open');
38 button.removeClass('open');
39 } else {
39 } else {
40 $('#'+cid).show();
40 $('#'+cid).show();
41 button.addClass('open one');
41 button.addClass('open one');
42 }
42 }
43 });
43 });
44 };
44 };
45
45
46 var compare_radio_buttons = function(repo_name, compare_ref_type){
46 var compare_radio_buttons = function(repo_name, compare_ref_type){
47 $('#compare_action').on('click', function(e){
47 $('#compare_action').on('click', function(e){
48 e.preventDefault();
48 e.preventDefault();
49
49
50 var source = $('input[name=compare_source]:checked').val();
50 var source = $('input[name=compare_source]:checked').val();
51 var target = $('input[name=compare_target]:checked').val();
51 var target = $('input[name=compare_target]:checked').val();
52 if(source && target){
52 if(source && target){
53 var url_data = {
53 var url_data = {
54 repo_name: repo_name,
54 repo_name: repo_name,
55 source_ref: source,
55 source_ref: source,
56 source_ref_type: compare_ref_type,
56 source_ref_type: compare_ref_type,
57 target_ref: target,
57 target_ref: target,
58 target_ref_type: compare_ref_type,
58 target_ref_type: compare_ref_type,
59 merge: 1
59 merge: 1
60 };
60 };
61 window.location = pyroutes.url('repo_compare', url_data);
61 window.location = pyroutes.url('repo_compare', url_data);
62 }
62 }
63 });
63 });
64 $('.compare-radio-button').on('click', function(e){
64 $('.compare-radio-button').on('click', function(e){
65 var source = $('input[name=compare_source]:checked').val();
65 var source = $('input[name=compare_source]:checked').val();
66 var target = $('input[name=compare_target]:checked').val();
66 var target = $('input[name=compare_target]:checked').val();
67 if(source && target){
67 if(source && target){
68 $('#compare_action').removeAttr("disabled");
68 $('#compare_action').removeAttr("disabled");
69 $('#compare_action').removeClass("disabled");
69 $('#compare_action').removeClass("disabled");
70 }
70 }
71 })
71 })
72 };
72 };
73
73
74 var showRepoSize = function(target, repo_name, commit_id, callback) {
74 var showRepoSize = function(target, repo_name, commit_id, callback) {
75 var container = $('#' + target);
75 var container = $('#' + target);
76 var url = pyroutes.url('repo_stats',
76 var url = pyroutes.url('repo_stats',
77 {"repo_name": repo_name, "commit_id": commit_id});
77 {"repo_name": repo_name, "commit_id": commit_id});
78
78
79 if (!container.hasClass('loaded')) {
79 if (!container.hasClass('loaded')) {
80 $.ajax({url: url})
80 $.ajax({url: url})
81 .complete(function (data) {
81 .complete(function (data) {
82 var responseJSON = data.responseJSON;
82 var responseJSON = data.responseJSON;
83 container.addClass('loaded');
83 container.addClass('loaded');
84 container.html(responseJSON.size);
84 container.html(responseJSON.size);
85 callback(responseJSON.code_stats)
85 callback(responseJSON.code_stats)
86 })
86 })
87 .fail(function (data) {
87 .fail(function (data) {
88 console.log('failed to load repo stats');
88 console.log('failed to load repo stats');
89 });
89 });
90 }
90 }
91
91
92 };
92 };
93
93
94 var showRepoStats = function(target, data){
94 var showRepoStats = function(target, data){
95 var container = $('#' + target);
95 var container = $('#' + target);
96
96
97 if (container.hasClass('loaded')) {
97 if (container.hasClass('loaded')) {
98 return
98 return
99 }
99 }
100
100
101 var total = 0;
101 var total = 0;
102 var no_data = true;
102 var no_data = true;
103 var tbl = document.createElement('table');
103 var tbl = document.createElement('table');
104 tbl.setAttribute('class', 'trending_language_tbl');
104 tbl.setAttribute('class', 'trending_language_tbl');
105
105
106 $.each(data, function(key, val){
106 $.each(data, function(key, val){
107 total += val.count;
107 total += val.count;
108 });
108 });
109
109
110 var sortedStats = [];
110 var sortedStats = [];
111 for (var obj in data){
111 for (var obj in data){
112 sortedStats.push([obj, data[obj]])
112 sortedStats.push([obj, data[obj]])
113 }
113 }
114 var sortedData = sortedStats.sort(function (a, b) {
114 var sortedData = sortedStats.sort(function (a, b) {
115 return b[1].count - a[1].count
115 return b[1].count - a[1].count
116 });
116 });
117 var cnt = 0;
117 var cnt = 0;
118 $.each(sortedData, function(idx, val){
118 $.each(sortedData, function(idx, val){
119 cnt += 1;
119 cnt += 1;
120 no_data = false;
120 no_data = false;
121
121
122 var hide = cnt > 2;
122 var hide = cnt > 2;
123 var tr = document.createElement('tr');
123 var tr = document.createElement('tr');
124 if (hide) {
124 if (hide) {
125 tr.setAttribute('style', 'display:none');
125 tr.setAttribute('style', 'display:none');
126 tr.setAttribute('class', 'stats_hidden');
126 tr.setAttribute('class', 'stats_hidden');
127 }
127 }
128
128
129 var key = val[0];
129 var key = val[0];
130 var obj = {"desc": val[1].desc, "count": val[1].count};
130 var obj = {"desc": val[1].desc, "count": val[1].count};
131
131
132 var percentage = Math.round((obj.count / total * 100), 2);
132 var percentage = Math.round((obj.count / total * 100), 2);
133
133
134 var td1 = document.createElement('td');
134 var td1 = document.createElement('td');
135 td1.width = 300;
135 td1.width = 300;
136 var trending_language_label = document.createElement('div');
136 var trending_language_label = document.createElement('div');
137 trending_language_label.innerHTML = obj.desc + " (.{0})".format(key);
137 trending_language_label.innerHTML = obj.desc + " (.{0})".format(key);
138 td1.appendChild(trending_language_label);
138 td1.appendChild(trending_language_label);
139
139
140 var td2 = document.createElement('td');
140 var td2 = document.createElement('td');
141 var trending_language = document.createElement('div');
141 var trending_language = document.createElement('div');
142 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
142 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
143
143
144 trending_language.title = key + " " + nr_files;
144 trending_language.title = key + " " + nr_files;
145
145
146 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
146 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
147 + "</span><b>" + percentage + "% " + nr_files + "</b>";
147 + "</span><b>" + percentage + "% " + nr_files + "</b>";
148
148
149 trending_language.setAttribute("class", 'trending_language');
149 trending_language.setAttribute("class", 'trending_language');
150 $('b', trending_language)[0].style.width = percentage + "%";
150 $('b', trending_language)[0].style.width = percentage + "%";
151 td2.appendChild(trending_language);
151 td2.appendChild(trending_language);
152
152
153 tr.appendChild(td1);
153 tr.appendChild(td1);
154 tr.appendChild(td2);
154 tr.appendChild(td2);
155 tbl.appendChild(tr);
155 tbl.appendChild(tr);
156 if (cnt == 3) {
156 if (cnt == 3) {
157 var show_more = document.createElement('tr');
157 var show_more = document.createElement('tr');
158 var td = document.createElement('td');
158 var td = document.createElement('td');
159 lnk = document.createElement('a');
159 lnk = document.createElement('a');
160
160
161 lnk.href = '#';
161 lnk.href = '#';
162 lnk.innerHTML = _gettext('Show more');
162 lnk.innerHTML = _gettext('Show more');
163 lnk.id = 'code_stats_show_more';
163 lnk.id = 'code_stats_show_more';
164 td.appendChild(lnk);
164 td.appendChild(lnk);
165
165
166 show_more.appendChild(td);
166 show_more.appendChild(td);
167 show_more.appendChild(document.createElement('td'));
167 show_more.appendChild(document.createElement('td'));
168 tbl.appendChild(show_more);
168 tbl.appendChild(show_more);
169 }
169 }
170 });
170 });
171
171
172 $(container).html(tbl);
172 $(container).html(tbl);
173 $(container).addClass('loaded');
173 $(container).addClass('loaded');
174
174
175 $('#code_stats_show_more').on('click', function (e) {
175 $('#code_stats_show_more').on('click', function (e) {
176 e.preventDefault();
176 e.preventDefault();
177 $('.stats_hidden').each(function (idx) {
177 $('.stats_hidden').each(function (idx) {
178 $(this).css("display", "");
178 $(this).css("display", "");
179 });
179 });
180 $('#code_stats_show_more').hide();
180 $('#code_stats_show_more').hide();
181 });
181 });
182
182
183 };
183 };
184
184
185 // returns a node from given html;
185 // returns a node from given html;
186 var fromHTML = function(html){
186 var fromHTML = function(html){
187 var _html = document.createElement('element');
187 var _html = document.createElement('element');
188 _html.innerHTML = html;
188 _html.innerHTML = html;
189 return _html;
189 return _html;
190 };
190 };
191
191
192 // Toggle Collapsable Content
192 // Toggle Collapsable Content
193 function collapsableContent() {
193 function collapsableContent() {
194
194
195 $('.collapsable-content').not('.no-hide').hide();
195 $('.collapsable-content').not('.no-hide').hide();
196
196
197 $('.btn-collapse').unbind(); //in case we've been here before
197 $('.btn-collapse').unbind(); //in case we've been here before
198 $('.btn-collapse').click(function() {
198 $('.btn-collapse').click(function() {
199 var button = $(this);
199 var button = $(this);
200 var togglename = $(this).data("toggle");
200 var togglename = $(this).data("toggle");
201 $('.collapsable-content[data-toggle='+togglename+']').toggle();
201 $('.collapsable-content[data-toggle='+togglename+']').toggle();
202 if ($(this).html()=="Show Less")
202 if ($(this).html()=="Show Less")
203 $(this).html("Show More");
203 $(this).html("Show More");
204 else
204 else
205 $(this).html("Show Less");
205 $(this).html("Show Less");
206 });
206 });
207 };
207 };
208
208
209 var timeagoActivate = function() {
209 var timeagoActivate = function() {
210 $("time.timeago").timeago();
210 $("time.timeago").timeago();
211 };
211 };
212
212
213
213
214 var clipboardActivate = function() {
214 var clipboardActivate = function() {
215 /*
215 /*
216 *
216 *
217 * <i class="tooltip icon-plus clipboard-action" data-clipboard-text="${commit.raw_id}" title="${_('Copy the full commit id')}"></i>
217 * <i class="tooltip icon-plus clipboard-action" data-clipboard-text="${commit.raw_id}" title="${_('Copy the full commit id')}"></i>
218 * */
218 * */
219 var clipboard = new Clipboard('.clipboard-action');
219 var clipboard = new Clipboard('.clipboard-action');
220
220
221 clipboard.on('success', function(e) {
221 clipboard.on('success', function(e) {
222 var callback = function () {
222 var callback = function () {
223 $(e.trigger).animate({'opacity': 1.00}, 200)
223 $(e.trigger).animate({'opacity': 1.00}, 200)
224 };
224 };
225 $(e.trigger).animate({'opacity': 0.15}, 200, callback);
225 $(e.trigger).animate({'opacity': 0.15}, 200, callback);
226 e.clearSelection();
226 e.clearSelection();
227 });
227 });
228 };
228 };
229
229
230
230
231 // Formatting values in a Select2 dropdown of commit references
231 // Formatting values in a Select2 dropdown of commit references
232 var formatSelect2SelectionRefs = function(commit_ref){
232 var formatSelect2SelectionRefs = function(commit_ref){
233 var tmpl = '';
233 var tmpl = '';
234 if (!commit_ref.text || commit_ref.type === 'sha'){
234 if (!commit_ref.text || commit_ref.type === 'sha'){
235 return commit_ref.text;
235 return commit_ref.text;
236 }
236 }
237 if (commit_ref.type === 'branch'){
237 if (commit_ref.type === 'branch'){
238 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
238 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
239 } else if (commit_ref.type === 'tag'){
239 } else if (commit_ref.type === 'tag'){
240 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
240 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
241 } else if (commit_ref.type === 'book'){
241 } else if (commit_ref.type === 'book'){
242 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
242 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
243 }
243 }
244 return tmpl.concat(escapeHtml(commit_ref.text));
244 return tmpl.concat(escapeHtml(commit_ref.text));
245 };
245 };
246
246
247 // takes a given html element and scrolls it down offset pixels
247 // takes a given html element and scrolls it down offset pixels
248 function offsetScroll(element, offset) {
248 function offsetScroll(element, offset) {
249 setTimeout(function() {
249 setTimeout(function() {
250 var location = element.offset().top;
250 var location = element.offset().top;
251 // some browsers use body, some use html
251 // some browsers use body, some use html
252 $('html, body').animate({ scrollTop: (location - offset) });
252 $('html, body').animate({ scrollTop: (location - offset) });
253 }, 100);
253 }, 100);
254 }
254 }
255
255
256 // scroll an element `percent`% from the top of page in `time` ms
256 // scroll an element `percent`% from the top of page in `time` ms
257 function scrollToElement(element, percent, time) {
257 function scrollToElement(element, percent, time) {
258 percent = (percent === undefined ? 25 : percent);
258 percent = (percent === undefined ? 25 : percent);
259 time = (time === undefined ? 100 : time);
259 time = (time === undefined ? 100 : time);
260
260
261 var $element = $(element);
261 var $element = $(element);
262 if ($element.length == 0) {
262 if ($element.length == 0) {
263 throw('Cannot scroll to {0}'.format(element))
263 throw('Cannot scroll to {0}'.format(element))
264 }
264 }
265 var elOffset = $element.offset().top;
265 var elOffset = $element.offset().top;
266 var elHeight = $element.height();
266 var elHeight = $element.height();
267 var windowHeight = $(window).height();
267 var windowHeight = $(window).height();
268 var offset = elOffset;
268 var offset = elOffset;
269 if (elHeight < windowHeight) {
269 if (elHeight < windowHeight) {
270 offset = elOffset - ((windowHeight / (100 / percent)) - (elHeight / 2));
270 offset = elOffset - ((windowHeight / (100 / percent)) - (elHeight / 2));
271 }
271 }
272 setTimeout(function() {
272 setTimeout(function() {
273 $('html, body').animate({ scrollTop: offset});
273 $('html, body').animate({ scrollTop: offset});
274 }, time);
274 }, time);
275 }
275 }
276
276
277 /**
277 /**
278 * global hooks after DOM is loaded
278 * global hooks after DOM is loaded
279 */
279 */
280 $(document).ready(function() {
280 $(document).ready(function() {
281 firefoxAnchorFix();
281 firefoxAnchorFix();
282
282
283 $('.navigation a.menulink').on('click', function(e){
283 $('.navigation a.menulink').on('click', function(e){
284 var menuitem = $(this).parent('li');
284 var menuitem = $(this).parent('li');
285 if (menuitem.hasClass('open')) {
285 if (menuitem.hasClass('open')) {
286 menuitem.removeClass('open');
286 menuitem.removeClass('open');
287 } else {
287 } else {
288 menuitem.addClass('open');
288 menuitem.addClass('open');
289 $(document).on('click', function(event) {
289 $(document).on('click', function(event) {
290 if (!$(event.target).closest(menuitem).length) {
290 if (!$(event.target).closest(menuitem).length) {
291 menuitem.removeClass('open');
291 menuitem.removeClass('open');
292 }
292 }
293 });
293 });
294 }
294 }
295 });
295 });
296 $('.compare_view_files').on(
296 $('.compare_view_files').on(
297 'mouseenter mouseleave', 'tr.line .lineno a',function(event) {
297 'mouseenter mouseleave', 'tr.line .lineno a',function(event) {
298 if (event.type === "mouseenter") {
298 if (event.type === "mouseenter") {
299 $(this).parents('tr.line').addClass('hover');
299 $(this).parents('tr.line').addClass('hover');
300 } else {
300 } else {
301 $(this).parents('tr.line').removeClass('hover');
301 $(this).parents('tr.line').removeClass('hover');
302 }
302 }
303 });
303 });
304
304
305 $('.compare_view_files').on(
305 $('.compare_view_files').on(
306 'mouseenter mouseleave', 'tr.line .add-comment-line a',function(event){
306 'mouseenter mouseleave', 'tr.line .add-comment-line a',function(event){
307 if (event.type === "mouseenter") {
307 if (event.type === "mouseenter") {
308 $(this).parents('tr.line').addClass('commenting');
308 $(this).parents('tr.line').addClass('commenting');
309 } else {
309 } else {
310 $(this).parents('tr.line').removeClass('commenting');
310 $(this).parents('tr.line').removeClass('commenting');
311 }
311 }
312 });
312 });
313
313
314 $('body').on( /* TODO: replace the $('.compare_view_files').on('click') below
314 $('body').on( /* TODO: replace the $('.compare_view_files').on('click') below
315 when new diffs are integrated */
315 when new diffs are integrated */
316 'click', '.cb-lineno a', function(event) {
316 'click', '.cb-lineno a', function(event) {
317
317
318 function sortNumber(a,b) {
319 return a - b;
320 }
321
318 if ($(this).attr('data-line-no') !== ""){
322 if ($(this).attr('data-line-no') !== "") {
323
324 // on shift, we do a range selection, if we got previous line
325 var prevLine = $('.cb-line-selected a').attr('data-line-no');
326 if (event.shiftKey && prevLine !== undefined) {
327 var prevLine = parseInt(prevLine);
328 var nextLine = parseInt($(this).attr('data-line-no'));
329 var pos = [prevLine, nextLine].sort(sortNumber);
330 var anchor = '#L{0}-{1}'.format(pos[0], pos[1]);
331
332 } else {
333 var nextLine = parseInt($(this).attr('data-line-no'));
334 var pos = [nextLine, nextLine];
335 var anchor = '#L{0}'.format(pos[0]);
336
337 }
338 // highlight
339 var range = [];
340 for (var i = pos[0]; i <= pos[1]; i++) {
341 range.push(i);
342 }
343 // clear selection
319 $('.cb-line-selected').removeClass('cb-line-selected');
344 $('.cb-line-selected').removeClass('cb-line-selected');
320 var td = $(this).parent();
345
321 td.addClass('cb-line-selected'); // line number td
346 $.each(range, function (i, lineNo) {
322 td.prev().addClass('cb-line-selected'); // line data td
347 var line_td = $('td.cb-lineno#L' + lineNo);
323 td.next().addClass('cb-line-selected'); // line content td
348 if (line_td.length) {
349 line_td.addClass('cb-line-selected'); // line number td
350 line_td.prev().addClass('cb-line-selected'); // line data
351 line_td.next().addClass('cb-line-selected'); // line content
352 }
353 });
324
354
325 // Replace URL without jumping to it if browser supports.
355 // Replace URL without jumping to it if browser supports.
326 // Default otherwise
356 // Default otherwise
327 if (history.pushState) {
357 if (history.pushState) {
328 var new_location = location.href.rstrip('#');
358 var new_location = location.href.rstrip('#');
329 if (location.hash) {
359 if (location.hash) {
360 // location without hash
330 new_location = new_location.replace(location.hash, "");
361 new_location = new_location.replace(location.hash, "");
331 }
362 }
332
363
333 // Make new anchor url
364 // Make new anchor url
334 new_location = new_location + $(this).attr('href');
365 new_location = new_location + anchor;
335 history.pushState(true, document.title, new_location);
366 history.pushState(true, document.title, new_location);
336
367
337 return false;
368 return false;
338 }
369 }
339 }
370 }
340 });
371 });
341
372
342 $('.compare_view_files').on( /* TODO: replace this with .cb function above
373 $('.compare_view_files').on( /* TODO: replace this with .cb function above
343 when new diffs are integrated */
374 when new diffs are integrated */
344 'click', 'tr.line .lineno a',function(event) {
375 'click', 'tr.line .lineno a',function(event) {
345 if ($(this).text() != ""){
376 if ($(this).text() != ""){
346 $('tr.line').removeClass('selected');
377 $('tr.line').removeClass('selected');
347 $(this).parents("tr.line").addClass('selected');
378 $(this).parents("tr.line").addClass('selected');
348
379
349 // Replace URL without jumping to it if browser supports.
380 // Replace URL without jumping to it if browser supports.
350 // Default otherwise
381 // Default otherwise
351 if (history.pushState) {
382 if (history.pushState) {
352 var new_location = location.href;
383 var new_location = location.href;
353 if (location.hash){
384 if (location.hash){
354 new_location = new_location.replace(location.hash, "");
385 new_location = new_location.replace(location.hash, "");
355 }
386 }
356
387
357 // Make new anchor url
388 // Make new anchor url
358 var new_location = new_location+$(this).attr('href');
389 var new_location = new_location+$(this).attr('href');
359 history.pushState(true, document.title, new_location);
390 history.pushState(true, document.title, new_location);
360
391
361 return false;
392 return false;
362 }
393 }
363 }
394 }
364 });
395 });
365
396
366 $('.compare_view_files').on(
397 $('.compare_view_files').on(
367 'click', 'tr.line .add-comment-line a',function(event) {
398 'click', 'tr.line .add-comment-line a',function(event) {
368 var tr = $(event.currentTarget).parents('tr.line')[0];
399 var tr = $(event.currentTarget).parents('tr.line')[0];
369 injectInlineForm(tr);
400 injectInlineForm(tr);
370 return false;
401 return false;
371 });
402 });
372
403
373 $('.collapse_file').on('click', function(e) {
404 $('.collapse_file').on('click', function(e) {
374 e.stopPropagation();
405 e.stopPropagation();
375 if ($(e.target).is('a')) { return; }
406 if ($(e.target).is('a')) { return; }
376 var node = $(e.delegateTarget).first();
407 var node = $(e.delegateTarget).first();
377 var icon = $($(node.children().first()).children().first());
408 var icon = $($(node.children().first()).children().first());
378 var id = node.attr('fid');
409 var id = node.attr('fid');
379 var target = $('#'+id);
410 var target = $('#'+id);
380 var tr = $('#tr_'+id);
411 var tr = $('#tr_'+id);
381 var diff = $('#diff_'+id);
412 var diff = $('#diff_'+id);
382 if(node.hasClass('expand_file')){
413 if(node.hasClass('expand_file')){
383 node.removeClass('expand_file');
414 node.removeClass('expand_file');
384 icon.removeClass('expand_file_icon');
415 icon.removeClass('expand_file_icon');
385 node.addClass('collapse_file');
416 node.addClass('collapse_file');
386 icon.addClass('collapse_file_icon');
417 icon.addClass('collapse_file_icon');
387 diff.show();
418 diff.show();
388 tr.show();
419 tr.show();
389 target.show();
420 target.show();
390 } else {
421 } else {
391 node.removeClass('collapse_file');
422 node.removeClass('collapse_file');
392 icon.removeClass('collapse_file_icon');
423 icon.removeClass('collapse_file_icon');
393 node.addClass('expand_file');
424 node.addClass('expand_file');
394 icon.addClass('expand_file_icon');
425 icon.addClass('expand_file_icon');
395 diff.hide();
426 diff.hide();
396 tr.hide();
427 tr.hide();
397 target.hide();
428 target.hide();
398 }
429 }
399 });
430 });
400
431
401 $('#expand_all_files').click(function() {
432 $('#expand_all_files').click(function() {
402 $('.expand_file').each(function() {
433 $('.expand_file').each(function() {
403 var node = $(this);
434 var node = $(this);
404 var icon = $($(node.children().first()).children().first());
435 var icon = $($(node.children().first()).children().first());
405 var id = $(this).attr('fid');
436 var id = $(this).attr('fid');
406 var target = $('#'+id);
437 var target = $('#'+id);
407 var tr = $('#tr_'+id);
438 var tr = $('#tr_'+id);
408 var diff = $('#diff_'+id);
439 var diff = $('#diff_'+id);
409 node.removeClass('expand_file');
440 node.removeClass('expand_file');
410 icon.removeClass('expand_file_icon');
441 icon.removeClass('expand_file_icon');
411 node.addClass('collapse_file');
442 node.addClass('collapse_file');
412 icon.addClass('collapse_file_icon');
443 icon.addClass('collapse_file_icon');
413 diff.show();
444 diff.show();
414 tr.show();
445 tr.show();
415 target.show();
446 target.show();
416 });
447 });
417 });
448 });
418
449
419 $('#collapse_all_files').click(function() {
450 $('#collapse_all_files').click(function() {
420 $('.collapse_file').each(function() {
451 $('.collapse_file').each(function() {
421 var node = $(this);
452 var node = $(this);
422 var icon = $($(node.children().first()).children().first());
453 var icon = $($(node.children().first()).children().first());
423 var id = $(this).attr('fid');
454 var id = $(this).attr('fid');
424 var target = $('#'+id);
455 var target = $('#'+id);
425 var tr = $('#tr_'+id);
456 var tr = $('#tr_'+id);
426 var diff = $('#diff_'+id);
457 var diff = $('#diff_'+id);
427 node.removeClass('collapse_file');
458 node.removeClass('collapse_file');
428 icon.removeClass('collapse_file_icon');
459 icon.removeClass('collapse_file_icon');
429 node.addClass('expand_file');
460 node.addClass('expand_file');
430 icon.addClass('expand_file_icon');
461 icon.addClass('expand_file_icon');
431 diff.hide();
462 diff.hide();
432 tr.hide();
463 tr.hide();
433 target.hide();
464 target.hide();
434 });
465 });
435 });
466 });
436
467
437 // Mouse over behavior for comments and line selection
468 // Mouse over behavior for comments and line selection
438
469
439 // Select the line that comes from the url anchor
470 // Select the line that comes from the url anchor
440 // At the time of development, Chrome didn't seem to support jquery's :target
471 // At the time of development, Chrome didn't seem to support jquery's :target
441 // element, so I had to scroll manually
472 // element, so I had to scroll manually
442
473
443 if (location.hash) {
474 if (location.hash) {
444 var result = splitDelimitedHash(location.hash);
475 var result = splitDelimitedHash(location.hash);
445 var loc = result.loc;
476 var loc = result.loc;
446 if (loc.length > 1) {
477 if (loc.length > 1) {
447
478
448 var highlightable_line_tds = [];
479 var highlightable_line_tds = [];
449
480
450 // source code line format
481 // source code line format
451 var page_highlights = loc.substring(
482 var page_highlights = loc.substring(
452 loc.indexOf('#') + 1).split('L');
483 loc.indexOf('#') + 1).split('L');
453
484
454 if (page_highlights.length > 1) {
485 if (page_highlights.length > 1) {
455 var highlight_ranges = page_highlights[1].split(",");
486 var highlight_ranges = page_highlights[1].split(",");
456 var h_lines = [];
487 var h_lines = [];
457 for (var pos in highlight_ranges) {
488 for (var pos in highlight_ranges) {
458 var _range = highlight_ranges[pos].split('-');
489 var _range = highlight_ranges[pos].split('-');
459 if (_range.length === 2) {
490 if (_range.length === 2) {
460 var start = parseInt(_range[0]);
491 var start = parseInt(_range[0]);
461 var end = parseInt(_range[1]);
492 var end = parseInt(_range[1]);
462 if (start < end) {
493 if (start < end) {
463 for (var i = start; i <= end; i++) {
494 for (var i = start; i <= end; i++) {
464 h_lines.push(i);
495 h_lines.push(i);
465 }
496 }
466 }
497 }
467 }
498 }
468 else {
499 else {
469 h_lines.push(parseInt(highlight_ranges[pos]));
500 h_lines.push(parseInt(highlight_ranges[pos]));
470 }
501 }
471 }
502 }
472 for (pos in h_lines) {
503 for (pos in h_lines) {
473 var line_td = $('td.cb-lineno#L' + h_lines[pos]);
504 var line_td = $('td.cb-lineno#L' + h_lines[pos]);
474 if (line_td.length) {
505 if (line_td.length) {
475 highlightable_line_tds.push(line_td);
506 highlightable_line_tds.push(line_td);
476 }
507 }
477 }
508 }
478 }
509 }
479
510
480 // now check a direct id reference (diff page)
511 // now check a direct id reference (diff page)
481 if ($(loc).length && $(loc).hasClass('cb-lineno')) {
512 if ($(loc).length && $(loc).hasClass('cb-lineno')) {
482 highlightable_line_tds.push($(loc));
513 highlightable_line_tds.push($(loc));
483 }
514 }
484 $.each(highlightable_line_tds, function (i, $td) {
515 $.each(highlightable_line_tds, function (i, $td) {
485 $td.addClass('cb-line-selected'); // line number td
516 $td.addClass('cb-line-selected'); // line number td
486 $td.prev().addClass('cb-line-selected'); // line data
517 $td.prev().addClass('cb-line-selected'); // line data
487 $td.next().addClass('cb-line-selected'); // line content
518 $td.next().addClass('cb-line-selected'); // line content
488 });
519 });
489
520
490 if (highlightable_line_tds.length) {
521 if (highlightable_line_tds.length) {
491 var $first_line_td = highlightable_line_tds[0];
522 var $first_line_td = highlightable_line_tds[0];
492 scrollToElement($first_line_td);
523 scrollToElement($first_line_td);
493 $.Topic('/ui/plugins/code/anchor_focus').prepareOrPublish({
524 $.Topic('/ui/plugins/code/anchor_focus').prepareOrPublish({
494 td: $first_line_td,
525 td: $first_line_td,
495 remainder: result.remainder
526 remainder: result.remainder
496 });
527 });
497 }
528 }
498 }
529 }
499 }
530 }
500 collapsableContent();
531 collapsableContent();
501 });
532 });
502
533
503 var feedLifetimeOptions = function(query, initialData){
534 var feedLifetimeOptions = function(query, initialData){
504 var data = {results: []};
535 var data = {results: []};
505 var isQuery = typeof query.term !== 'undefined';
536 var isQuery = typeof query.term !== 'undefined';
506
537
507 var section = _gettext('Lifetime');
538 var section = _gettext('Lifetime');
508 var children = [];
539 var children = [];
509
540
510 //filter results
541 //filter results
511 $.each(initialData.results, function(idx, value) {
542 $.each(initialData.results, function(idx, value) {
512
543
513 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
544 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
514 children.push({
545 children.push({
515 'id': this.id,
546 'id': this.id,
516 'text': this.text
547 'text': this.text
517 })
548 })
518 }
549 }
519
550
520 });
551 });
521 data.results.push({
552 data.results.push({
522 'text': section,
553 'text': section,
523 'children': children
554 'children': children
524 });
555 });
525
556
526 if (isQuery) {
557 if (isQuery) {
527
558
528 var now = moment.utc();
559 var now = moment.utc();
529
560
530 var parseQuery = function(entry, now){
561 var parseQuery = function(entry, now){
531 var fmt = 'DD/MM/YYYY H:mm';
562 var fmt = 'DD/MM/YYYY H:mm';
532 var parsed = moment.utc(entry, fmt);
563 var parsed = moment.utc(entry, fmt);
533 var diffInMin = parsed.diff(now, 'minutes');
564 var diffInMin = parsed.diff(now, 'minutes');
534
565
535 if (diffInMin > 0){
566 if (diffInMin > 0){
536 return {
567 return {
537 id: diffInMin,
568 id: diffInMin,
538 text: parsed.format(fmt)
569 text: parsed.format(fmt)
539 }
570 }
540 } else {
571 } else {
541 return {
572 return {
542 id: undefined,
573 id: undefined,
543 text: parsed.format('DD/MM/YYYY') + ' ' + _gettext('date not in future')
574 text: parsed.format('DD/MM/YYYY') + ' ' + _gettext('date not in future')
544 }
575 }
545 }
576 }
546
577
547
578
548 };
579 };
549
580
550 data.results.push({
581 data.results.push({
551 'text': _gettext('Specified expiration date'),
582 'text': _gettext('Specified expiration date'),
552 'children': [{
583 'children': [{
553 'id': parseQuery(query.term, now).id,
584 'id': parseQuery(query.term, now).id,
554 'text': parseQuery(query.term, now).text
585 'text': parseQuery(query.term, now).text
555 }]
586 }]
556 });
587 });
557 }
588 }
558
589
559 query.callback(data);
590 query.callback(data);
560 };
591 };
General Comments 0
You need to be logged in to leave comments. Login now