##// END OF EJS Templates
show links to files on compare data at other and org refs
show links to files on compare data at other and org refs

File last commit:

r3247:ed2fa8b1 beta
r3357:674a8fad beta
Show More
rhodecode.js
1972 lines | 57.7 KiB | application/javascript | JavascriptLexer
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
r1421 /**
RhodeCode JS Files
**/
if (typeof console == "undefined" || typeof console.log == "undefined"){
console = { log: function() {} }
}
cleaned up JS files in files templates....
r1699 var str_repeat = function(i, m) {
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
r1421 for (var o = []; m > 0; o[--m] = i);
return o.join('');
cleaned up JS files in files templates....
r1699 };
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
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;
added author to main page tooltip
r1458 }();
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
r1421
Autocomplete fixes...
r2369 String.prototype.strip = function(char) {
if(char === undefined){
char = '\\s';
}
return this.replace(new RegExp('^'+char+'+|'+char+'+$','g'), '');
}
String.prototype.lstrip = function(char) {
if(char === undefined){
char = '\\s';
}
return this.replace(new RegExp('^'+char+'+'),'');
}
String.prototype.rstrip = function(char) {
if(char === undefined){
char = '\\s';
}
return this.replace(new RegExp(''+char+'+$'),'');
}
Added smart color generator to rhodecode.js
r1465
Added autocomplete widget for pull request reviewers, in exchange of 90s style...
r2612
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(needle) {
for(var i = 0; i < this.length; i++) {
if(this[i] === needle) {
return i;
}
}
return -1;
};
}
ie8 fixes for inline comments :/
r2698 // IE(CRAP) doesn't support previousElementSibling
var prevElementSibling = function( el ) {
if( el.previousElementSibling ) {
return el.previousElementSibling;
} else {
while( el = el.previousSibling ) {
if( el.nodeType === 1 ) return el;
}
}
}
fixed few issues with autoselection of revisions on pull requests
r2849 var setSelectValue = function(select, val){
var selection = YUD.get(select);
// select element
for(var i=0;i<selection.options.length;i++){
if (selection.options[i].innerHTML == val) {
selection.selectedIndex = i;
break;
}
}
}
ie8 fixes for inline comments :/
r2698
Added smart color generator to rhodecode.js
r1465 /**
* SmartColorGenerator
*
*usage::
* var CG = new ColorGenerator();
* var col = CG.getColor(key); //returns array of RGB
* 'rgb({0})'.format(col.join(',')
*
* @returns {ColorGenerator}
*/
cleaned up JS files in files templates....
r1699 var ColorGenerator = function(){
Added smart color generator to rhodecode.js
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])];
}
}
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
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)
)
cleaned up JS files in files templates....
r1699 );
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
r1421
Notification fixes...
r1717 var _run_callbacks = function(callbacks){
if (callbacks !== undefined){
var _l = callbacks.length;
for (var i=0;i<_l;i++){
var func = callbacks[i];
if(typeof(func)=='function'){
try{
func();
}catch (err){};
}
}
}
}
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
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){
Display error on ypjax fail
r1651 console.log(o);
fix leftover error coloring after ypjax failure
r2690 YUD.get(container).innerHTML='<span class="error_red">ERROR: {0}</span>'.format(o.status);
Display error on ypjax fail
r1651 YUD.setStyle(container,'opacity','1.0');
Add cache to ypjax calls to overcome chrome caching issues of requests
r2694 },
cache:false
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
r1421 },args);
cleaned up JS files in files templates....
r1699 };
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
r1421
new tooltip implementation...
r2971 var ajaxGET = function(url,success) {
// Set special header for ajax == HTTP_X_PARTIAL_XHR
YUC.initHeader('X-PARTIAL-XHR',true);
var sUrl = url;
var callback = {
success: success,
failure: function (o) {
alert("error");
},
};
var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
return request;
};
#415: Adding comment to changeset causes reload...
r2187 var ajaxPOST = function(url,postData,success) {
fixed main comments, prevent from sending inline comments if text is empty
r2189 // Set special header for ajax == HTTP_X_PARTIAL_XHR
YUC.initHeader('X-PARTIAL-XHR',true);
#415: Adding comment to changeset causes reload...
r2187 var toQueryString = function(o) {
if(typeof o !== 'object') {
return false;
}
var _p, _qs = [];
for(_p in o) {
_qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
}
return _qs.join('&');
};
var sUrl = url;
var callback = {
success: success,
failure: function (o) {
alert("error");
},
};
var postData = toQueryString(postData);
var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
return request;
};
Javascripts rewrite: updated yui to latest 2.9, simplified ajax loading for multiple pages. Removed YUI dev package
r1421 /**
* tooltip activate
*/
added author to main page tooltip
r1458 var tooltip_activate = function(){
new tooltip implementation...
r2971 yt = YAHOO.yuitip.main;
YUE.onDOMReady(yt.init);
cleaned up JS files in files templates....
r1699 };
Fixed show more links....
r1426
/**
* show more
*/
added author to main page tooltip
r1458 var show_more_event = function(){
Fixed show more links....
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');
});
cleaned up JS files in files templates....
r1699 };
Fixed show more links....
r1426
new tooltip implementation...
r2971 /**
* show changeset tooltip
*/
var show_changeset_tooltip = function(){
YUE.on(YUD.getElementsByClassName('lazy-cs'), 'mouseover', function(e){
var target = e.currentTarget;
var rid = YUD.getAttribute(target,'raw_id');
var repo_name = YUD.getAttribute(target,'repo_name');
var ttid = 'tt-'+rid;
var success = function(o){
var json = JSON.parse(o.responseText);
YUD.addClass(target,'tooltip')
YUD.setAttribute(target, 'title',json['message']);
YAHOO.yuitip.main.show_yuitip(e, target);
}
if(rid && !YUD.hasClass(target, 'tooltip')){
YUD.setAttribute(target,'id',ttid);
- add loading message on lazy loaded toolips for journals...
r2979 YUD.setAttribute(target, 'title',_TM['loading...']);
YAHOO.yuitip.main.set_listeners(target);
YAHOO.yuitip.main.show_yuitip(e, target);
fixed issue #719 Journal revision ID tooltip AJAX query path is incorrect when running in a subdir
r3160 ajaxGET(LAZY_CS_URL.replace('__NAME__',repo_name).replace('__REV__', rid), success)
new tooltip implementation...
r2971 }
});
};
JS cleanup
r3066 var onSuccessFollow = function(target){
var f = YUD.get(target.id);
var f_cnt = YUD.get('current_followers_count');
if(YUD.hasClass(f, 'follow')){
f.setAttribute('class','following');
f.setAttribute('title',_TM['Stop following this repository']);
if(f_cnt){
var cnt = Number(f_cnt.innerHTML)+1;
f_cnt.innerHTML = cnt;
}
}
else{
f.setAttribute('class','follow');
f.setAttribute('title',_TM['Start following this repository']);
if(f_cnt){
var cnt = Number(f_cnt.innerHTML)-1;
f_cnt.innerHTML = cnt;
}
}
}
var toggleFollowingUser = function(target,fallows_user_id,token,user_id){
args = 'follows_user_id='+fallows_user_id;
args+= '&amp;auth_token='+token;
if(user_id != undefined){
args+="&amp;user_id="+user_id;
}
YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
success:function(o){
onSuccessFollow(target);
}
},args);
return false;
}
var toggleFollowingRepo = function(target,fallows_repo_id,token,user_id){
args = 'follows_repo_id='+fallows_repo_id;
args+= '&amp;auth_token='+token;
if(user_id != undefined){
args+="&amp;user_id="+user_id;
}
YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
success:function(o){
onSuccessFollow(target);
}
},args);
return false;
}
implemented #83 show repo size on summary page
r3246 var showRepoSize = function(target, repo_name, token){
var args= 'auth_token='+token;
disallow triggering repo size action more than once after loading
r3247 if(!YUD.hasClass(target, 'loaded')){
YUD.get(target).innerHTML = _TM['loading...'];
var url = REPO_SIZE_URL.replace('__NAME__', repo_name);
YUC.asyncRequest('POST',url,{
success:function(o){
YUD.get(target).innerHTML = JSON.parse(o.responseText);
YUD.addClass(target, 'loaded');
}
},args);
}
implemented #83 show repo size on summary page
r3246 return false;
}
new tooltip implementation...
r2971
/**
* TOOLTIP IMPL.
*/
YAHOO.namespace('yuitip');
YAHOO.yuitip.main = {
$: YAHOO.util.Dom.get,
bgColor: '#000',
speed: 0.3,
opacity: 0.9,
offset: [15,15],
useAnim: false,
- add loading message on lazy loaded toolips for journals...
r2979 maxWidth: 600,
disable tooltip links
r2974 add_links: false,
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 yuitips: [],
set_listeners: function(tt){
YUE.on(tt, 'mouseover', yt.show_yuitip, tt);
YUE.on(tt, 'mousemove', yt.move_yuitip, tt);
YUE.on(tt, 'mouseout', yt.close_yuitip, tt);
},
new tooltip implementation...
r2971
init: function(){
yt.tipBox = yt.$('tip-box');
if(!yt.tipBox){
yt.tipBox = document.createElement('div');
document.body.appendChild(yt.tipBox);
yt.tipBox.id = 'tip-box';
}
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUD.setStyle(yt.tipBox, 'display', 'none');
YUD.setStyle(yt.tipBox, 'position', 'absolute');
new tooltip implementation...
r2971 if(yt.maxWidth !== null){
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUD.setStyle(yt.tipBox, 'max-width', yt.maxWidth+'px');
new tooltip implementation...
r2971 }
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 var yuitips = YUD.getElementsByClassName('tooltip');
new tooltip implementation...
r2971
if(yt.add_links === true){
var links = document.getElementsByTagName('a');
var linkLen = links.length;
for(i=0;i<linkLen;i++){
yuitips.push(links[i]);
}
}
var yuiLen = yuitips.length;
for(i=0;i<yuiLen;i++){
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 yt.set_listeners(yuitips[i]);
new tooltip implementation...
r2971 }
},
show_yuitip: function(e, el){
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUE.stopEvent(e);
new tooltip implementation...
r2971 if(el.tagName.toLowerCase() === 'img'){
yt.tipText = el.alt ? el.alt : '';
} else {
yt.tipText = el.title ? el.title : '';
}
if(yt.tipText !== ''){
// save org title
fixes #687 Lazy loaded tooltip bug with simultaneous ajax requests
r3119 YUD.setAttribute(el, 'tt_title', yt.tipText);
new tooltip implementation...
r2971 // reset title to not show org tooltips
YUD.setAttribute(el, 'title', '');
yt.tipBox.innerHTML = yt.tipText;
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUD.setStyle(yt.tipBox, 'display', 'block');
new tooltip implementation...
r2971 if(yt.useAnim === true){
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUD.setStyle(yt.tipBox, 'opacity', '0');
new tooltip implementation...
r2971 var newAnim = new YAHOO.util.Anim(yt.tipBox,
{
opacity: { to: yt.opacity }
}, yt.speed, YAHOO.util.Easing.easeOut
);
newAnim.animate();
}
}
},
move_yuitip: function(e, el){
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUE.stopEvent(e);
var movePos = YUE.getXY(e);
YUD.setStyle(yt.tipBox, 'top', (movePos[1] + yt.offset[1]) + 'px');
YUD.setStyle(yt.tipBox, 'left', (movePos[0] + yt.offset[0]) + 'px');
new tooltip implementation...
r2971 },
close_yuitip: function(e, el){
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUE.stopEvent(e);
new tooltip implementation...
r2971
if(yt.useAnim === true){
var newAnim = new YAHOO.util.Anim(yt.tipBox,
{
opacity: { to: 0 }
}, yt.speed, YAHOO.util.Easing.easeOut
);
newAnim.animate();
} else {
Optimized new tooltip, and fixed events on lazy loaded ones
r2976 YUD.setStyle(yt.tipBox, 'display', 'none');
new tooltip implementation...
r2971 }
fixes #687 Lazy loaded tooltip bug with simultaneous ajax requests
r3119 YUD.setAttribute(el,'title', YUD.getAttribute(el, 'tt_title'));
new tooltip implementation...
r2971 }
}
one generic qfilter function.
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;
fixed repo counter on main page
r1667 var showing = 0;
one generic qfilter function.
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);
fixed repo counter on main page
r1667 showing+=1;
one generic qfilter function.
r1653 }
}
fixed repo counter on main page
r1667 // if repo_count is set update the number
var cnt = YUD.get('repo_count');
if(cnt){
YUD.get('repo_count').innerHTML = showing;
}
one generic qfilter function.
r1653 }
cleaned up JS files in files templates....
r1699 };
one generic qfilter function.
r1653
Don't use .innerHTML for tr field, I'm looking at you IE
r2787 var tableTr = function(cls, body){
Fixing inline comment for IE.
r2789 var _el = document.createElement('div');
#415: Adding comment to changeset causes reload...
r2187 var cont = new YAHOO.util.Element(body);
var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
Don't use .innerHTML for tr field, I'm looking at you IE
r2787 var id = 'comment-tr-{0}'.format(comment_id);
Fixing inline comment for IE.
r2789 var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
Don't use .innerHTML for tr field, I'm looking at you IE
r2787 '<td class="lineno-inline new-inline"></td>'+
'<td class="lineno-inline old-inline"></td>'+
'<td>{2}</td>'+
Fixing inline comment for IE.
r2789 '</tr></tbody></table>').format(id, cls, body);
Don't use .innerHTML for tr field, I'm looking at you IE
r2787 _el.innerHTML = _html;
Fixing inline comment for IE.
r2789 return _el.children[0].children[0].children[0];
#71 code review...
r1674 };
one generic qfilter function.
r1653
#71 code-review...
r1677 /** comments **/
var removeInlineForm = function(form) {
form.parentNode.removeChild(form);
cleaned up JS files in files templates....
r1699 };
#71 code-review...
r1677
#71 code review...
r1682 var createInlineForm = function(parent_tr, f_path, line) {
#71 code-review...
r1677 var tmpl = YUD.get('comment-inline-form-template').innerHTML;
tmpl = tmpl.format(f_path, line);
#71 code review...
r1682 var form = tableTr('comment-form-inline',tmpl)
Don't use .innerHTML for tr field, I'm looking at you IE
r2787
#71 code-review...
r1677 // create event for hide button
form = new YAHOO.util.Element(form);
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 var form_hide_button = new YAHOO.util.Element(YUD.getElementsByClassName('hide-inline-form',null,form)[0]);
#71 code-review...
r1677 form_hide_button.on('click', function(e) {
var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
#415: Adding comment to changeset causes reload...
r2187 if(YUD.hasClass(newtr.nextElementSibling,'inline-comments-button')){
YUD.setStyle(newtr.nextElementSibling,'display','');
}
#71 code-review...
r1677 removeInlineForm(newtr);
YUD.removeClass(parent_tr, 'form-open');
Add highlight class for future multiline comments
r2868 YUD.removeClass(parent_tr, 'hl-comment');
#415: Adding comment to changeset causes reload...
r2187
#71 code-review...
r1677 });
#415: Adding comment to changeset causes reload...
r2187
#71 code-review...
r1677 return form
cleaned up JS files in files templates....
r1699 };
#415: Adding comment to changeset causes reload...
r2187
/**
* Inject inline comment for on given TR this tr should be always an .line
* tr containing the line. Code will detect comment, and always put the comment
* block at the very bottom
*/
added reply comment button on top of inline comments...
r1705 var injectInlineForm = function(tr){
#415: Adding comment to changeset causes reload...
r2187 if(!YUD.hasClass(tr, 'line')){
return
}
var submit_url = AJAX_COMMENT_URL;
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 var _td = YUD.getElementsByClassName('code',null,tr)[0];
Added option to close pull requests, in future that will be close & merge
r2608 if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(_td,'no-comment')){
added reply comment button on top of inline comments...
r1705 return
}
YUD.addClass(tr,'form-open');
Add highlight class for future multiline comments
r2868 YUD.addClass(tr,'hl-comment');
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 var node = YUD.getElementsByClassName('full_f_path',null,tr.parentNode.parentNode.parentNode)[0];
added reply comment button on top of inline comments...
r1705 var f_path = YUD.getAttribute(node,'path');
var lineno = getLineNo(tr);
#415: Adding comment to changeset causes reload...
r2187 var form = createInlineForm(tr, f_path, lineno, submit_url);
var parent = tr;
while (1){
var n = parent.nextElementSibling;
// next element are comments !
if(YUD.hasClass(n,'inline-comments')){
parent = n;
}
else{
break;
}
}
YUD.insertAfter(form,parent);
var f = YUD.get(form);
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 var overlay = YUD.getElementsByClassName('overlay',null,f)[0];
var _form = YUD.getElementsByClassName('inline-form',null,f)[0];
#415: Adding comment to changeset causes reload...
r2187
Fixing inline comment for IE.
r2789 YUE.on(YUD.get(_form), 'submit',function(e){
#415: Adding comment to changeset causes reload...
r2187 YUE.preventDefault(e);
//ajax submit
var text = YUD.get('text_'+lineno).value;
var postData = {
'text':text,
'f_path':f_path,
'line':lineno
};
if(lineno === undefined){
alert('missing line !');
return
}
if(f_path === undefined){
alert('missing file path !');
return
}
fixed main comments, prevent from sending inline comments if text is empty
r2189 if(text == ""){
return
}
#415: Adding comment to changeset causes reload...
r2187 var success = function(o){
YUD.removeClass(tr, 'form-open');
removeInlineForm(f);
var json_data = JSON.parse(o.responseText);
renderInlineComment(json_data);
};
if (YUD.hasClass(overlay,'overlay')){
var w = _form.offsetWidth;
var h = _form.offsetHeight;
YUD.setStyle(overlay,'width',w+'px');
YUD.setStyle(overlay,'height',h+'px');
}
YUD.addClass(overlay, 'submitting');
ajaxPOST(submit_url, postData, success);
});
fixed race condition in autocomplete widget on inlines comments
r2437
setTimeout(function(){
// callbacks
tooltip_activate();
MentionsAutoComplete('text_'+lineno, 'mentions_container_'+lineno,
_USERS_AC_DATA, _GROUPS_AC_DATA);
ie8 fixes for inline comments :/
r2698 var _e = YUD.get('text_'+lineno);
if(_e){
_e.focus();
}
fixed race condition in autocomplete widget on inlines comments
r2437 },10)
added reply comment button on top of inline comments...
r1705 };
#415: Adding comment to changeset causes reload...
r2187 var deleteComment = function(comment_id){
var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__',comment_id);
var postData = {'_method':'delete'};
var success = function(o){
var n = YUD.get('comment-tr-'+comment_id);
ie8 fixes for inline comments :/
r2698 var root = prevElementSibling(prevElementSibling(n));
#415: Adding comment to changeset causes reload...
r2187 n.parentNode.removeChild(n);
// scann nodes, and attach add button to last one
fixed main comments, prevent from sending inline comments if text is empty
r2189 placeAddButton(root);
#415: Adding comment to changeset causes reload...
r2187 }
ajaxPOST(url,postData,success);
}
Added editing of pull-request reviewers.
r2614 var updateReviewers = function(reviewers_ids){
remove reviewers button removes them without need of hitting save button.
r3106 if (reviewers_ids === undefined){
var reviewers_ids = [];
var ids = YUQ('#review_members input');
for(var i=0; i<ids.length;i++){
var id = ids[i].value
reviewers_ids.push(id);
}
}
Added editing of pull-request reviewers.
r2614 var url = AJAX_UPDATE_PULLREQUEST;
var postData = {'_method':'put',
'reviewers_ids': reviewers_ids};
var success = function(o){
window.location.reload();
}
ajaxPOST(url,postData,success);
}
#415: Adding comment to changeset causes reload...
r2187
var createInlineAddButton = function(tr){
var label = TRANSLATION_MAP['add another comment'];
var html_el = document.createElement('div');
YUD.addClass(html_el, 'add-comment');
html_el.innerHTML = '<span class="ui-btn">{0}</span>'.format(label);
var add = new YAHOO.util.Element(html_el);
added reply comment button on top of inline comments...
r1705 add.on('click', function(e) {
injectInlineForm(tr);
});
return add;
};
cleaned up JS files in files templates....
r1699
#71 code-review...
r1677 var getLineNo = function(tr) {
var line;
var o = tr.children[0].id.split('_');
var n = tr.children[1].id.split('_');
fixed inline comment file parsing
r1679 if (n.length >= 2) {
line = n[n.length-1];
} else if (o.length >= 2) {
fixed typo in linenumber calculation on inline comments
r1685 line = o[o.length-1];
#71 code-review...
r1677 }
return line
cleaned up JS files in files templates....
r1699 };
#415: Adding comment to changeset causes reload...
r2187 var placeAddButton = function(target_tr){
if(!target_tr){
return
}
var last_node = target_tr;
//scann
while (1){
var n = last_node.nextElementSibling;
// next element are comments !
if(YUD.hasClass(n,'inline-comments')){
last_node = n;
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 //also remove the comment button from previous
var comment_add_buttons = YUD.getElementsByClassName('add-comment',null,last_node);
#415: Adding comment to changeset causes reload...
r2187 for(var i=0;i<comment_add_buttons.length;i++){
var b = comment_add_buttons[i];
b.parentNode.removeChild(b);
}
}
else{
break;
}
}
var add = createInlineAddButton(target_tr);
// get the comment div
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 var comment_block = YUD.getElementsByClassName('comment',null,last_node)[0];
#415: Adding comment to changeset causes reload...
r2187 // attach add button
YUD.insertAfter(add,comment_block);
}
/**
* Places the inline comment into the changeset block in proper line position
*/
var placeInline = function(target_container,lineno,html){
var lineid = "{0}_{1}".format(target_container,lineno);
var target_line = YUD.get(lineid);
var comment = new YAHOO.util.Element(tableTr('inline-comments',html))
// check if there are comments already !
var parent = target_line.parentNode;
var root_parent = parent;
while (1){
var n = parent.nextElementSibling;
// next element are comments !
if(YUD.hasClass(n,'inline-comments')){
parent = n;
}
else{
break;
}
}
// put in the comment at the bottom
YUD.insertAfter(comment,parent);
// scann nodes, and attach add button to last one
placeAddButton(root_parent);
return target_line;
}
/**
* make a single inline comment and place it inside
*/
var renderInlineComment = function(json_data){
try{
var html = json_data['rendered_text'];
var lineno = json_data['line_no'];
var target_id = json_data['target_id'];
placeInline(target_id, lineno, html);
}catch(e){
console.log(e);
}
}
/**
* Iterates over all the inlines, and places them inside proper blocks of data
*/
var renderInlineComments = function(file_comments){
for (f in file_comments){
// holding all comments for a FILE
var box = file_comments[f];
var target_id = YUD.getAttribute(box,'target_id');
// actually comments with line numbers
var comments = box.children;
for(var i=0; i<comments.length; i++){
var data = {
'rendered_text': comments[i].outerHTML,
'line_no': YUD.getAttribute(comments[i],'line'),
'target_id': target_id
}
renderInlineComment(data);
}
}
}
added option to remove members added using autocomplete widget from pull...
r2613 var removeReviewer = function(reviewer_id){
var el = YUD.get('reviewer_{0}'.format(reviewer_id));
if (el.parentNode !== undefined){
el.parentNode.removeChild(el);
}
remove reviewers button removes them without need of hitting save button.
r3106 updateReviewers();
added option to remove members added using autocomplete widget from pull...
r2613 }
cleaned up JS files in files templates....
r1699
removed JSON array envelope from filter files function...
r2428 var fileBrowserListeners = function(current_url, node_list_url, url_base){
cleaned up JS files in files templates....
r1699 var current_url_branch = +"?branch=__BRANCH__";
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');
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);
fix files quick filter links
r2891 YUC.asyncRequest('GET', node_list_url, {
cleaned up JS files in files templates....
r1699 success:function(o){
removed JSON array envelope from filter files function...
r2428 nodes = JSON.parse(o.responseText).nodes;
cleaned up JS files in files templates....
r1699 YUD.setStyle('node_filter_box_loading','display','none');
YUD.setStyle('node_filter_box','display','');
implements #330 api method for listing nodes at particular revision...
r1810 n_filter.focus();
if(YUD.hasClass(n_filter,'init')){
n_filter.value = '';
YUD.removeClass(n_filter,'init');
}
cleaned up JS files in files templates....
r1699 },
failure:function(o){
console.log('failed to load');
}
},null);
}
F.updateFilter = function(e) {
return function(){
// Reset timeout
F.filterTimeout = null;
implements #330 api method for listing nodes at particular revision...
r1810 var query = e.target.value.toLowerCase();
cleaned up JS files in files templates....
r1699 var match = [];
var matches = 0;
var matches_max = 20;
if (query != ""){
for(var i=0;i<nodes.length;i++){
implements #330 api method for listing nodes at particular revision...
r1810
var pos = nodes[i].name.toLowerCase().indexOf(query)
cleaned up JS files in files templates....
r1699 if(query && pos != -1){
matches++
//show only certain amount to not kill browser
if (matches > matches_max){
break;
}
implements #330 api method for listing nodes at particular revision...
r1810 var n = nodes[i].name;
var t = nodes[i].type;
cleaned up JS files in files templates....
r1699 var n_hl = n.substring(0,pos)
+"<b>{0}</b>".format(n.substring(pos,pos+query.length))
Reimplemented file-browser using partial-ajax...
r2686 +n.substring(pos+query.length)
fix files quick filter links
r2891 var new_url = url_base.replace('__FPATH__',n);
match.push('<tr><td><a class="browser-{0}" href="{1}">{2}</a></td><td colspan="5"></td></tr>'.format(t,new_url,n_hl));
cleaned up JS files in files templates....
r1699 }
if(match.length >= matches_max){
removed JSON array envelope from filter files function...
r2428 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['search truncated']));
cleaned up JS files in files templates....
r1699 }
}
}
if(query != ""){
YUD.setStyle('tbody','display','none');
YUD.setStyle('tbody_filtered','display','');
if (match.length==0){
removed JSON array envelope from filter files function...
r2428 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['no matching files']));
cleaned up JS files in files templates....
r1699 }
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(){
implements #330 api method for listing nodes at particular revision...
r1810 if(YUD.hasClass(n_filter,'init')){
n_filter.value = '';
YUD.removeClass(n_filter,'init');
}
cleaned up JS files in files templates....
r1699 });
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);
}
};
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 var getSelectionLink = function(e) {
fixed source selection link pop-up tooltip
r3081
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 //get selection from start/to nodes
if (typeof window.getSelection != "undefined") {
s = window.getSelection();
cleaned up JS files in files templates....
r1699
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 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];
}
fixed source selection link pop-up tooltip
r3081 // if we select more than 2 lines
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 if (ranges[0] != ranges[1]){
if(YUD.get('linktt') == null){
hl_div = document.createElement('div');
hl_div.id = 'linktt';
cleaned up JS files in files templates....
r1699 }
fixed source selection link pop-up tooltip
r3081 hl_div.innerHTML = '';
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 anchor = '#L'+ranges[0]+'-'+ranges[1];
fixed source selection link pop-up tooltip
r3081 var link = document.createElement('a');
link.href = location.href.substring(0,location.href.indexOf('#'))+anchor;
link.innerHTML = _TM['Selection link'];
hl_div.appendChild(link);
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 YUD.get('body').appendChild(hl_div);
xy = YUD.getXY(till.id);
fixed source selection link pop-up tooltip
r3081
YUD.addClass('linktt', 'hl-tip-box');
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 YUD.setStyle('linktt','top',xy[1]+offset+'px');
YUD.setStyle('linktt','left',xy[0]+'px');
YUD.setStyle('linktt','visibility','visible');
fixed source selection link pop-up tooltip
r3081
implements #636, lazy loading of history and authors to speed up page responsiveness....
r3001 }
else{
YUD.setStyle('linktt','visibility','hidden');
cleaned up JS files in files templates....
r1699 }
}
};
Notification system improvements...
r1712
Notification fixes...
r1717 var deleteNotification = function(url, notification_id,callbacks){
Notification system improvements...
r1712 var callback = {
success:function(o){
var obj = YUD.get(String("notification_"+notification_id));
Notification fixes...
r1717 if(obj.parentNode !== undefined){
obj.parentNode.removeChild(obj);
}
_run_callbacks(callbacks);
Notification system improvements...
r1712 },
failure:function(o){
alert("error");
},
};
var postData = '_method=delete';
var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
callback, postData);
};
fixes #229 repo sorting is not working....
r1778
added mark as read for single notifications
r2610 var readNotification = function(url, notification_id,callbacks){
var callback = {
success:function(o){
var obj = YUD.get(String("notification_"+notification_id));
YUD.removeClass(obj, 'unread');
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 var r_button = YUD.getElementsByClassName('read-notification',null,obj.children[0])[0];
added mark as read for single notifications
r2610
if(r_button.parentNode !== undefined){
r_button.parentNode.removeChild(r_button);
}
_run_callbacks(callbacks);
},
failure:function(o){
alert("error");
},
};
var postData = '_method=put';
var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
callback, postData);
};
fixes #229 repo sorting is not working....
r1778
Added gravatars into permissions view and permissions autocomplete
r2142 /** MEMBERS AUTOCOMPLETE WIDGET **/
#538 form for permissions can handle multiple users at once
r2759 var MembersAutoComplete = function (divid, cont, users_list, groups_list) {
Added gravatars into permissions view and permissions autocomplete
r2142 var myUsers = users_list;
var myGroups = groups_list;
// Define a custom search function for the DataSource of users
var matchUsers = function (sQuery) {
// Case insensitive matching
var query = sQuery.toLowerCase();
var i = 0;
var l = myUsers.length;
var matches = [];
// Match against each name of each contact
for (; i < l; i++) {
contact = myUsers[i];
Autocomplete fixes...
r2369 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
matches[matches.length] = contact;
}
Added gravatars into permissions view and permissions autocomplete
r2142 }
return matches;
};
// Define a custom search function for the DataSource of usersGroups
var matchGroups = function (sQuery) {
// Case insensitive matching
var query = sQuery.toLowerCase();
var i = 0;
var l = myGroups.length;
var matches = [];
// Match against each name of each contact
for (; i < l; i++) {
matched_group = myGroups[i];
if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
matches[matches.length] = matched_group;
}
}
return matches;
};
//match all
var matchAll = function (sQuery) {
u = matchUsers(sQuery);
g = matchGroups(sQuery);
return u.concat(g);
};
// DataScheme for members
var memberDS = new YAHOO.util.FunctionDataSource(matchAll);
memberDS.responseSchema = {
fields: ["id", "fname", "lname", "nname", "grname", "grmembers", "gravatar_lnk"]
};
// DataScheme for owner
var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
ownerDS.responseSchema = {
fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
};
// Instantiate AutoComplete for perms
#538 form for permissions can handle multiple users at once
r2759 var membersAC = new YAHOO.widget.AutoComplete(divid, cont, memberDS);
Added gravatars into permissions view and permissions autocomplete
r2142 membersAC.useShadow = false;
membersAC.resultTypeList = false;
disable animation on autocomplete widget
r2611 membersAC.animVert = false;
membersAC.animHoriz = false;
membersAC.animSpeed = 0.1;
Added gravatars into permissions view and permissions autocomplete
r2142
// Instantiate AutoComplete for owner
var ownerAC = new YAHOO.widget.AutoComplete("user", "owner_container", ownerDS);
ownerAC.useShadow = false;
ownerAC.resultTypeList = false;
disable animation on autocomplete widget
r2611 ownerAC.animVert = false;
ownerAC.animHoriz = false;
ownerAC.animSpeed = 0.1;
Added gravatars into permissions view and permissions autocomplete
r2142
// Helper highlight function for the formatter
var highlightMatch = function (full, snippet, matchindex) {
return full.substring(0, matchindex)
+ "<span class='match'>"
+ full.substr(matchindex, snippet.length)
+ "</span>" + full.substring(matchindex + snippet.length);
};
// Custom formatter to highlight the matching letters
var custom_formatter = function (oResultData, sQuery, sResultMatch) {
var query = sQuery.toLowerCase();
var _gravatar = function(res, em, group){
if (group !== undefined){
em = '/images/icons/group.png'
}
autocomplete overflow fixes
r2145 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
Added gravatars into permissions view and permissions autocomplete
r2142 return tmpl.format(em,res)
}
// group
if (oResultData.grname != undefined) {
var grname = oResultData.grname;
var grmembers = oResultData.grmembers;
var grnameMatchIndex = grname.toLowerCase().indexOf(query);
Autocomplete fixes...
r2369 var grprefix = "{0}: ".format(_TM['Group']);
Added gravatars into permissions view and permissions autocomplete
r2142 var grsuffix = " (" + grmembers + " )";
Autocomplete fixes...
r2369 var grsuffix = " ({0} {1})".format(grmembers, _TM['members']);
Added gravatars into permissions view and permissions autocomplete
r2142
if (grnameMatchIndex > -1) {
return _gravatar(grprefix + highlightMatch(grname, query, grnameMatchIndex) + grsuffix,null,true);
}
return _gravatar(grprefix + oResultData.grname + grsuffix, null,true);
// Users
Autocomplete fixes...
r2369 } else if (oResultData.nname != undefined) {
var fname = oResultData.fname || "";
var lname = oResultData.lname || "";
var nname = oResultData.nname;
// Guard against null value
var fnameMatchIndex = fname.toLowerCase().indexOf(query),
Added gravatars into permissions view and permissions autocomplete
r2142 lnameMatchIndex = lname.toLowerCase().indexOf(query),
nnameMatchIndex = nname.toLowerCase().indexOf(query),
displayfname, displaylname, displaynname;
if (fnameMatchIndex > -1) {
displayfname = highlightMatch(fname, query, fnameMatchIndex);
} else {
displayfname = fname;
}
if (lnameMatchIndex > -1) {
displaylname = highlightMatch(lname, query, lnameMatchIndex);
} else {
displaylname = lname;
}
if (nnameMatchIndex > -1) {
displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
} else {
displaynname = nname ? "(" + nname + ")" : "";
}
return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
} else {
return '';
}
};
membersAC.formatResult = custom_formatter;
ownerAC.formatResult = custom_formatter;
var myHandler = function (sType, aArgs) {
#538 form for permissions can handle multiple users at once
r2759 var nextId = divid.split('perm_new_member_name_')[1];
Added gravatars into permissions view and permissions autocomplete
r2142 var myAC = aArgs[0]; // reference back to the AC instance
var elLI = aArgs[1]; // reference to the selected LI element
var oData = aArgs[2]; // object literal of selected item's result data
//fill the autocomplete with value
if (oData.nname != undefined) {
//users
myAC.getInputEl().value = oData.nname;
#538 form for permissions can handle multiple users at once
r2759 YUD.get('perm_new_member_type_'+nextId).value = 'user';
Added gravatars into permissions view and permissions autocomplete
r2142 } else {
//groups
myAC.getInputEl().value = oData.grname;
#538 form for permissions can handle multiple users at once
r2759 YUD.get('perm_new_member_type_'+nextId).value = 'users_group';
Added gravatars into permissions view and permissions autocomplete
r2142 }
};
membersAC.itemSelectEvent.subscribe(myHandler);
if(ownerAC.itemSelectEvent){
ownerAC.itemSelectEvent.subscribe(myHandler);
}
return {
memberDS: memberDS,
ownerDS: ownerDS,
membersAC: membersAC,
ownerAC: ownerAC,
};
}
Autocomplete fixes...
r2369 var MentionsAutoComplete = function (divid, cont, users_list, groups_list) {
Added mentions autocomplete into main comments form...
r2368 var myUsers = users_list;
var myGroups = groups_list;
// Define a custom search function for the DataSource of users
var matchUsers = function (sQuery) {
var org_sQuery = sQuery;
if(this.mentionQuery == null){
return []
}
sQuery = this.mentionQuery;
// Case insensitive matching
var query = sQuery.toLowerCase();
var i = 0;
var l = myUsers.length;
var matches = [];
// Match against each name of each contact
for (; i < l; i++) {
contact = myUsers[i];
Autocomplete fixes...
r2369 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
Added mentions autocomplete into main comments form...
r2368 matches[matches.length] = contact;
}
}
return matches
};
//match all
var matchAll = function (sQuery) {
u = matchUsers(sQuery);
return u
};
// DataScheme for owner
var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
Autocomplete fixes...
r2369
Added mentions autocomplete into main comments form...
r2368 ownerDS.responseSchema = {
fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
};
// Instantiate AutoComplete for mentions
var ownerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
ownerAC.useShadow = false;
ownerAC.resultTypeList = false;
ownerAC.suppressInputUpdate = true;
disable animation on autocomplete widget
r2611 ownerAC.animVert = false;
ownerAC.animHoriz = false;
ownerAC.animSpeed = 0.1;
Added mentions autocomplete into main comments form...
r2368 // Helper highlight function for the formatter
var highlightMatch = function (full, snippet, matchindex) {
return full.substring(0, matchindex)
+ "<span class='match'>"
+ full.substr(matchindex, snippet.length)
+ "</span>" + full.substring(matchindex + snippet.length);
};
// Custom formatter to highlight the matching letters
ownerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
var org_sQuery = sQuery;
if(this.dataSource.mentionQuery != null){
sQuery = this.dataSource.mentionQuery;
}
var query = sQuery.toLowerCase();
var _gravatar = function(res, em, group){
if (group !== undefined){
em = '/images/icons/group.png'
}
tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
return tmpl.format(em,res)
}
Autocomplete fixes...
r2369 if (oResultData.nname != undefined) {
var fname = oResultData.fname || "";
var lname = oResultData.lname || "";
var nname = oResultData.nname;
// Guard against null value
var fnameMatchIndex = fname.toLowerCase().indexOf(query),
Added mentions autocomplete into main comments form...
r2368 lnameMatchIndex = lname.toLowerCase().indexOf(query),
nnameMatchIndex = nname.toLowerCase().indexOf(query),
displayfname, displaylname, displaynname;
if (fnameMatchIndex > -1) {
displayfname = highlightMatch(fname, query, fnameMatchIndex);
} else {
displayfname = fname;
}
if (lnameMatchIndex > -1) {
displaylname = highlightMatch(lname, query, lnameMatchIndex);
} else {
displaylname = lname;
}
if (nnameMatchIndex > -1) {
displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
} else {
displaynname = nname ? "(" + nname + ")" : "";
}
return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
} else {
return '';
}
};
if(ownerAC.itemSelectEvent){
ownerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
var myAC = aArgs[0]; // reference back to the AC instance
var elLI = aArgs[1]; // reference to the selected LI element
var oData = aArgs[2]; // object literal of selected item's result data
//fill the autocomplete with value
if (oData.nname != undefined) {
//users
//Replace the mention name with replaced
var re = new RegExp();
var org = myAC.getInputEl().value;
var chunks = myAC.dataSource.chunks
// replace middle chunk(the search term) with actuall match
chunks[1] = chunks[1].replace('@'+myAC.dataSource.mentionQuery,
'@'+oData.nname+' ');
myAC.getInputEl().value = chunks.join('')
YUD.get(myAC.getInputEl()).focus(); // Y U NO WORK !?
} else {
//groups
myAC.getInputEl().value = oData.grname;
YUD.get('perm_new_member_type').value = 'users_group';
}
});
}
// in this keybuffer we will gather current value of search !
// since we need to get this just when someone does `@` then we do the
// search
ownerAC.dataSource.chunks = [];
ownerAC.dataSource.mentionQuery = null;
ownerAC.get_mention = function(msg, max_pos) {
var org = msg;
var re = new RegExp('(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)$')
var chunks = [];
// cut first chunk until curret pos
var to_max = msg.substr(0, max_pos);
var at_pos = Math.max(0,to_max.lastIndexOf('@')-1);
var msg2 = to_max.substr(at_pos);
chunks.push(org.substr(0,at_pos))// prefix chunk
chunks.push(msg2) // search chunk
chunks.push(org.substr(max_pos)) // postfix chunk
// clean up msg2 for filtering and regex match
Autocomplete fixes...
r2369 var msg2 = msg2.lstrip(' ').lstrip('\n');
Added mentions autocomplete into main comments form...
r2368
if(re.test(msg2)){
var unam = re.exec(msg2)[1];
return [unam, chunks];
}
return [null, null];
Added autocomplete widget for pull request reviewers, in exchange of 90s style...
r2612 };
ie8 fixes for inline comments :/
r2698 if (ownerAC.textboxKeyUpEvent){
ownerAC.textboxKeyUpEvent.subscribe(function(type, args){
var ac_obj = args[0];
var currentMessage = args[1];
var currentCaretPosition = args[0]._elTextbox.selectionStart;
var unam = ownerAC.get_mention(currentMessage, currentCaretPosition);
var curr_search = null;
if(unam[0]){
curr_search = unam[0];
}
ownerAC.dataSource.chunks = unam[1];
ownerAC.dataSource.mentionQuery = curr_search;
})
}
Added mentions autocomplete into main comments form...
r2368 return {
ownerDS: ownerDS,
ownerAC: ownerAC,
};
}
Added autocomplete widget for pull request reviewers, in exchange of 90s style...
r2612 var PullRequestAutoComplete = function (divid, cont, users_list, groups_list) {
var myUsers = users_list;
var myGroups = groups_list;
// Define a custom search function for the DataSource of users
var matchUsers = function (sQuery) {
// Case insensitive matching
var query = sQuery.toLowerCase();
var i = 0;
var l = myUsers.length;
var matches = [];
// Match against each name of each contact
for (; i < l; i++) {
contact = myUsers[i];
if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
matches[matches.length] = contact;
}
}
return matches;
};
// Define a custom search function for the DataSource of usersGroups
var matchGroups = function (sQuery) {
// Case insensitive matching
var query = sQuery.toLowerCase();
var i = 0;
var l = myGroups.length;
var matches = [];
// Match against each name of each contact
for (; i < l; i++) {
matched_group = myGroups[i];
if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
matches[matches.length] = matched_group;
}
}
return matches;
};
//match all
var matchAll = function (sQuery) {
u = matchUsers(sQuery);
return u
};
// DataScheme for owner
var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
ownerDS.responseSchema = {
fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
};
// Instantiate AutoComplete for mentions
var reviewerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
reviewerAC.useShadow = false;
reviewerAC.resultTypeList = false;
reviewerAC.suppressInputUpdate = true;
reviewerAC.animVert = false;
reviewerAC.animHoriz = false;
reviewerAC.animSpeed = 0.1;
// Helper highlight function for the formatter
var highlightMatch = function (full, snippet, matchindex) {
return full.substring(0, matchindex)
+ "<span class='match'>"
+ full.substr(matchindex, snippet.length)
+ "</span>" + full.substring(matchindex + snippet.length);
};
// Custom formatter to highlight the matching letters
reviewerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
var org_sQuery = sQuery;
if(this.dataSource.mentionQuery != null){
sQuery = this.dataSource.mentionQuery;
}
var query = sQuery.toLowerCase();
var _gravatar = function(res, em, group){
if (group !== undefined){
em = '/images/icons/group.png'
}
tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
return tmpl.format(em,res)
}
if (oResultData.nname != undefined) {
var fname = oResultData.fname || "";
var lname = oResultData.lname || "";
var nname = oResultData.nname;
// Guard against null value
var fnameMatchIndex = fname.toLowerCase().indexOf(query),
lnameMatchIndex = lname.toLowerCase().indexOf(query),
nnameMatchIndex = nname.toLowerCase().indexOf(query),
displayfname, displaylname, displaynname;
if (fnameMatchIndex > -1) {
displayfname = highlightMatch(fname, query, fnameMatchIndex);
} else {
displayfname = fname;
}
if (lnameMatchIndex > -1) {
displaylname = highlightMatch(lname, query, lnameMatchIndex);
} else {
displaylname = lname;
}
if (nnameMatchIndex > -1) {
displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
} else {
displaynname = nname ? "(" + nname + ")" : "";
}
return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
} else {
return '';
}
};
//members cache to catch duplicates
reviewerAC.dataSource.cache = [];
// hack into select event
if(reviewerAC.itemSelectEvent){
reviewerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
var myAC = aArgs[0]; // reference back to the AC instance
var elLI = aArgs[1]; // reference to the selected LI element
var oData = aArgs[2]; // object literal of selected item's result data
var members = YUD.get('review_members');
//fill the autocomplete with value
if (oData.nname != undefined) {
if (myAC.dataSource.cache.indexOf(oData.id) != -1){
return
}
added option to remove members added using autocomplete widget from pull...
r2613 var tmpl = '<li id="reviewer_{2}">'+
Added autocomplete widget for pull request reviewers, in exchange of 90s style...
r2612 '<div class="reviewers_member">'+
'<div class="gravatar"><img alt="gravatar" src="{0}"/> </div>'+
'<div style="float:left">{1}</div>'+
'<input type="hidden" value="{2}" name="review_members" />'+
added option to remove members added using autocomplete widget from pull...
r2613 '<span class="delete_icon action_button" onclick="removeReviewer({2})"></span>'+
Added autocomplete widget for pull request reviewers, in exchange of 90s style...
r2612 '</div>'+
'</li>'
var displayname = "{0} {1} ({2})".format(oData.fname,oData.lname,oData.nname);
var element = tmpl.format(oData.gravatar_lnk,displayname,oData.id);
members.innerHTML += element;
myAC.dataSource.cache.push(oData.id);
added option to remove members added using autocomplete widget from pull...
r2613 YUD.get('user').value = ''
Added autocomplete widget for pull request reviewers, in exchange of 90s style...
r2612 }
});
}
return {
ownerDS: ownerDS,
reviewerAC: reviewerAC,
};
}
fixes #229 repo sorting is not working....
r1778 /**
Added sorting into journal and admin pages...
r1779 * QUICK REPO MENU
*/
var quick_repo_menu = function(){
quick_repo_menu changed from mouseclick to popup
r2088 YUE.on(YUQ('.quick_repo_menu'),'mouseenter',function(e){
var menu = e.currentTarget.firstElementChild.firstElementChild;
if(YUD.hasClass(menu,'hidden')){
YUD.replaceClass(e.currentTarget,'hidden', 'active');
YUD.replaceClass(menu, 'hidden', 'active');
}
})
YUE.on(YUQ('.quick_repo_menu'),'mouseleave',function(e){
var menu = e.currentTarget.firstElementChild.firstElementChild;
if(YUD.hasClass(menu,'active')){
YUD.replaceClass(e.currentTarget, 'active', 'hidden');
YUD.replaceClass(menu, 'active', 'hidden');
}
})
Added sorting into journal and admin pages...
r1779 };
/**
fixes #229 repo sorting is not working....
r1778 * TABLE SORTING
*/
// returns a node from given html;
var fromHTML = function(html){
var _html = document.createElement('element');
_html.innerHTML = html;
return _html;
}
var get_rev = function(node){
var n = node.firstElementChild.firstElementChild;
if (n===null){
return -1
}
else{
out = n.firstElementChild.innerHTML.split(':')[0].replace('r','');
return parseInt(out);
}
}
var get_name = function(node){
var name = node.firstElementChild.children[2].innerHTML;
return name
}
var get_group_name = function(node){
var name = node.firstElementChild.children[1].innerHTML;
return name
}
added sorting to bookmarks tags and branches
r1782 var get_date = function(node){
Fixed sorting by data when using custom date format from settings
r2548 var date_ = YUD.getAttribute(node.firstElementChild,'date');
added sorting to bookmarks tags and branches
r1782 return date_
}
Fixed sorting by data when using custom date format from settings
r2548 var get_age = function(node){
return node
}
implemented admin panel Users table with YUI datatable...
r2658 var get_link = function(node){
return node.firstElementChild.text;
}
fixes #229 repo sorting is not working....
r1778 var revisionSort = function(a, b, desc, field) {
var a_ = fromHTML(a.getData(field));
var b_ = fromHTML(b.getData(field));
// extract revisions from string nodes
a_ = get_rev(a_)
b_ = get_rev(b_)
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
};
var ageSort = function(a, b, desc, field) {
Fixed sorting by data when using custom date format from settings
r2548 var a_ = fromHTML(a.getData(field));
var b_ = fromHTML(b.getData(field));
// extract name from table
a_ = get_date(a_)
b_ = get_date(b_)
fixes #229 repo sorting is not working....
r1778
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
};
fixed sorting by last_login in users admin page
r2699 var lastLoginSort = function(a, b, desc, field) {
var a_ = a.getData('last_login_raw') || 0;
var b_ = b.getData('last_login_raw') || 0;
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
};
fixes #229 repo sorting is not working....
r1778 var nameSort = function(a, b, desc, field) {
var a_ = fromHTML(a.getData(field));
var b_ = fromHTML(b.getData(field));
implemented admin panel Users table with YUI datatable...
r2658
fixes #229 repo sorting is not working....
r1778 // extract name from table
a_ = get_name(a_)
b_ = get_name(b_)
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
};
implemented #377 Users view own permissions...
r2127 var permNameSort = function(a, b, desc, field) {
var a_ = fromHTML(a.getData(field));
var b_ = fromHTML(b.getData(field));
// extract name from table
linkify perms and make global ones display better
r2128
a_ = a_.children[0].innerHTML;
b_ = b_.children[0].innerHTML;
implemented #377 Users view own permissions...
r2127
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
};
fixes #229 repo sorting is not working....
r1778 var groupNameSort = function(a, b, desc, field) {
var a_ = fromHTML(a.getData(field));
var b_ = fromHTML(b.getData(field));
// extract name from table
a_ = get_group_name(a_)
b_ = get_group_name(b_)
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
added sorting to bookmarks tags and branches
r1782 };
var dateSort = function(a, b, desc, field) {
var a_ = fromHTML(a.getData(field));
var b_ = fromHTML(b.getData(field));
// extract name from table
a_ = get_date(a_)
b_ = get_date(b_)
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
Moved select widget to rhodecode.js
r2394 };
implemented admin panel Users table with YUI datatable...
r2658 var linkSort = function(a, b, desc, field) {
var a_ = fromHTML(a.getData(field));
var b_ = fromHTML(a.getData(field));
// extract url text from string nodes
a_ = get_link(a_)
b_ = get_link(b_)
var comp = YAHOO.util.Sort.compare;
var compState = comp(a_, b_, desc);
return compState;
}
Moved select widget to rhodecode.js
r2394
#538 form for permissions can handle multiple users at once
r2759 var addPermAction = function(_html, users_list, groups_list){
var elmts = YUD.getElementsByClassName('last_new_member');
var last_node = elmts[elmts.length-1];
if (last_node){
var next_id = (YUD.getElementsByClassName('new_members')).length;
_html = _html.format(next_id);
last_node.innerHTML = _html;
YUD.setStyle(last_node, 'display', '');
YUD.removeClass(last_node, 'last_new_member');
MembersAutoComplete("perm_new_member_name_"+next_id,
"perm_container_"+next_id, users_list, groups_list);
//create new last NODE
var el = document.createElement('tr');
el.id = 'add_perm_input';
YUD.addClass(el,'last_new_member');
YUD.addClass(el,'new_members');
YUD.insertAfter(el, last_node);
}
}
Moved select widget to rhodecode.js
r2394
/* Multi selectors */
var MultiSelectWidget = function(selected_id, available_id, form_id){
//definition of containers ID's
var selected_container = selected_id;
var available_container = available_id;
//temp container for selected storage.
var cache = new Array();
var av_cache = new Array();
var c = YUD.get(selected_container);
var ac = YUD.get(available_container);
//get only selected options for further fullfilment
for(var i = 0;node =c.options[i];i++){
if(node.selected){
//push selected to my temp storage left overs :)
cache.push(node);
}
}
//get all available options to cache
for(var i = 0;node =ac.options[i];i++){
//push selected to my temp storage left overs :)
av_cache.push(node);
}
//fill available only with those not in choosen
ac.options.length=0;
tmp_cache = new Array();
for(var i = 0;node = av_cache[i];i++){
var add = true;
for(var i2 = 0;node_2 = cache[i2];i2++){
if(node.value == node_2.value){
add=false;
break;
}
}
if(add){
tmp_cache.push(new Option(node.text, node.value, false, false));
}
}
for(var i = 0;node = tmp_cache[i];i++){
ac.options[i] = node;
}
function prompts_action_callback(e){
var choosen = YUD.get(selected_container);
var available = YUD.get(available_container);
//get checked and unchecked options from field
function get_checked(from_field){
//temp container for storage.
var sel_cache = new Array();
var oth_cache = new Array();
for(var i = 0;node = from_field.options[i];i++){
if(node.selected){
//push selected fields :)
sel_cache.push(node);
}
else{
oth_cache.push(node)
}
}
return [sel_cache,oth_cache]
}
//fill the field with given options
function fill_with(field,options){
//clear firtst
field.options.length=0;
for(var i = 0;node = options[i];i++){
field.options[i]=new Option(node.text, node.value,
false, false);
}
}
//adds to current field
function add_to(field,options){
for(var i = 0;node = options[i];i++){
field.appendChild(new Option(node.text, node.value,
false, false));
}
}
// add action
if (this.id=='add_element'){
var c = get_checked(available);
add_to(choosen,c[0]);
fill_with(available,c[1]);
}
// remove action
if (this.id=='remove_element'){
var c = get_checked(choosen);
add_to(available,c[0]);
fill_with(choosen,c[1]);
}
// add all elements
if(this.id=='add_all_elements'){
for(var i=0; node = available.options[i];i++){
choosen.appendChild(new Option(node.text,
node.value, false, false));
}
available.options.length = 0;
}
//remove all elements
if(this.id=='remove_all_elements'){
for(var i=0; node = choosen.options[i];i++){
available.appendChild(new Option(node.text,
node.value, false, false));
}
choosen.options.length = 0;
}
}
YUE.addListener(['add_element','remove_element',
'add_all_elements','remove_all_elements'],'click',
prompts_action_callback)
if (form_id !== undefined) {
YUE.addListener(form_id,'submit',function(){
var choosen = YUD.get(selected_container);
for (var i = 0; i < choosen.options.length; i++) {
choosen.options[i].selected = 'selected';
}
});
}
Dies Koper
fixed comment addition and deletion functionality on IE9
r2723 }