rhodecode.js
422 lines
| 13.4 KiB
| application/javascript
|
JavascriptLexer
r1 | // # Copyright (C) 2010-2016 RhodeCode GmbH | |||
// # | ||||
// # This program is free software: you can redistribute it and/or modify | ||||
// # it under the terms of the GNU Affero General Public License, version 3 | ||||
// # (only), as published by the Free Software Foundation. | ||||
// # | ||||
// # This program is distributed in the hope that it will be useful, | ||||
// # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
// # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
// # GNU General Public License for more details. | ||||
// # | ||||
// # You should have received a copy of the GNU Affero General Public License | ||||
// # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
// # | ||||
// # This program is dual-licensed. If you wish to learn more about the | ||||
// # RhodeCode Enterprise Edition, including its added features, Support services, | ||||
// # and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
/** | ||||
RhodeCode JS Files | ||||
**/ | ||||
if (typeof console == "undefined" || typeof console.log == "undefined"){ | ||||
console = { log: function() {} } | ||||
} | ||||
// alias for backward compat | ||||
var _tm = function(s) { | ||||
if (_TM.hasOwnProperty(s)) { | ||||
return _TM[s]; | ||||
} | ||||
return s | ||||
}; | ||||
// TODO: move the following function to submodules | ||||
/** | ||||
* show more | ||||
*/ | ||||
var show_more_event = function(){ | ||||
$('table .show_more').click(function(e) { | ||||
var cid = e.target.id.substring(1); | ||||
var button = $(this); | ||||
if (button.hasClass('open')) { | ||||
$('#'+cid).hide(); | ||||
button.removeClass('open'); | ||||
} else { | ||||
$('#'+cid).show(); | ||||
button.addClass('open one'); | ||||
} | ||||
}); | ||||
}; | ||||
var compare_radio_buttons = function(repo_name, compare_ref_type){ | ||||
$('#compare_action').on('click', function(e){ | ||||
e.preventDefault(); | ||||
var source = $('input[name=compare_source]:checked').val(); | ||||
var target = $('input[name=compare_target]:checked').val(); | ||||
if(source && target){ | ||||
var url_data = { | ||||
repo_name: repo_name, | ||||
source_ref: source, | ||||
source_ref_type: compare_ref_type, | ||||
target_ref: target, | ||||
target_ref_type: compare_ref_type, | ||||
merge: 1 | ||||
}; | ||||
window.location = pyroutes.url('compare_url', url_data); | ||||
} | ||||
}); | ||||
$('.compare-radio-button').on('click', function(e){ | ||||
var source = $('input[name=compare_source]:checked').val(); | ||||
var target = $('input[name=compare_target]:checked').val(); | ||||
if(source && target){ | ||||
$('#compare_action').removeAttr("disabled"); | ||||
$('#compare_action').removeClass("disabled"); | ||||
} | ||||
}) | ||||
}; | ||||
var showRepoSize = function(target, repo_name, commit_id, callback) { | ||||
var container = $('#' + target); | ||||
var url = pyroutes.url('repo_stats', | ||||
{"repo_name": repo_name, "commit_id": commit_id}); | ||||
if (!container.hasClass('loaded')) { | ||||
$.ajax({url: url}) | ||||
.complete(function (data) { | ||||
var responseJSON = data.responseJSON; | ||||
container.addClass('loaded'); | ||||
container.html(responseJSON.size); | ||||
callback(responseJSON.code_stats) | ||||
}) | ||||
.fail(function (data) { | ||||
console.log('failed to load repo stats'); | ||||
}); | ||||
} | ||||
}; | ||||
var showRepoStats = function(target, data){ | ||||
var container = $('#' + target); | ||||
if (container.hasClass('loaded')) { | ||||
return | ||||
} | ||||
var total = 0; | ||||
var no_data = true; | ||||
var tbl = document.createElement('table'); | ||||
tbl.setAttribute('class', 'trending_language_tbl'); | ||||
$.each(data, function(key, val){ | ||||
total += val.count; | ||||
}); | ||||
var sortedStats = []; | ||||
for (var obj in data){ | ||||
sortedStats.push([obj, data[obj]]) | ||||
} | ||||
var sortedData = sortedStats.sort(function (a, b) { | ||||
return b[1].count - a[1].count | ||||
}); | ||||
var cnt = 0; | ||||
$.each(sortedData, function(idx, val){ | ||||
cnt += 1; | ||||
no_data = false; | ||||
var hide = cnt > 2; | ||||
var tr = document.createElement('tr'); | ||||
if (hide) { | ||||
tr.setAttribute('style', 'display:none'); | ||||
tr.setAttribute('class', 'stats_hidden'); | ||||
} | ||||
var key = val[0]; | ||||
var obj = {"desc": val[1].desc, "count": val[1].count}; | ||||
var percentage = Math.round((obj.count / total * 100), 2); | ||||
var td1 = document.createElement('td'); | ||||
td1.width = 300; | ||||
var trending_language_label = document.createElement('div'); | ||||
trending_language_label.innerHTML = obj.desc + " (.{0})".format(key); | ||||
td1.appendChild(trending_language_label); | ||||
var td2 = document.createElement('td'); | ||||
var trending_language = document.createElement('div'); | ||||
var nr_files = obj.count +" "+ (obj.count === 1 ? _tm('file'): _tm('files')); | ||||
trending_language.title = key + " " + nr_files; | ||||
trending_language.innerHTML = "<span>" + percentage + "% " + nr_files | ||||
+ "</span><b>" + percentage + "% " + nr_files + "</b>"; | ||||
trending_language.setAttribute("class", 'trending_language'); | ||||
$('b', trending_language)[0].style.width = percentage + "%"; | ||||
td2.appendChild(trending_language); | ||||
tr.appendChild(td1); | ||||
tr.appendChild(td2); | ||||
tbl.appendChild(tr); | ||||
if (cnt == 3) { | ||||
var show_more = document.createElement('tr'); | ||||
var td = document.createElement('td'); | ||||
lnk = document.createElement('a'); | ||||
lnk.href = '#'; | ||||
lnk.innerHTML = _tm('Show more'); | ||||
lnk.id = 'code_stats_show_more'; | ||||
td.appendChild(lnk); | ||||
show_more.appendChild(td); | ||||
show_more.appendChild(document.createElement('td')); | ||||
tbl.appendChild(show_more); | ||||
} | ||||
}); | ||||
$(container).html(tbl); | ||||
$(container).addClass('loaded'); | ||||
$('#code_stats_show_more').on('click', function (e) { | ||||
e.preventDefault(); | ||||
$('.stats_hidden').each(function (idx) { | ||||
$(this).css("display", ""); | ||||
}); | ||||
$('#code_stats_show_more').hide(); | ||||
}); | ||||
}; | ||||
// Toggle Collapsable Content | ||||
function collapsableContent() { | ||||
$('.collapsable-content').not('.no-hide').hide(); | ||||
$('.btn-collapse').unbind(); //in case we've been here before | ||||
$('.btn-collapse').click(function() { | ||||
var button = $(this); | ||||
var togglename = $(this).data("toggle"); | ||||
$('.collapsable-content[data-toggle='+togglename+']').toggle(); | ||||
if ($(this).html()=="Show Less") | ||||
$(this).html("Show More"); | ||||
else | ||||
$(this).html("Show Less"); | ||||
}); | ||||
}; | ||||
var timeagoActivate = function() { | ||||
$("time.timeago").timeago(); | ||||
}; | ||||
// Formatting values in a Select2 dropdown of commit references | ||||
var formatSelect2SelectionRefs = function(commit_ref){ | ||||
var tmpl = ''; | ||||
if (!commit_ref.text || commit_ref.type === 'sha'){ | ||||
return commit_ref.text; | ||||
} | ||||
if (commit_ref.type === 'branch'){ | ||||
tmpl = tmpl.concat('<i class="icon-branch"></i> '); | ||||
} else if (commit_ref.type === 'tag'){ | ||||
tmpl = tmpl.concat('<i class="icon-tag"></i> '); | ||||
} else if (commit_ref.type === 'book'){ | ||||
tmpl = tmpl.concat('<i class="icon-bookmark"></i> '); | ||||
} | ||||
return tmpl.concat(commit_ref.text); | ||||
}; | ||||
// takes a given html element and scrolls it down offset pixels | ||||
function offsetScroll(element, offset){ | ||||
setTimeout(function(){ | ||||
console.log(element); | ||||
var location = element.offset().top; | ||||
// some browsers use body, some use html | ||||
$('html, body').animate({ scrollTop: (location - offset) }); | ||||
}, 100); | ||||
} | ||||
/** | ||||
* global hooks after DOM is loaded | ||||
*/ | ||||
$(document).ready(function() { | ||||
firefoxAnchorFix(); | ||||
$('.navigation a.menulink').on('click', function(e){ | ||||
var menuitem = $(this).parent('li'); | ||||
if (menuitem.hasClass('open')) { | ||||
menuitem.removeClass('open'); | ||||
} else { | ||||
menuitem.addClass('open'); | ||||
$(document).on('click', function(event) { | ||||
if (!$(event.target).closest(menuitem).length) { | ||||
menuitem.removeClass('open'); | ||||
} | ||||
}); | ||||
} | ||||
}); | ||||
// Add tooltips | ||||
$('tr.line .lineno a').attr("title","Click to select line").addClass('tooltip'); | ||||
$('tr.line .add-comment-line a').attr("title","Click to comment").addClass('tooltip'); | ||||
// Set colors and styles | ||||
$('tr.line .lineno a').hover( | ||||
function(){ | ||||
$(this).parents('tr.line').addClass('hover'); | ||||
}, function(){ | ||||
$(this).parents('tr.line').removeClass('hover'); | ||||
} | ||||
); | ||||
$('tr.line .lineno a').click( | ||||
function(){ | ||||
if ($(this).text() != ""){ | ||||
$('tr.line').removeClass('selected'); | ||||
$(this).parents("tr.line").addClass('selected'); | ||||
// Replace URL without jumping to it if browser supports. | ||||
// Default otherwise | ||||
if (history.pushState) { | ||||
var new_location = location.href | ||||
if (location.hash){ | ||||
new_location = new_location.replace(location.hash, ""); | ||||
} | ||||
// Make new anchor url | ||||
var new_location = new_location+$(this).attr('href'); | ||||
history.pushState(true, document.title, new_location); | ||||
return false; | ||||
} | ||||
} | ||||
} | ||||
); | ||||
$('tr.line .add-comment-line a').hover( | ||||
function(){ | ||||
$(this).parents('tr.line').addClass('commenting'); | ||||
}, function(){ | ||||
$(this).parents('tr.line').removeClass('commenting'); | ||||
} | ||||
); | ||||
$('tr.line .add-comment-line a').on('click', function(e){ | ||||
var tr = $(e.currentTarget).parents('tr.line')[0]; | ||||
injectInlineForm(tr); | ||||
return false; | ||||
}); | ||||
$('.collapse_file').on('click', function(e) { | ||||
e.stopPropagation(); | ||||
if ($(e.target).is('a')) { return; } | ||||
var node = $(e.delegateTarget).first(); | ||||
var icon = $($(node.children().first()).children().first()); | ||||
var id = node.attr('fid'); | ||||
var target = $('#'+id); | ||||
var tr = $('#tr_'+id); | ||||
var diff = $('#diff_'+id); | ||||
if(node.hasClass('expand_file')){ | ||||
node.removeClass('expand_file'); | ||||
icon.removeClass('expand_file_icon'); | ||||
node.addClass('collapse_file'); | ||||
icon.addClass('collapse_file_icon'); | ||||
diff.show(); | ||||
tr.show(); | ||||
target.show(); | ||||
} else { | ||||
node.removeClass('collapse_file'); | ||||
icon.removeClass('collapse_file_icon'); | ||||
node.addClass('expand_file'); | ||||
icon.addClass('expand_file_icon'); | ||||
diff.hide(); | ||||
tr.hide(); | ||||
target.hide(); | ||||
} | ||||
}); | ||||
$('#expand_all_files').click(function() { | ||||
$('.expand_file').each(function() { | ||||
var node = $(this); | ||||
var icon = $($(node.children().first()).children().first()); | ||||
var id = $(this).attr('fid'); | ||||
var target = $('#'+id); | ||||
var tr = $('#tr_'+id); | ||||
var diff = $('#diff_'+id); | ||||
node.removeClass('expand_file'); | ||||
icon.removeClass('expand_file_icon'); | ||||
node.addClass('collapse_file'); | ||||
icon.addClass('collapse_file_icon'); | ||||
diff.show(); | ||||
tr.show(); | ||||
target.show(); | ||||
}); | ||||
}); | ||||
$('#collapse_all_files').click(function() { | ||||
$('.collapse_file').each(function() { | ||||
var node = $(this); | ||||
var icon = $($(node.children().first()).children().first()); | ||||
var id = $(this).attr('fid'); | ||||
var target = $('#'+id); | ||||
var tr = $('#tr_'+id); | ||||
var diff = $('#diff_'+id); | ||||
node.removeClass('collapse_file'); | ||||
icon.removeClass('collapse_file_icon'); | ||||
node.addClass('expand_file'); | ||||
icon.addClass('expand_file_icon'); | ||||
diff.hide(); | ||||
tr.hide(); | ||||
target.hide(); | ||||
}); | ||||
}); | ||||
// Mouse over behavior for comments and line selection | ||||
// Select the line that comes from the url anchor | ||||
// At the time of development, Chrome didn't seem to support jquery's :target | ||||
// element, so I had to scroll manually | ||||
if (location.hash) { | ||||
var splitIx = location.hash.indexOf('/?/'); | ||||
if (splitIx !== -1){ | ||||
var loc = location.hash.slice(0, splitIx); | ||||
var remainder = location.hash.slice(splitIx + 2); | ||||
} | ||||
else{ | ||||
var loc = location.hash; | ||||
var remainder = null; | ||||
} | ||||
if (loc.length > 1){ | ||||
var lineno = $(loc+'.lineno'); | ||||
if (lineno.length > 0){ | ||||
var tr = lineno.parents('tr.line'); | ||||
tr.addClass('selected'); | ||||
// once we scrolled into our line, trigger chat app | ||||
if (remainder){ | ||||
tr.find('.add-comment-line a').trigger( "click" ); | ||||
setTimeout(function(){ | ||||
var nextNode = $(tr).next(); | ||||
if(nextNode.hasClass('inline-comments')){ | ||||
nextNode.next().find('.switch-to-chat').trigger( "click" ); | ||||
} | ||||
else{ | ||||
nextNode.find('.switch-to-chat').trigger( "click" ); | ||||
} | ||||
// trigger scroll into, later so all elements are already loaded | ||||
tr[0].scrollIntoView(); | ||||
}, 250); | ||||
} | ||||
else{ | ||||
tr[0].scrollIntoView(); | ||||
} | ||||
} | ||||
} | ||||
}; | ||||
collapsableContent(); | ||||
}); | ||||