diff --git a/rhodecode/public/js/rhodecode.js b/rhodecode/public/js/rhodecode.js --- a/rhodecode/public/js/rhodecode.js +++ b/rhodecode/public/js/rhodecode.js @@ -163,7 +163,175 @@ ColorGenerator.prototype = { } } +/** + * PyRoutesJS + * + * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/ + */ +var pyroutes = (function() { + // access global map defined in special file pyroutes + var matchlist = PROUTES_MAP; + var sprintf = (function() { + function get_type(variable) { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); + } + function str_repeat(input, multiplier) { + for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */} + return output.join(''); + } + var str_format = function() { + if (!str_format.cache.hasOwnProperty(arguments[0])) { + str_format.cache[arguments[0]] = str_format.parse(arguments[0]); + } + return str_format.format.call(null, str_format.cache[arguments[0]], arguments); + }; + + str_format.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } + else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = Math.abs(arg); break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + str_format.cache = {}; + + str_format.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw('[sprintf] huh?'); + } + } + } + else { + throw('[sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw('[sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + return str_format; + })(); + + var vsprintf = function(fmt, argv) { + argv.unshift(fmt); + return sprintf.apply(null, argv); + }; + return { + 'url': function(route_name, params) { + var result = route_name; + if (typeof(params) != 'object'){ + params = {}; + } + if (matchlist.hasOwnProperty(route_name)) { + var route = matchlist[route_name]; + for(var i=0; i < route[1].length; i++) { + + if (!params.hasOwnProperty(route[1][i])) + throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation'); + } + result = sprintf(route[0], params); + } + + return result; + }, + 'register': function(route_name, route_tmpl, req_params) { + if (typeof(req_params) != 'object') { + req_params = []; + } + //fix escape + route_tmpl = unescape(route_tmpl); + keys = []; + for (o in req_params){ + keys.push(req_params[o]) + } + matchlist[route_name] = [ + route_tmpl, + keys + ] + }, + '_routes': function(){ + return matchlist; + } + } +})(); @@ -333,8 +501,9 @@ var show_changeset_tooltip = function(){ YUD.setAttribute(target,'id',ttid); YUD.setAttribute(target, 'title',_TM['loading...']); YAHOO.yuitip.main.set_listeners(target); - YAHOO.yuitip.main.show_yuitip(e, target); - ajaxGET(LAZY_CS_URL.replace('__NAME__',repo_name).replace('__REV__', rid), success) + YAHOO.yuitip.main.show_yuitip(e, target); + var url = pyroutes.url('changeset_info', {"repo_name":repo_name, "revision": rid}); + ajaxGET(url, success) } }); }; @@ -396,7 +565,7 @@ var showRepoSize = function(target, repo if(!YUD.hasClass(target, 'loaded')){ YUD.get(target).innerHTML = _TM['loading...']; - var url = REPO_SIZE_URL.replace('__NAME__', repo_name); + var url = pyroutes.url('repo_size', {"repo_name":repo_name}); YUC.asyncRequest('POST',url,{ success:function(o){ YUD.get(target).innerHTML = JSON.parse(o.responseText); @@ -725,24 +894,6 @@ var deleteComment = function(comment_id) ajaxPOST(url,postData,success); } -var updateReviewers = function(reviewers_ids){ - if (reviewers_ids === undefined){ - var reviewers_ids = []; - var ids = YUQ('#review_members input'); - for(var i=0; i'+ + '
gravatar
'+ + '
{1}
'+ + ''+ + ''+ + ''+ + '' ; + var displayname = "{0} {1} ({2})".format(fname,lname,nname); + var element = tmpl.format(gravatar_link,displayname,id); + // check if we don't have this ID already in + var ids = []; + var _els = YUQ('#review_members li'); + for (el in _els){ + ids.push(_els[el].id) + } + if(ids.indexOf('reviewer_'+id) == -1){ + //only add if it's not there + members.innerHTML += element; + } + +} + +var removeReviewMember = function(reviewer_id, repo_name, pull_request_id){ + var el = YUD.get('reviewer_{0}'.format(reviewer_id)); + if (el.parentNode !== undefined){ + el.parentNode.removeChild(el); + } +} + +var updateReviewers = function(reviewers_ids, repo_name, pull_request_id){ + if (reviewers_ids === undefined){ + var reviewers_ids = []; + var ids = YUQ('#review_members input'); + for(var i=0; i'+ - '
gravatar
'+ - '
{1}
'+ - ''+ - ''+ - ''+ - '' - - 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; + addReviewMember(oData.id, oData.fname, oData.lname, oData.nname, + oData.gravatar_lnk); myAC.dataSource.cache.push(oData.id); YUD.get('user').value = '' } @@ -1651,7 +1830,6 @@ var PullRequestAutoComplete = function ( }; } - /** * QUICK REPO MENU */