rhodecode.js
546 lines
| 14.9 KiB
| application/javascript
|
JavascriptLexer
r1421 | /** | |||
RhodeCode JS Files | ||||
**/ | ||||
if (typeof console == "undefined" || typeof console.log == "undefined"){ | ||||
console = { log: function() {} } | ||||
} | ||||
r1699 | var str_repeat = function(i, m) { | |||
r1421 | for (var o = []; m > 0; o[--m] = i); | |||
return o.join(''); | ||||
r1699 | }; | |||
r1421 | ||||
/** | ||||
* INJECT .format function into String | ||||
* Usage: "My name is {0} {1}".format("Johny","Bravo") | ||||
* Return "My name is Johny Bravo" | ||||
* Inspired by https://gist.github.com/1049426 | ||||
*/ | ||||
String.prototype.format = function() { | ||||
function format() { | ||||
var str = this; | ||||
var len = arguments.length+1; | ||||
var safe = undefined; | ||||
var arg = undefined; | ||||
// For each {0} {1} {n...} replace with the argument in that position. If | ||||
// the argument is an object or an array it will be stringified to JSON. | ||||
for (var i=0; i < len; arg = arguments[i++]) { | ||||
safe = typeof arg === 'object' ? JSON.stringify(arg) : arg; | ||||
str = str.replace(RegExp('\\{'+(i-1)+'\\}', 'g'), safe); | ||||
} | ||||
return str; | ||||
} | ||||
// Save a reference of what may already exist under the property native. | ||||
// Allows for doing something like: if("".format.native) { /* use native */ } | ||||
format.native = String.prototype.format; | ||||
// Replace the prototype property | ||||
return format; | ||||
r1458 | }(); | |||
r1421 | ||||
r1465 | ||||
/** | ||||
* SmartColorGenerator | ||||
* | ||||
*usage:: | ||||
* var CG = new ColorGenerator(); | ||||
* var col = CG.getColor(key); //returns array of RGB | ||||
* 'rgb({0})'.format(col.join(',') | ||||
* | ||||
* @returns {ColorGenerator} | ||||
*/ | ||||
r1699 | var ColorGenerator = function(){ | |||
r1465 | this.GOLDEN_RATIO = 0.618033988749895; | |||
this.CURRENT_RATIO = 0.22717784590367374 // this can be random | ||||
this.HSV_1 = 0.75;//saturation | ||||
this.HSV_2 = 0.95; | ||||
this.color; | ||||
this.cacheColorMap = {}; | ||||
}; | ||||
ColorGenerator.prototype = { | ||||
getColor:function(key){ | ||||
if(this.cacheColorMap[key] !== undefined){ | ||||
return this.cacheColorMap[key]; | ||||
} | ||||
else{ | ||||
this.cacheColorMap[key] = this.generateColor(); | ||||
return this.cacheColorMap[key]; | ||||
} | ||||
}, | ||||
_hsvToRgb:function(h,s,v){ | ||||
if (s == 0.0) | ||||
return [v, v, v]; | ||||
i = parseInt(h * 6.0) | ||||
f = (h * 6.0) - i | ||||
p = v * (1.0 - s) | ||||
q = v * (1.0 - s * f) | ||||
t = v * (1.0 - s * (1.0 - f)) | ||||
i = i % 6 | ||||
if (i == 0) | ||||
return [v, t, p] | ||||
if (i == 1) | ||||
return [q, v, p] | ||||
if (i == 2) | ||||
return [p, v, t] | ||||
if (i == 3) | ||||
return [p, q, v] | ||||
if (i == 4) | ||||
return [t, p, v] | ||||
if (i == 5) | ||||
return [v, p, q] | ||||
}, | ||||
generateColor:function(){ | ||||
this.CURRENT_RATIO = this.CURRENT_RATIO+this.GOLDEN_RATIO; | ||||
this.CURRENT_RATIO = this.CURRENT_RATIO %= 1; | ||||
HSV_tuple = [this.CURRENT_RATIO, this.HSV_1, this.HSV_2] | ||||
RGB_tuple = this._hsvToRgb(HSV_tuple[0],HSV_tuple[1],HSV_tuple[2]); | ||||
function toRgb(v){ | ||||
return ""+parseInt(v*256) | ||||
} | ||||
return [toRgb(RGB_tuple[0]),toRgb(RGB_tuple[1]),toRgb(RGB_tuple[2])]; | ||||
} | ||||
} | ||||
r1421 | /** | |||
* GLOBAL YUI Shortcuts | ||||
*/ | ||||
var YUC = YAHOO.util.Connect; | ||||
var YUD = YAHOO.util.Dom; | ||||
var YUE = YAHOO.util.Event; | ||||
var YUQ = YAHOO.util.Selector.query; | ||||
// defines if push state is enabled for this browser ? | ||||
var push_state_enabled = Boolean( | ||||
window.history && window.history.pushState && window.history.replaceState | ||||
&& !( /* disable for versions of iOS before version 4.3 (8F190) */ | ||||
(/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) | ||||
/* disable for the mercury iOS browser, or at least older versions of the webkit engine */ | ||||
|| (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) | ||||
) | ||||
r1699 | ); | |||
r1421 | ||||
/** | ||||
* Partial Ajax Implementation | ||||
* | ||||
* @param url: defines url to make partial request | ||||
* @param container: defines id of container to input partial result | ||||
* @param s_call: success callback function that takes o as arg | ||||
* o.tId | ||||
* o.status | ||||
* o.statusText | ||||
* o.getResponseHeader[ ] | ||||
* o.getAllResponseHeaders | ||||
* o.responseText | ||||
* o.responseXML | ||||
* o.argument | ||||
* @param f_call: failure callback | ||||
* @param args arguments | ||||
*/ | ||||
function ypjax(url,container,s_call,f_call,args){ | ||||
var method='GET'; | ||||
if(args===undefined){ | ||||
args=null; | ||||
} | ||||
// Set special header for partial ajax == HTTP_X_PARTIAL_XHR | ||||
YUC.initHeader('X-PARTIAL-XHR',true); | ||||
// wrapper of passed callback | ||||
var s_wrapper = (function(o){ | ||||
return function(o){ | ||||
YUD.get(container).innerHTML=o.responseText; | ||||
YUD.setStyle(container,'opacity','1.0'); | ||||
//execute the given original callback | ||||
if (s_call !== undefined){ | ||||
s_call(o); | ||||
} | ||||
} | ||||
})() | ||||
YUD.setStyle(container,'opacity','0.3'); | ||||
YUC.asyncRequest(method,url,{ | ||||
success:s_wrapper, | ||||
failure:function(o){ | ||||
r1651 | console.log(o); | |||
YUD.get(container).innerHTML='ERROR'; | ||||
YUD.setStyle(container,'opacity','1.0'); | ||||
YUD.setStyle(container,'color','red'); | ||||
r1421 | } | |||
},args); | ||||
r1699 | }; | |||
r1421 | ||||
/** | ||||
* tooltip activate | ||||
*/ | ||||
r1458 | var tooltip_activate = function(){ | |||
r1421 | function toolTipsId(){ | |||
var ids = []; | ||||
var tts = YUQ('.tooltip'); | ||||
for (var i = 0; i < tts.length; i++) { | ||||
// if element doesn't not have and id | ||||
// autogenerate one for tooltip | ||||
if (!tts[i].id){ | ||||
tts[i].id='tt'+((i*100)+tts.length); | ||||
} | ||||
ids.push(tts[i].id); | ||||
} | ||||
return ids | ||||
}; | ||||
var myToolTips = new YAHOO.widget.Tooltip("tooltip", { | ||||
context: [[toolTipsId()],"tl","bl",null,[0,5]], | ||||
monitorresize:false, | ||||
xyoffset :[0,0], | ||||
autodismissdelay:300000, | ||||
hidedelay:5, | ||||
showdelay:20, | ||||
}); | ||||
r1699 | }; | |||
r1426 | ||||
/** | ||||
* show more | ||||
*/ | ||||
r1458 | var show_more_event = function(){ | |||
r1426 | YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){ | |||
var el = e.target; | ||||
YUD.setStyle(YUD.get(el.id.substring(1)),'display',''); | ||||
YUD.setStyle(el.parentNode,'display','none'); | ||||
}); | ||||
r1699 | }; | |||
r1426 | ||||
r1653 | ||||
/** | ||||
* Quick filter widget | ||||
* | ||||
* @param target: filter input target | ||||
* @param nodes: list of nodes in html we want to filter. | ||||
* @param display_element function that takes current node from nodes and | ||||
* does hide or show based on the node | ||||
* | ||||
*/ | ||||
var q_filter = function(target,nodes,display_element){ | ||||
var nodes = nodes; | ||||
var q_filter_field = YUD.get(target); | ||||
var F = YAHOO.namespace(target); | ||||
YUE.on(q_filter_field,'click',function(){ | ||||
q_filter_field.value = ''; | ||||
}); | ||||
YUE.on(q_filter_field,'keyup',function(e){ | ||||
clearTimeout(F.filterTimeout); | ||||
F.filterTimeout = setTimeout(F.updateFilter,600); | ||||
}); | ||||
F.filterTimeout = null; | ||||
var show_node = function(node){ | ||||
YUD.setStyle(node,'display','') | ||||
} | ||||
var hide_node = function(node){ | ||||
YUD.setStyle(node,'display','none'); | ||||
} | ||||
F.updateFilter = function() { | ||||
// Reset timeout | ||||
F.filterTimeout = null; | ||||
var obsolete = []; | ||||
var req = q_filter_field.value.toLowerCase(); | ||||
var l = nodes.length; | ||||
var i; | ||||
r1667 | var showing = 0; | |||
r1653 | for (i=0;i<l;i++ ){ | |||
var n = nodes[i]; | ||||
var target_element = display_element(n) | ||||
if(req && n.innerHTML.toLowerCase().indexOf(req) == -1){ | ||||
hide_node(target_element); | ||||
} | ||||
else{ | ||||
show_node(target_element); | ||||
r1667 | showing+=1; | |||
r1653 | } | |||
} | ||||
r1667 | // if repo_count is set update the number | |||
var cnt = YUD.get('repo_count'); | ||||
if(cnt){ | ||||
YUD.get('repo_count').innerHTML = showing; | ||||
} | ||||
r1653 | } | |||
r1699 | }; | |||
r1653 | ||||
r1674 | var ajaxPOST = function(url,postData,success) { | |||
var sUrl = url; | ||||
var callback = { | ||||
success: success, | ||||
failure: function (o) { | ||||
alert("error"); | ||||
}, | ||||
}; | ||||
var postData = postData; | ||||
var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData); | ||||
}; | ||||
r1653 | ||||
r1677 | ||||
/** comments **/ | ||||
var removeInlineForm = function(form) { | ||||
form.parentNode.removeChild(form); | ||||
r1699 | }; | |||
r1677 | ||||
r1682 | var tableTr = function(cls,body){ | |||
r1677 | var form = document.createElement('tr'); | |||
r1682 | YUD.addClass(form, cls); | |||
r1683 | form.innerHTML = '<td class="lineno-inline new-inline"></td>'+ | |||
'<td class="lineno-inline old-inline"></td>'+ | ||||
r1682 | '<td>{0}</td>'.format(body); | |||
return form; | ||||
r1699 | }; | |||
r1682 | ||||
var createInlineForm = function(parent_tr, f_path, line) { | ||||
r1677 | var tmpl = YUD.get('comment-inline-form-template').innerHTML; | |||
tmpl = tmpl.format(f_path, line); | ||||
r1682 | var form = tableTr('comment-form-inline',tmpl) | |||
r1677 | // create event for hide button | |||
form = new YAHOO.util.Element(form); | ||||
var form_hide_button = new YAHOO.util.Element(form.getElementsByClassName('hide-inline-form')[0]); | ||||
form_hide_button.on('click', function(e) { | ||||
var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode; | ||||
removeInlineForm(newtr); | ||||
YUD.removeClass(parent_tr, 'form-open'); | ||||
}); | ||||
return form | ||||
r1699 | }; | |||
r1677 | var getLineNo = function(tr) { | |||
var line; | ||||
var o = tr.children[0].id.split('_'); | ||||
var n = tr.children[1].id.split('_'); | ||||
r1679 | if (n.length >= 2) { | |||
line = n[n.length-1]; | ||||
} else if (o.length >= 2) { | ||||
r1685 | line = o[o.length-1]; | |||
r1677 | } | |||
return line | ||||
r1699 | }; | |||
var fileBrowserListeners = function(current_url, node_list_url, url_base){ | ||||
var current_url_branch = +"?branch=__BRANCH__"; | ||||
var url = url_base; | ||||
var node_url = node_list_url; | ||||
YUE.on('stay_at_branch','click',function(e){ | ||||
if(e.target.checked){ | ||||
var uri = current_url_branch; | ||||
uri = uri.replace('__BRANCH__',e.target.value); | ||||
window.location = uri; | ||||
} | ||||
else{ | ||||
window.location = current_url; | ||||
} | ||||
}) | ||||
var n_filter = YUD.get('node_filter'); | ||||
var F = YAHOO.namespace('node_filter'); | ||||
url = url.replace('__REPO__','${c.repo_name}'); | ||||
url = url.replace('__REVISION__','${c.changeset.raw_id}'); | ||||
url = url.replace('__FPATH__','${c.files_list.path}'); | ||||
node_url = node_url.replace('__REPO__','${c.repo_name}'); | ||||
node_url = node_url.replace('__REVISION__','${c.changeset.raw_id}'); | ||||
F.filterTimeout = null; | ||||
var nodes = null; | ||||
F.initFilter = function(){ | ||||
YUD.setStyle('node_filter_box_loading','display',''); | ||||
YUD.setStyle('search_activate_id','display','none'); | ||||
YUD.setStyle('add_node_id','display','none'); | ||||
YUC.initHeader('X-PARTIAL-XHR',true); | ||||
YUC.asyncRequest('GET',url,{ | ||||
success:function(o){ | ||||
nodes = JSON.parse(o.responseText); | ||||
YUD.setStyle('node_filter_box_loading','display','none'); | ||||
YUD.setStyle('node_filter_box','display',''); | ||||
}, | ||||
failure:function(o){ | ||||
console.log('failed to load'); | ||||
} | ||||
},null); | ||||
} | ||||
F.updateFilter = function(e) { | ||||
return function(){ | ||||
// Reset timeout | ||||
F.filterTimeout = null; | ||||
var query = e.target.value; | ||||
var match = []; | ||||
var matches = 0; | ||||
var matches_max = 20; | ||||
if (query != ""){ | ||||
for(var i=0;i<nodes.length;i++){ | ||||
var pos = nodes[i].toLowerCase().indexOf(query) | ||||
if(query && pos != -1){ | ||||
matches++ | ||||
//show only certain amount to not kill browser | ||||
if (matches > matches_max){ | ||||
break; | ||||
} | ||||
var n = nodes[i]; | ||||
var n_hl = n.substring(0,pos) | ||||
+"<b>{0}</b>".format(n.substring(pos,pos+query.length)) | ||||
+n.substring(pos+query.length) | ||||
match.push('<tr><td><a class="browser-file" href="{0}">{1}</a></td><td colspan="5"></td></tr>'.format(node_url.replace('__FPATH__',n),n_hl)); | ||||
} | ||||
if(match.length >= matches_max){ | ||||
match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format("${_('search truncated')}")); | ||||
} | ||||
} | ||||
} | ||||
if(query != ""){ | ||||
YUD.setStyle('tbody','display','none'); | ||||
YUD.setStyle('tbody_filtered','display',''); | ||||
if (match.length==0){ | ||||
match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format("${_('no matching files')}")); | ||||
} | ||||
YUD.get('tbody_filtered').innerHTML = match.join(""); | ||||
} | ||||
else{ | ||||
YUD.setStyle('tbody','display',''); | ||||
YUD.setStyle('tbody_filtered','display','none'); | ||||
} | ||||
} | ||||
}; | ||||
YUE.on(YUD.get('filter_activate'),'click',function(){ | ||||
F.initFilter(); | ||||
}) | ||||
YUE.on(n_filter,'click',function(){ | ||||
n_filter.value = ''; | ||||
}); | ||||
YUE.on(n_filter,'keyup',function(e){ | ||||
clearTimeout(F.filterTimeout); | ||||
F.filterTimeout = setTimeout(F.updateFilter(e),600); | ||||
}); | ||||
}; | ||||
var initCodeMirror = function(textAreadId,resetUrl){ | ||||
var myCodeMirror = CodeMirror.fromTextArea(YUD.get(textAreadId),{ | ||||
mode: "null", | ||||
lineNumbers:true | ||||
}); | ||||
YUE.on('reset','click',function(e){ | ||||
window.location=resetUrl | ||||
}); | ||||
YUE.on('file_enable','click',function(){ | ||||
YUD.setStyle('editor_container','display',''); | ||||
YUD.setStyle('upload_file_container','display','none'); | ||||
YUD.setStyle('filename_container','display',''); | ||||
}); | ||||
YUE.on('upload_file_enable','click',function(){ | ||||
YUD.setStyle('editor_container','display','none'); | ||||
YUD.setStyle('upload_file_container','display',''); | ||||
YUD.setStyle('filename_container','display','none'); | ||||
}); | ||||
}; | ||||
var getIdentNode = function(n){ | ||||
//iterate thru nodes untill matched interesting node ! | ||||
if (typeof n == 'undefined'){ | ||||
return -1 | ||||
} | ||||
if(typeof n.id != "undefined" && n.id.match('L[0-9]+')){ | ||||
return n | ||||
} | ||||
else{ | ||||
return getIdentNode(n.parentNode); | ||||
} | ||||
}; | ||||
var getSelectionLink = function(selection_link_label) { | ||||
return function(){ | ||||
//get selection from start/to nodes | ||||
if (typeof window.getSelection != "undefined") { | ||||
s = window.getSelection(); | ||||
from = getIdentNode(s.anchorNode); | ||||
till = getIdentNode(s.focusNode); | ||||
f_int = parseInt(from.id.replace('L','')); | ||||
t_int = parseInt(till.id.replace('L','')); | ||||
if (f_int > t_int){ | ||||
//highlight from bottom | ||||
offset = -35; | ||||
ranges = [t_int,f_int]; | ||||
} | ||||
else{ | ||||
//highligth from top | ||||
offset = 35; | ||||
ranges = [f_int,t_int]; | ||||
} | ||||
if (ranges[0] != ranges[1]){ | ||||
if(YUD.get('linktt') == null){ | ||||
hl_div = document.createElement('div'); | ||||
hl_div.id = 'linktt'; | ||||
} | ||||
anchor = '#L'+ranges[0]+'-'+ranges[1]; | ||||
hl_div.innerHTML = ''; | ||||
l = document.createElement('a'); | ||||
l.href = location.href.substring(0,location.href.indexOf('#'))+anchor; | ||||
l.innerHTML = selection_link_label; | ||||
hl_div.appendChild(l); | ||||
YUD.get('body').appendChild(hl_div); | ||||
xy = YUD.getXY(till.id); | ||||
YUD.addClass('linktt','yui-tt'); | ||||
YUD.setStyle('linktt','top',xy[1]+offset+'px'); | ||||
YUD.setStyle('linktt','left',xy[0]+'px'); | ||||
YUD.setStyle('linktt','visibility','visible'); | ||||
} | ||||
else{ | ||||
YUD.setStyle('linktt','visibility','hidden'); | ||||
} | ||||
} | ||||
} | ||||
}; | ||||