##// END OF EJS Templates
select2: always escape .text attributes to prevent XSS via...
ergo -
r2196:2338f289 stable
parent child Browse files
Show More
@@ -1,483 +1,483 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('compare_url', url_data);
61 window.location = pyroutes.url('compare_url', 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 // Formatting values in a Select2 dropdown of commit references
213 // Formatting values in a Select2 dropdown of commit references
214 var formatSelect2SelectionRefs = function(commit_ref){
214 var formatSelect2SelectionRefs = function(commit_ref){
215 var tmpl = '';
215 var tmpl = '';
216 if (!commit_ref.text || commit_ref.type === 'sha'){
216 if (!commit_ref.text || commit_ref.type === 'sha'){
217 return commit_ref.text;
217 return commit_ref.text;
218 }
218 }
219 if (commit_ref.type === 'branch'){
219 if (commit_ref.type === 'branch'){
220 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
220 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
221 } else if (commit_ref.type === 'tag'){
221 } else if (commit_ref.type === 'tag'){
222 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
222 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
223 } else if (commit_ref.type === 'book'){
223 } else if (commit_ref.type === 'book'){
224 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
224 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
225 }
225 }
226 return tmpl.concat(commit_ref.text);
226 return tmpl.concat(escapeHtml(commit_ref.text));
227 };
227 };
228
228
229 // takes a given html element and scrolls it down offset pixels
229 // takes a given html element and scrolls it down offset pixels
230 function offsetScroll(element, offset) {
230 function offsetScroll(element, offset) {
231 setTimeout(function() {
231 setTimeout(function() {
232 var location = element.offset().top;
232 var location = element.offset().top;
233 // some browsers use body, some use html
233 // some browsers use body, some use html
234 $('html, body').animate({ scrollTop: (location - offset) });
234 $('html, body').animate({ scrollTop: (location - offset) });
235 }, 100);
235 }, 100);
236 }
236 }
237
237
238 // scroll an element `percent`% from the top of page in `time` ms
238 // scroll an element `percent`% from the top of page in `time` ms
239 function scrollToElement(element, percent, time) {
239 function scrollToElement(element, percent, time) {
240 percent = (percent === undefined ? 25 : percent);
240 percent = (percent === undefined ? 25 : percent);
241 time = (time === undefined ? 100 : time);
241 time = (time === undefined ? 100 : time);
242
242
243 var $element = $(element);
243 var $element = $(element);
244 if ($element.length == 0) {
244 if ($element.length == 0) {
245 throw('Cannot scroll to {0}'.format(element))
245 throw('Cannot scroll to {0}'.format(element))
246 }
246 }
247 var elOffset = $element.offset().top;
247 var elOffset = $element.offset().top;
248 var elHeight = $element.height();
248 var elHeight = $element.height();
249 var windowHeight = $(window).height();
249 var windowHeight = $(window).height();
250 var offset = elOffset;
250 var offset = elOffset;
251 if (elHeight < windowHeight) {
251 if (elHeight < windowHeight) {
252 offset = elOffset - ((windowHeight / (100 / percent)) - (elHeight / 2));
252 offset = elOffset - ((windowHeight / (100 / percent)) - (elHeight / 2));
253 }
253 }
254 setTimeout(function() {
254 setTimeout(function() {
255 $('html, body').animate({ scrollTop: offset});
255 $('html, body').animate({ scrollTop: offset});
256 }, time);
256 }, time);
257 }
257 }
258
258
259 /**
259 /**
260 * global hooks after DOM is loaded
260 * global hooks after DOM is loaded
261 */
261 */
262 $(document).ready(function() {
262 $(document).ready(function() {
263 firefoxAnchorFix();
263 firefoxAnchorFix();
264
264
265 $('.navigation a.menulink').on('click', function(e){
265 $('.navigation a.menulink').on('click', function(e){
266 var menuitem = $(this).parent('li');
266 var menuitem = $(this).parent('li');
267 if (menuitem.hasClass('open')) {
267 if (menuitem.hasClass('open')) {
268 menuitem.removeClass('open');
268 menuitem.removeClass('open');
269 } else {
269 } else {
270 menuitem.addClass('open');
270 menuitem.addClass('open');
271 $(document).on('click', function(event) {
271 $(document).on('click', function(event) {
272 if (!$(event.target).closest(menuitem).length) {
272 if (!$(event.target).closest(menuitem).length) {
273 menuitem.removeClass('open');
273 menuitem.removeClass('open');
274 }
274 }
275 });
275 });
276 }
276 }
277 });
277 });
278 $('.compare_view_files').on(
278 $('.compare_view_files').on(
279 'mouseenter mouseleave', 'tr.line .lineno a',function(event) {
279 'mouseenter mouseleave', 'tr.line .lineno a',function(event) {
280 if (event.type === "mouseenter") {
280 if (event.type === "mouseenter") {
281 $(this).parents('tr.line').addClass('hover');
281 $(this).parents('tr.line').addClass('hover');
282 } else {
282 } else {
283 $(this).parents('tr.line').removeClass('hover');
283 $(this).parents('tr.line').removeClass('hover');
284 }
284 }
285 });
285 });
286
286
287 $('.compare_view_files').on(
287 $('.compare_view_files').on(
288 'mouseenter mouseleave', 'tr.line .add-comment-line a',function(event){
288 'mouseenter mouseleave', 'tr.line .add-comment-line a',function(event){
289 if (event.type === "mouseenter") {
289 if (event.type === "mouseenter") {
290 $(this).parents('tr.line').addClass('commenting');
290 $(this).parents('tr.line').addClass('commenting');
291 } else {
291 } else {
292 $(this).parents('tr.line').removeClass('commenting');
292 $(this).parents('tr.line').removeClass('commenting');
293 }
293 }
294 });
294 });
295
295
296 $('body').on( /* TODO: replace the $('.compare_view_files').on('click') below
296 $('body').on( /* TODO: replace the $('.compare_view_files').on('click') below
297 when new diffs are integrated */
297 when new diffs are integrated */
298 'click', '.cb-lineno a', function(event) {
298 'click', '.cb-lineno a', function(event) {
299
299
300 if ($(this).attr('data-line-no') !== ""){
300 if ($(this).attr('data-line-no') !== ""){
301 $('.cb-line-selected').removeClass('cb-line-selected');
301 $('.cb-line-selected').removeClass('cb-line-selected');
302 var td = $(this).parent();
302 var td = $(this).parent();
303 td.addClass('cb-line-selected'); // line number td
303 td.addClass('cb-line-selected'); // line number td
304 td.prev().addClass('cb-line-selected'); // line data td
304 td.prev().addClass('cb-line-selected'); // line data td
305 td.next().addClass('cb-line-selected'); // line content td
305 td.next().addClass('cb-line-selected'); // line content td
306
306
307 // Replace URL without jumping to it if browser supports.
307 // Replace URL without jumping to it if browser supports.
308 // Default otherwise
308 // Default otherwise
309 if (history.pushState) {
309 if (history.pushState) {
310 var new_location = location.href.rstrip('#');
310 var new_location = location.href.rstrip('#');
311 if (location.hash) {
311 if (location.hash) {
312 new_location = new_location.replace(location.hash, "");
312 new_location = new_location.replace(location.hash, "");
313 }
313 }
314
314
315 // Make new anchor url
315 // Make new anchor url
316 new_location = new_location + $(this).attr('href');
316 new_location = new_location + $(this).attr('href');
317 history.pushState(true, document.title, new_location);
317 history.pushState(true, document.title, new_location);
318
318
319 return false;
319 return false;
320 }
320 }
321 }
321 }
322 });
322 });
323
323
324 $('.compare_view_files').on( /* TODO: replace this with .cb function above
324 $('.compare_view_files').on( /* TODO: replace this with .cb function above
325 when new diffs are integrated */
325 when new diffs are integrated */
326 'click', 'tr.line .lineno a',function(event) {
326 'click', 'tr.line .lineno a',function(event) {
327 if ($(this).text() != ""){
327 if ($(this).text() != ""){
328 $('tr.line').removeClass('selected');
328 $('tr.line').removeClass('selected');
329 $(this).parents("tr.line").addClass('selected');
329 $(this).parents("tr.line").addClass('selected');
330
330
331 // Replace URL without jumping to it if browser supports.
331 // Replace URL without jumping to it if browser supports.
332 // Default otherwise
332 // Default otherwise
333 if (history.pushState) {
333 if (history.pushState) {
334 var new_location = location.href;
334 var new_location = location.href;
335 if (location.hash){
335 if (location.hash){
336 new_location = new_location.replace(location.hash, "");
336 new_location = new_location.replace(location.hash, "");
337 }
337 }
338
338
339 // Make new anchor url
339 // Make new anchor url
340 var new_location = new_location+$(this).attr('href');
340 var new_location = new_location+$(this).attr('href');
341 history.pushState(true, document.title, new_location);
341 history.pushState(true, document.title, new_location);
342
342
343 return false;
343 return false;
344 }
344 }
345 }
345 }
346 });
346 });
347
347
348 $('.compare_view_files').on(
348 $('.compare_view_files').on(
349 'click', 'tr.line .add-comment-line a',function(event) {
349 'click', 'tr.line .add-comment-line a',function(event) {
350 var tr = $(event.currentTarget).parents('tr.line')[0];
350 var tr = $(event.currentTarget).parents('tr.line')[0];
351 injectInlineForm(tr);
351 injectInlineForm(tr);
352 return false;
352 return false;
353 });
353 });
354
354
355 $('.collapse_file').on('click', function(e) {
355 $('.collapse_file').on('click', function(e) {
356 e.stopPropagation();
356 e.stopPropagation();
357 if ($(e.target).is('a')) { return; }
357 if ($(e.target).is('a')) { return; }
358 var node = $(e.delegateTarget).first();
358 var node = $(e.delegateTarget).first();
359 var icon = $($(node.children().first()).children().first());
359 var icon = $($(node.children().first()).children().first());
360 var id = node.attr('fid');
360 var id = node.attr('fid');
361 var target = $('#'+id);
361 var target = $('#'+id);
362 var tr = $('#tr_'+id);
362 var tr = $('#tr_'+id);
363 var diff = $('#diff_'+id);
363 var diff = $('#diff_'+id);
364 if(node.hasClass('expand_file')){
364 if(node.hasClass('expand_file')){
365 node.removeClass('expand_file');
365 node.removeClass('expand_file');
366 icon.removeClass('expand_file_icon');
366 icon.removeClass('expand_file_icon');
367 node.addClass('collapse_file');
367 node.addClass('collapse_file');
368 icon.addClass('collapse_file_icon');
368 icon.addClass('collapse_file_icon');
369 diff.show();
369 diff.show();
370 tr.show();
370 tr.show();
371 target.show();
371 target.show();
372 } else {
372 } else {
373 node.removeClass('collapse_file');
373 node.removeClass('collapse_file');
374 icon.removeClass('collapse_file_icon');
374 icon.removeClass('collapse_file_icon');
375 node.addClass('expand_file');
375 node.addClass('expand_file');
376 icon.addClass('expand_file_icon');
376 icon.addClass('expand_file_icon');
377 diff.hide();
377 diff.hide();
378 tr.hide();
378 tr.hide();
379 target.hide();
379 target.hide();
380 }
380 }
381 });
381 });
382
382
383 $('#expand_all_files').click(function() {
383 $('#expand_all_files').click(function() {
384 $('.expand_file').each(function() {
384 $('.expand_file').each(function() {
385 var node = $(this);
385 var node = $(this);
386 var icon = $($(node.children().first()).children().first());
386 var icon = $($(node.children().first()).children().first());
387 var id = $(this).attr('fid');
387 var id = $(this).attr('fid');
388 var target = $('#'+id);
388 var target = $('#'+id);
389 var tr = $('#tr_'+id);
389 var tr = $('#tr_'+id);
390 var diff = $('#diff_'+id);
390 var diff = $('#diff_'+id);
391 node.removeClass('expand_file');
391 node.removeClass('expand_file');
392 icon.removeClass('expand_file_icon');
392 icon.removeClass('expand_file_icon');
393 node.addClass('collapse_file');
393 node.addClass('collapse_file');
394 icon.addClass('collapse_file_icon');
394 icon.addClass('collapse_file_icon');
395 diff.show();
395 diff.show();
396 tr.show();
396 tr.show();
397 target.show();
397 target.show();
398 });
398 });
399 });
399 });
400
400
401 $('#collapse_all_files').click(function() {
401 $('#collapse_all_files').click(function() {
402 $('.collapse_file').each(function() {
402 $('.collapse_file').each(function() {
403 var node = $(this);
403 var node = $(this);
404 var icon = $($(node.children().first()).children().first());
404 var icon = $($(node.children().first()).children().first());
405 var id = $(this).attr('fid');
405 var id = $(this).attr('fid');
406 var target = $('#'+id);
406 var target = $('#'+id);
407 var tr = $('#tr_'+id);
407 var tr = $('#tr_'+id);
408 var diff = $('#diff_'+id);
408 var diff = $('#diff_'+id);
409 node.removeClass('collapse_file');
409 node.removeClass('collapse_file');
410 icon.removeClass('collapse_file_icon');
410 icon.removeClass('collapse_file_icon');
411 node.addClass('expand_file');
411 node.addClass('expand_file');
412 icon.addClass('expand_file_icon');
412 icon.addClass('expand_file_icon');
413 diff.hide();
413 diff.hide();
414 tr.hide();
414 tr.hide();
415 target.hide();
415 target.hide();
416 });
416 });
417 });
417 });
418
418
419 // Mouse over behavior for comments and line selection
419 // Mouse over behavior for comments and line selection
420
420
421 // Select the line that comes from the url anchor
421 // Select the line that comes from the url anchor
422 // At the time of development, Chrome didn't seem to support jquery's :target
422 // At the time of development, Chrome didn't seem to support jquery's :target
423 // element, so I had to scroll manually
423 // element, so I had to scroll manually
424
424
425 if (location.hash) {
425 if (location.hash) {
426 var result = splitDelimitedHash(location.hash);
426 var result = splitDelimitedHash(location.hash);
427 var loc = result.loc;
427 var loc = result.loc;
428 if (loc.length > 1) {
428 if (loc.length > 1) {
429
429
430 var highlightable_line_tds = [];
430 var highlightable_line_tds = [];
431
431
432 // source code line format
432 // source code line format
433 var page_highlights = loc.substring(
433 var page_highlights = loc.substring(
434 loc.indexOf('#') + 1).split('L');
434 loc.indexOf('#') + 1).split('L');
435
435
436 if (page_highlights.length > 1) {
436 if (page_highlights.length > 1) {
437 var highlight_ranges = page_highlights[1].split(",");
437 var highlight_ranges = page_highlights[1].split(",");
438 var h_lines = [];
438 var h_lines = [];
439 for (var pos in highlight_ranges) {
439 for (var pos in highlight_ranges) {
440 var _range = highlight_ranges[pos].split('-');
440 var _range = highlight_ranges[pos].split('-');
441 if (_range.length === 2) {
441 if (_range.length === 2) {
442 var start = parseInt(_range[0]);
442 var start = parseInt(_range[0]);
443 var end = parseInt(_range[1]);
443 var end = parseInt(_range[1]);
444 if (start < end) {
444 if (start < end) {
445 for (var i = start; i <= end; i++) {
445 for (var i = start; i <= end; i++) {
446 h_lines.push(i);
446 h_lines.push(i);
447 }
447 }
448 }
448 }
449 }
449 }
450 else {
450 else {
451 h_lines.push(parseInt(highlight_ranges[pos]));
451 h_lines.push(parseInt(highlight_ranges[pos]));
452 }
452 }
453 }
453 }
454 for (pos in h_lines) {
454 for (pos in h_lines) {
455 var line_td = $('td.cb-lineno#L' + h_lines[pos]);
455 var line_td = $('td.cb-lineno#L' + h_lines[pos]);
456 if (line_td.length) {
456 if (line_td.length) {
457 highlightable_line_tds.push(line_td);
457 highlightable_line_tds.push(line_td);
458 }
458 }
459 }
459 }
460 }
460 }
461
461
462 // now check a direct id reference (diff page)
462 // now check a direct id reference (diff page)
463 if ($(loc).length && $(loc).hasClass('cb-lineno')) {
463 if ($(loc).length && $(loc).hasClass('cb-lineno')) {
464 highlightable_line_tds.push($(loc));
464 highlightable_line_tds.push($(loc));
465 }
465 }
466 $.each(highlightable_line_tds, function (i, $td) {
466 $.each(highlightable_line_tds, function (i, $td) {
467 $td.addClass('cb-line-selected'); // line number td
467 $td.addClass('cb-line-selected'); // line number td
468 $td.prev().addClass('cb-line-selected'); // line data
468 $td.prev().addClass('cb-line-selected'); // line data
469 $td.next().addClass('cb-line-selected'); // line content
469 $td.next().addClass('cb-line-selected'); // line content
470 });
470 });
471
471
472 if (highlightable_line_tds.length) {
472 if (highlightable_line_tds.length) {
473 var $first_line_td = highlightable_line_tds[0];
473 var $first_line_td = highlightable_line_tds[0];
474 scrollToElement($first_line_td);
474 scrollToElement($first_line_td);
475 $.Topic('/ui/plugins/code/anchor_focus').prepareOrPublish({
475 $.Topic('/ui/plugins/code/anchor_focus').prepareOrPublish({
476 td: $first_line_td,
476 td: $first_line_td,
477 remainder: result.remainder
477 remainder: result.remainder
478 });
478 });
479 }
479 }
480 }
480 }
481 }
481 }
482 collapsableContent();
482 collapsableContent();
483 });
483 });
@@ -1,84 +1,82 b''
1 /* COMMON */
1 /* COMMON */
2 var select2RefFilterResults = function(queryTerm, data) {
2 var select2RefFilterResults = function(queryTerm, data) {
3 var filteredData = {results: []};
3 var filteredData = {results: []};
4 //filter results
4 //filter results
5 $.each(data.results, function() {
5 $.each(data.results, function() {
6 var section = this.text;
6 var section = this.text;
7 var children = [];
7 var children = [];
8 $.each(this.children, function() {
8 $.each(this.children, function() {
9 if (queryTerm.length === 0 || this.text.toUpperCase().indexOf(queryTerm.toUpperCase()) >= 0) {
9 if (queryTerm.length === 0 || this.text.toUpperCase().indexOf(queryTerm.toUpperCase()) >= 0) {
10 children.push(this);
10 children.push(this);
11 }
11 }
12 });
12 });
13
13
14 if (children.length > 0) {
14 if (children.length > 0) {
15 filteredData.results.push({
15 filteredData.results.push({
16 'text': section,
16 'text': section,
17 'children': children
17 'children': children
18 });
18 });
19 }
19 }
20 });
20 });
21
21
22 return filteredData
22 return filteredData
23 };
23 };
24
24
25
25
26 var select2RefBaseSwitcher = function(targetElement, loadUrl, initialData){
26 var select2RefBaseSwitcher = function(targetElement, loadUrl, initialData){
27 var formatResult = function(result, container, query) {
27 var formatResult = function(result, container, query) {
28 return formatSelect2SelectionRefs(result);
28 return formatSelect2SelectionRefs(result);
29 };
29 };
30
30
31 var formatSelection = function(data, container) {
31 var formatSelection = function(data, container) {
32 return formatSelect2SelectionRefs(data);
32 return formatSelect2SelectionRefs(data);
33 };
33 };
34
34
35 $(targetElement).select2({
35 $(targetElement).select2({
36 cachedDataSource: {},
36 cachedDataSource: {},
37 dropdownAutoWidth: true,
37 dropdownAutoWidth: true,
38 formatResult: formatResult,
39 width: "resolve",
38 width: "resolve",
40 containerCssClass: "drop-menu",
39 containerCssClass: "drop-menu",
41 dropdownCssClass: "drop-menu-dropdown",
40 dropdownCssClass: "drop-menu-dropdown",
42 query: function(query) {
41 query: function(query) {
43 var self = this;
42 var self = this;
44 var cacheKey = '__ALLREFS__';
43 var cacheKey = '__ALLREFS__';
45 var cachedData = self.cachedDataSource[cacheKey];
44 var cachedData = self.cachedDataSource[cacheKey];
46 if (cachedData) {
45 if (cachedData) {
47 var data = select2RefFilterResults(query.term, cachedData);
46 var data = select2RefFilterResults(query.term, cachedData);
48 query.callback({results: data.results});
47 query.callback({results: data.results});
49 } else {
48 } else {
50 $.ajax({
49 $.ajax({
51 url: loadUrl,
50 url: loadUrl,
52 data: {},
51 data: {},
53 dataType: 'json',
52 dataType: 'json',
54 type: 'GET',
53 type: 'GET',
55 success: function(data) {
54 success: function(data) {
56 self.cachedDataSource[cacheKey] = data;
55 self.cachedDataSource[cacheKey] = data;
57 query.callback({results: data.results});
56 query.callback({results: data.results});
58 }
57 }
59 });
58 });
60 }
59 }
61 },
60 },
62
63 initSelection: function(element, callback) {
61 initSelection: function(element, callback) {
64 callback(initialData);
62 callback(initialData);
65 },
63 },
66
64 formatResult: formatResult,
67 formatSelection: formatSelection
65 formatSelection: formatSelection
68 });
66 });
69
67
70 };
68 };
71
69
72 /* WIDGETS */
70 /* WIDGETS */
73 var select2RefSwitcher = function(targetElement, initialData) {
71 var select2RefSwitcher = function(targetElement, initialData) {
74 var loadUrl = pyroutes.url('repo_refs_data',
72 var loadUrl = pyroutes.url('repo_refs_data',
75 {'repo_name': templateContext.repo_name});
73 {'repo_name': templateContext.repo_name});
76 select2RefBaseSwitcher(targetElement, loadUrl, initialData);
74 select2RefBaseSwitcher(targetElement, loadUrl, initialData);
77 };
75 };
78
76
79 var select2FileHistorySwitcher = function(targetElement, initialData, state) {
77 var select2FileHistorySwitcher = function(targetElement, initialData, state) {
80 var loadUrl = pyroutes.url('files_history_home',
78 var loadUrl = pyroutes.url('files_history_home',
81 {'repo_name': templateContext.repo_name, 'revision': state.rev,
79 {'repo_name': templateContext.repo_name, 'revision': state.rev,
82 'f_path': state.f_path});
80 'f_path': state.f_path});
83 select2RefBaseSwitcher(targetElement, loadUrl, initialData);
81 select2RefBaseSwitcher(targetElement, loadUrl, initialData);
84 };
82 };
General Comments 0
You need to be logged in to leave comments. Login now