##// END OF EJS Templates
make sure we hide the spans
marcink -
r3784:62fb395a beta
parent child Browse files
Show More
@@ -1,2512 +1,2513 b''
1 1 /**
2 2 RhodeCode JS Files
3 3 **/
4 4
5 5 if (typeof console == "undefined" || typeof console.log == "undefined"){
6 6 console = { log: function() {} }
7 7 }
8 8
9 9
10 10 var str_repeat = function(i, m) {
11 11 for (var o = []; m > 0; o[--m] = i);
12 12 return o.join('');
13 13 };
14 14
15 15 /**
16 16 * INJECT .format function into String
17 17 * Usage: "My name is {0} {1}".format("Johny","Bravo")
18 18 * Return "My name is Johny Bravo"
19 19 * Inspired by https://gist.github.com/1049426
20 20 */
21 21 String.prototype.format = function() {
22 22
23 23 function format() {
24 24 var str = this;
25 25 var len = arguments.length+1;
26 26 var safe = undefined;
27 27 var arg = undefined;
28 28
29 29 // For each {0} {1} {n...} replace with the argument in that position. If
30 30 // the argument is an object or an array it will be stringified to JSON.
31 31 for (var i=0; i < len; arg = arguments[i++]) {
32 32 safe = typeof arg === 'object' ? JSON.stringify(arg) : arg;
33 33 str = str.replace(RegExp('\\{'+(i-1)+'\\}', 'g'), safe);
34 34 }
35 35 return str;
36 36 }
37 37
38 38 // Save a reference of what may already exist under the property native.
39 39 // Allows for doing something like: if("".format.native) { /* use native */ }
40 40 format.native = String.prototype.format;
41 41
42 42 // Replace the prototype property
43 43 return format;
44 44
45 45 }();
46 46
47 47 String.prototype.strip = function(char) {
48 48 if(char === undefined){
49 49 char = '\\s';
50 50 }
51 51 return this.replace(new RegExp('^'+char+'+|'+char+'+$','g'), '');
52 52 }
53 53 String.prototype.lstrip = function(char) {
54 54 if(char === undefined){
55 55 char = '\\s';
56 56 }
57 57 return this.replace(new RegExp('^'+char+'+'),'');
58 58 }
59 59 String.prototype.rstrip = function(char) {
60 60 if(char === undefined){
61 61 char = '\\s';
62 62 }
63 63 return this.replace(new RegExp(''+char+'+$'),'');
64 64 }
65 65
66 66
67 67 if(!Array.prototype.indexOf) {
68 68 Array.prototype.indexOf = function(needle) {
69 69 for(var i = 0; i < this.length; i++) {
70 70 if(this[i] === needle) {
71 71 return i;
72 72 }
73 73 }
74 74 return -1;
75 75 };
76 76 }
77 77
78 78 // IE(CRAP) doesn't support previousElementSibling
79 79 var prevElementSibling = function( el ) {
80 80 if( el.previousElementSibling ) {
81 81 return el.previousElementSibling;
82 82 } else {
83 83 while( el = el.previousSibling ) {
84 84 if( el.nodeType === 1 ) return el;
85 85 }
86 86 }
87 87 }
88 88
89 89 /**
90 90 * SmartColorGenerator
91 91 *
92 92 *usage::
93 93 * var CG = new ColorGenerator();
94 94 * var col = CG.getColor(key); //returns array of RGB
95 95 * 'rgb({0})'.format(col.join(',')
96 96 *
97 97 * @returns {ColorGenerator}
98 98 */
99 99 var ColorGenerator = function(){
100 100 this.GOLDEN_RATIO = 0.618033988749895;
101 101 this.CURRENT_RATIO = 0.22717784590367374 // this can be random
102 102 this.HSV_1 = 0.75;//saturation
103 103 this.HSV_2 = 0.95;
104 104 this.color;
105 105 this.cacheColorMap = {};
106 106 };
107 107
108 108 ColorGenerator.prototype = {
109 109 getColor:function(key){
110 110 if(this.cacheColorMap[key] !== undefined){
111 111 return this.cacheColorMap[key];
112 112 }
113 113 else{
114 114 this.cacheColorMap[key] = this.generateColor();
115 115 return this.cacheColorMap[key];
116 116 }
117 117 },
118 118 _hsvToRgb:function(h,s,v){
119 119 if (s == 0.0)
120 120 return [v, v, v];
121 121 i = parseInt(h * 6.0)
122 122 f = (h * 6.0) - i
123 123 p = v * (1.0 - s)
124 124 q = v * (1.0 - s * f)
125 125 t = v * (1.0 - s * (1.0 - f))
126 126 i = i % 6
127 127 if (i == 0)
128 128 return [v, t, p]
129 129 if (i == 1)
130 130 return [q, v, p]
131 131 if (i == 2)
132 132 return [p, v, t]
133 133 if (i == 3)
134 134 return [p, q, v]
135 135 if (i == 4)
136 136 return [t, p, v]
137 137 if (i == 5)
138 138 return [v, p, q]
139 139 },
140 140 generateColor:function(){
141 141 this.CURRENT_RATIO = this.CURRENT_RATIO+this.GOLDEN_RATIO;
142 142 this.CURRENT_RATIO = this.CURRENT_RATIO %= 1;
143 143 HSV_tuple = [this.CURRENT_RATIO, this.HSV_1, this.HSV_2]
144 144 RGB_tuple = this._hsvToRgb(HSV_tuple[0],HSV_tuple[1],HSV_tuple[2]);
145 145 function toRgb(v){
146 146 return ""+parseInt(v*256)
147 147 }
148 148 return [toRgb(RGB_tuple[0]),toRgb(RGB_tuple[1]),toRgb(RGB_tuple[2])];
149 149
150 150 }
151 151 }
152 152
153 153 /**
154 154 * PyRoutesJS
155 155 *
156 156 * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id>
157 157 */
158 158 var pyroutes = (function() {
159 159 // access global map defined in special file pyroutes
160 160 var matchlist = PROUTES_MAP;
161 161 var sprintf = (function() {
162 162 function get_type(variable) {
163 163 return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
164 164 }
165 165 function str_repeat(input, multiplier) {
166 166 for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
167 167 return output.join('');
168 168 }
169 169
170 170 var str_format = function() {
171 171 if (!str_format.cache.hasOwnProperty(arguments[0])) {
172 172 str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
173 173 }
174 174 return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
175 175 };
176 176
177 177 str_format.format = function(parse_tree, argv) {
178 178 var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
179 179 for (i = 0; i < tree_length; i++) {
180 180 node_type = get_type(parse_tree[i]);
181 181 if (node_type === 'string') {
182 182 output.push(parse_tree[i]);
183 183 }
184 184 else if (node_type === 'array') {
185 185 match = parse_tree[i]; // convenience purposes only
186 186 if (match[2]) { // keyword argument
187 187 arg = argv[cursor];
188 188 for (k = 0; k < match[2].length; k++) {
189 189 if (!arg.hasOwnProperty(match[2][k])) {
190 190 throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
191 191 }
192 192 arg = arg[match[2][k]];
193 193 }
194 194 }
195 195 else if (match[1]) { // positional argument (explicit)
196 196 arg = argv[match[1]];
197 197 }
198 198 else { // positional argument (implicit)
199 199 arg = argv[cursor++];
200 200 }
201 201
202 202 if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
203 203 throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
204 204 }
205 205 switch (match[8]) {
206 206 case 'b': arg = arg.toString(2); break;
207 207 case 'c': arg = String.fromCharCode(arg); break;
208 208 case 'd': arg = parseInt(arg, 10); break;
209 209 case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
210 210 case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
211 211 case 'o': arg = arg.toString(8); break;
212 212 case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
213 213 case 'u': arg = Math.abs(arg); break;
214 214 case 'x': arg = arg.toString(16); break;
215 215 case 'X': arg = arg.toString(16).toUpperCase(); break;
216 216 }
217 217 arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
218 218 pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
219 219 pad_length = match[6] - String(arg).length;
220 220 pad = match[6] ? str_repeat(pad_character, pad_length) : '';
221 221 output.push(match[5] ? arg + pad : pad + arg);
222 222 }
223 223 }
224 224 return output.join('');
225 225 };
226 226
227 227 str_format.cache = {};
228 228
229 229 str_format.parse = function(fmt) {
230 230 var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
231 231 while (_fmt) {
232 232 if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
233 233 parse_tree.push(match[0]);
234 234 }
235 235 else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
236 236 parse_tree.push('%');
237 237 }
238 238 else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
239 239 if (match[2]) {
240 240 arg_names |= 1;
241 241 var field_list = [], replacement_field = match[2], field_match = [];
242 242 if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
243 243 field_list.push(field_match[1]);
244 244 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
245 245 if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
246 246 field_list.push(field_match[1]);
247 247 }
248 248 else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
249 249 field_list.push(field_match[1]);
250 250 }
251 251 else {
252 252 throw('[sprintf] huh?');
253 253 }
254 254 }
255 255 }
256 256 else {
257 257 throw('[sprintf] huh?');
258 258 }
259 259 match[2] = field_list;
260 260 }
261 261 else {
262 262 arg_names |= 2;
263 263 }
264 264 if (arg_names === 3) {
265 265 throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
266 266 }
267 267 parse_tree.push(match);
268 268 }
269 269 else {
270 270 throw('[sprintf] huh?');
271 271 }
272 272 _fmt = _fmt.substring(match[0].length);
273 273 }
274 274 return parse_tree;
275 275 };
276 276
277 277 return str_format;
278 278 })();
279 279
280 280 var vsprintf = function(fmt, argv) {
281 281 argv.unshift(fmt);
282 282 return sprintf.apply(null, argv);
283 283 };
284 284 return {
285 285 'url': function(route_name, params) {
286 286 var result = route_name;
287 287 if (typeof(params) != 'object'){
288 288 params = {};
289 289 }
290 290 if (matchlist.hasOwnProperty(route_name)) {
291 291 var route = matchlist[route_name];
292 292 // param substitution
293 293 for(var i=0; i < route[1].length; i++) {
294 294
295 295 if (!params.hasOwnProperty(route[1][i]))
296 296 throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation');
297 297 }
298 298 result = sprintf(route[0], params);
299 299
300 300 var ret = [];
301 301 //extra params => GET
302 302 for(param in params){
303 303 if (route[1].indexOf(param) == -1){
304 304 ret.push(encodeURIComponent(param) + "=" + encodeURIComponent(params[param]));
305 305 }
306 306 }
307 307 var _parts = ret.join("&");
308 308 if(_parts){
309 309 result = result +'?'+ _parts
310 310 }
311 311 }
312 312
313 313 return result;
314 314 },
315 315 'register': function(route_name, route_tmpl, req_params) {
316 316 if (typeof(req_params) != 'object') {
317 317 req_params = [];
318 318 }
319 319 //fix escape
320 320 route_tmpl = unescape(route_tmpl);
321 321 keys = [];
322 322 for (o in req_params){
323 323 keys.push(req_params[o])
324 324 }
325 325 matchlist[route_name] = [
326 326 route_tmpl,
327 327 keys
328 328 ]
329 329 },
330 330 '_routes': function(){
331 331 return matchlist;
332 332 }
333 333 }
334 334 })();
335 335
336 336
337 337
338 338 /**
339 339 * GLOBAL YUI Shortcuts
340 340 */
341 341 var YUC = YAHOO.util.Connect;
342 342 var YUD = YAHOO.util.Dom;
343 343 var YUE = YAHOO.util.Event;
344 344 var YUQ = YAHOO.util.Selector.query;
345 345
346 346 // defines if push state is enabled for this browser ?
347 347 var push_state_enabled = Boolean(
348 348 window.history && window.history.pushState && window.history.replaceState
349 349 && !( /* disable for versions of iOS before version 4.3 (8F190) */
350 350 (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent)
351 351 /* disable for the mercury iOS browser, or at least older versions of the webkit engine */
352 352 || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent)
353 353 )
354 354 );
355 355
356 356 var _run_callbacks = function(callbacks){
357 357 if (callbacks !== undefined){
358 358 var _l = callbacks.length;
359 359 for (var i=0;i<_l;i++){
360 360 var func = callbacks[i];
361 361 if(typeof(func)=='function'){
362 362 try{
363 363 func();
364 364 }catch (err){};
365 365 }
366 366 }
367 367 }
368 368 }
369 369
370 370 /**
371 371 * turns objects into GET query string
372 372 */
373 373 var toQueryString = function(o) {
374 374 if(typeof o !== 'object') {
375 375 return false;
376 376 }
377 377 var _p, _qs = [];
378 378 for(_p in o) {
379 379 _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
380 380 }
381 381 return _qs.join('&');
382 382 };
383 383
384 384 /**
385 385 * Partial Ajax Implementation
386 386 *
387 387 * @param url: defines url to make partial request
388 388 * @param container: defines id of container to input partial result
389 389 * @param s_call: success callback function that takes o as arg
390 390 * o.tId
391 391 * o.status
392 392 * o.statusText
393 393 * o.getResponseHeader[ ]
394 394 * o.getAllResponseHeaders
395 395 * o.responseText
396 396 * o.responseXML
397 397 * o.argument
398 398 * @param f_call: failure callback
399 399 * @param args arguments
400 400 */
401 401 function ypjax(url,container,s_call,f_call,args){
402 402 var method='GET';
403 403 if(args===undefined){
404 404 args=null;
405 405 }
406 406
407 407 // Set special header for partial ajax == HTTP_X_PARTIAL_XHR
408 408 YUC.initHeader('X-PARTIAL-XHR',true);
409 409
410 410 // wrapper of passed callback
411 411 var s_wrapper = (function(o){
412 412 return function(o){
413 413 YUD.get(container).innerHTML=o.responseText;
414 414 YUD.setStyle(container,'opacity','1.0');
415 415 //execute the given original callback
416 416 if (s_call !== undefined){
417 417 s_call(o);
418 418 }
419 419 }
420 420 })()
421 421 YUD.setStyle(container,'opacity','0.3');
422 422 YUC.asyncRequest(method,url,{
423 423 success:s_wrapper,
424 424 failure:function(o){
425 425 console.log(o);
426 426 YUD.get(container).innerHTML='<span class="error_red">ERROR: {0}</span>'.format(o.status);
427 427 YUD.setStyle(container,'opacity','1.0');
428 428 },
429 429 cache:false
430 430 },args);
431 431
432 432 };
433 433
434 434 var ajaxGET = function(url,success) {
435 435 // Set special header for ajax == HTTP_X_PARTIAL_XHR
436 436 YUC.initHeader('X-PARTIAL-XHR',true);
437 437
438 438 var sUrl = url;
439 439 var callback = {
440 440 success: success,
441 441 failure: function (o) {
442 442 if (o.status != 0) {
443 443 alert("error: " + o.statusText);
444 444 };
445 445 },
446 446 };
447 447
448 448 var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
449 449 return request;
450 450 };
451 451
452 452
453 453
454 454 var ajaxPOST = function(url,postData,success) {
455 455 // Set special header for ajax == HTTP_X_PARTIAL_XHR
456 456 YUC.initHeader('X-PARTIAL-XHR',true);
457 457
458 458 var sUrl = url;
459 459 var callback = {
460 460 success: success,
461 461 failure: function (o) {
462 462 alert("error");
463 463 },
464 464 };
465 465 var postData = toQueryString(postData);
466 466 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
467 467 return request;
468 468 };
469 469
470 470
471 471 /**
472 472 * tooltip activate
473 473 */
474 474 var tooltip_activate = function(){
475 475 yt = YAHOO.yuitip.main;
476 476 YUE.onDOMReady(yt.init);
477 477 };
478 478
479 479 /**
480 480 * show more
481 481 */
482 482 var show_more_event = function(){
483 483 YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
484 484 var el = e.target;
485 485 YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
486 486 YUD.setStyle(el.parentNode,'display','none');
487 487 });
488 488 };
489 489
490 490 /**
491 491 * show changeset tooltip
492 492 */
493 493 var show_changeset_tooltip = function(){
494 494 YUE.on(YUD.getElementsByClassName('lazy-cs'), 'mouseover', function(e){
495 495 var target = e.currentTarget;
496 496 var rid = YUD.getAttribute(target,'raw_id');
497 497 var repo_name = YUD.getAttribute(target,'repo_name');
498 498 var ttid = 'tt-'+rid;
499 499 var success = function(o){
500 500 var json = JSON.parse(o.responseText);
501 501 YUD.addClass(target,'tooltip')
502 502 YUD.setAttribute(target, 'title',json['message']);
503 503 YAHOO.yuitip.main.show_yuitip(e, target);
504 504 }
505 505 if(rid && !YUD.hasClass(target, 'tooltip')){
506 506 YUD.setAttribute(target,'id',ttid);
507 507 YUD.setAttribute(target, 'title',_TM['loading...']);
508 508 YAHOO.yuitip.main.set_listeners(target);
509 509 YAHOO.yuitip.main.show_yuitip(e, target);
510 510 var url = pyroutes.url('changeset_info', {"repo_name":repo_name, "revision": rid});
511 511 ajaxGET(url, success)
512 512 }
513 513 });
514 514 };
515 515
516 516 var onSuccessFollow = function(target){
517 517 var f = YUD.get(target);
518 518 var f_cnt = YUD.get('current_followers_count');
519 519
520 520 if(YUD.hasClass(f, 'follow')){
521 521 f.setAttribute('class','following');
522 522 f.setAttribute('title',_TM['Stop following this repository']);
523 523
524 524 if(f_cnt){
525 525 var cnt = Number(f_cnt.innerHTML)+1;
526 526 f_cnt.innerHTML = cnt;
527 527 }
528 528 }
529 529 else{
530 530 f.setAttribute('class','follow');
531 531 f.setAttribute('title',_TM['Start following this repository']);
532 532 if(f_cnt){
533 533 var cnt = Number(f_cnt.innerHTML)-1;
534 534 f_cnt.innerHTML = cnt;
535 535 }
536 536 }
537 537 }
538 538
539 539 var toggleFollowingUser = function(target,fallows_user_id,token,user_id){
540 540 args = 'follows_user_id='+fallows_user_id;
541 541 args+= '&amp;auth_token='+token;
542 542 if(user_id != undefined){
543 543 args+="&amp;user_id="+user_id;
544 544 }
545 545 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
546 546 success:function(o){
547 547 onSuccessFollow(target);
548 548 }
549 549 },args);
550 550 return false;
551 551 }
552 552
553 553 var toggleFollowingRepo = function(target,fallows_repo_id,token,user_id){
554 554
555 555 args = 'follows_repo_id='+fallows_repo_id;
556 556 args+= '&amp;auth_token='+token;
557 557 if(user_id != undefined){
558 558 args+="&amp;user_id="+user_id;
559 559 }
560 560 YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
561 561 success:function(o){
562 562 onSuccessFollow(target);
563 563 }
564 564 },args);
565 565 return false;
566 566 }
567 567
568 568 var showRepoSize = function(target, repo_name, token){
569 569 var args= 'auth_token='+token;
570 570
571 571 if(!YUD.hasClass(target, 'loaded')){
572 572 YUD.get(target).innerHTML = _TM['Loading ...'];
573 573 var url = pyroutes.url('repo_size', {"repo_name":repo_name});
574 574 YUC.asyncRequest('POST',url,{
575 575 success:function(o){
576 576 YUD.get(target).innerHTML = JSON.parse(o.responseText);
577 577 YUD.addClass(target, 'loaded');
578 578 }
579 579 },args);
580 580 }
581 581 return false;
582 582 }
583 583
584 584 /**
585 585 * TOOLTIP IMPL.
586 586 */
587 587 YAHOO.namespace('yuitip');
588 588 YAHOO.yuitip.main = {
589 589
590 590 $: YAHOO.util.Dom.get,
591 591
592 592 bgColor: '#000',
593 593 speed: 0.3,
594 594 opacity: 0.9,
595 595 offset: [15,15],
596 596 useAnim: false,
597 597 maxWidth: 600,
598 598 add_links: false,
599 599 yuitips: [],
600 600
601 601 set_listeners: function(tt){
602 602 YUE.on(tt, 'mouseover', yt.show_yuitip, tt);
603 603 YUE.on(tt, 'mousemove', yt.move_yuitip, tt);
604 604 YUE.on(tt, 'mouseout', yt.close_yuitip, tt);
605 605 },
606 606
607 607 init: function(){
608 608 yt.tipBox = yt.$('tip-box');
609 609 if(!yt.tipBox){
610 610 yt.tipBox = document.createElement('div');
611 611 document.body.appendChild(yt.tipBox);
612 612 yt.tipBox.id = 'tip-box';
613 613 }
614 614
615 615 YUD.setStyle(yt.tipBox, 'display', 'none');
616 616 YUD.setStyle(yt.tipBox, 'position', 'absolute');
617 617 if(yt.maxWidth !== null){
618 618 YUD.setStyle(yt.tipBox, 'max-width', yt.maxWidth+'px');
619 619 }
620 620
621 621 var yuitips = YUD.getElementsByClassName('tooltip');
622 622
623 623 if(yt.add_links === true){
624 624 var links = document.getElementsByTagName('a');
625 625 var linkLen = links.length;
626 626 for(i=0;i<linkLen;i++){
627 627 yuitips.push(links[i]);
628 628 }
629 629 }
630 630
631 631 var yuiLen = yuitips.length;
632 632
633 633 for(i=0;i<yuiLen;i++){
634 634 yt.set_listeners(yuitips[i]);
635 635 }
636 636 },
637 637
638 638 show_yuitip: function(e, el){
639 639 YUE.stopEvent(e);
640 640 if(el.tagName.toLowerCase() === 'img'){
641 641 yt.tipText = el.alt ? el.alt : '';
642 642 } else {
643 643 yt.tipText = el.title ? el.title : '';
644 644 }
645 645
646 646 if(yt.tipText !== ''){
647 647 // save org title
648 648 YUD.setAttribute(el, 'tt_title', yt.tipText);
649 649 // reset title to not show org tooltips
650 650 YUD.setAttribute(el, 'title', '');
651 651
652 652 yt.tipBox.innerHTML = yt.tipText;
653 653 YUD.setStyle(yt.tipBox, 'display', 'block');
654 654 if(yt.useAnim === true){
655 655 YUD.setStyle(yt.tipBox, 'opacity', '0');
656 656 var newAnim = new YAHOO.util.Anim(yt.tipBox,
657 657 {
658 658 opacity: { to: yt.opacity }
659 659 }, yt.speed, YAHOO.util.Easing.easeOut
660 660 );
661 661 newAnim.animate();
662 662 }
663 663 }
664 664 },
665 665
666 666 move_yuitip: function(e, el){
667 667 YUE.stopEvent(e);
668 668 var movePos = YUE.getXY(e);
669 669 YUD.setStyle(yt.tipBox, 'top', (movePos[1] + yt.offset[1]) + 'px');
670 670 YUD.setStyle(yt.tipBox, 'left', (movePos[0] + yt.offset[0]) + 'px');
671 671 },
672 672
673 673 close_yuitip: function(e, el){
674 674 YUE.stopEvent(e);
675 675
676 676 if(yt.useAnim === true){
677 677 var newAnim = new YAHOO.util.Anim(yt.tipBox,
678 678 {
679 679 opacity: { to: 0 }
680 680 }, yt.speed, YAHOO.util.Easing.easeOut
681 681 );
682 682 newAnim.animate();
683 683 } else {
684 684 YUD.setStyle(yt.tipBox, 'display', 'none');
685 685 }
686 686 YUD.setAttribute(el,'title', YUD.getAttribute(el, 'tt_title'));
687 687 }
688 688 }
689 689
690 690 /**
691 691 * Quick filter widget
692 692 *
693 693 * @param target: filter input target
694 694 * @param nodes: list of nodes in html we want to filter.
695 695 * @param display_element function that takes current node from nodes and
696 696 * does hide or show based on the node
697 697 *
698 698 */
699 699 var q_filter = function(target,nodes,display_element){
700 700
701 701 var nodes = nodes;
702 702 var q_filter_field = YUD.get(target);
703 703 var F = YAHOO.namespace(target);
704 704
705 705 YUE.on(q_filter_field,'keyup',function(e){
706 706 clearTimeout(F.filterTimeout);
707 707 F.filterTimeout = setTimeout(F.updateFilter,600);
708 708 });
709 709
710 710 F.filterTimeout = null;
711 711
712 712 var show_node = function(node){
713 713 YUD.setStyle(node,'display','')
714 714 }
715 715 var hide_node = function(node){
716 716 YUD.setStyle(node,'display','none');
717 717 }
718 718
719 719 F.updateFilter = function() {
720 720 // Reset timeout
721 721 F.filterTimeout = null;
722 722
723 723 var obsolete = [];
724 724
725 725 var req = q_filter_field.value.toLowerCase();
726 726
727 727 var l = nodes.length;
728 728 var i;
729 729 var showing = 0;
730 730
731 731 for (i=0;i<l;i++ ){
732 732 var n = nodes[i];
733 733 var target_element = display_element(n)
734 734 if(req && n.innerHTML.toLowerCase().indexOf(req) == -1){
735 735 hide_node(target_element);
736 736 }
737 737 else{
738 738 show_node(target_element);
739 739 showing+=1;
740 740 }
741 741 }
742 742
743 743 // if repo_count is set update the number
744 744 var cnt = YUD.get('repo_count');
745 745 if(cnt){
746 746 YUD.get('repo_count').innerHTML = showing;
747 747 }
748 748
749 749 }
750 750 };
751 751
752 752 var tableTr = function(cls, body){
753 753 var _el = document.createElement('div');
754 754 var cont = new YAHOO.util.Element(body);
755 755 var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
756 756 var id = 'comment-tr-{0}'.format(comment_id);
757 757 var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
758 758 '<td class="lineno-inline new-inline"></td>'+
759 759 '<td class="lineno-inline old-inline"></td>'+
760 760 '<td>{2}</td>'+
761 761 '</tr></tbody></table>').format(id, cls, body);
762 762 _el.innerHTML = _html;
763 763 return _el.children[0].children[0].children[0];
764 764 };
765 765
766 766 /** comments **/
767 767 var removeInlineForm = function(form) {
768 768 form.parentNode.removeChild(form);
769 769 };
770 770
771 771 var createInlineForm = function(parent_tr, f_path, line) {
772 772 var tmpl = YUD.get('comment-inline-form-template').innerHTML;
773 773 tmpl = tmpl.format(f_path, line);
774 774 var form = tableTr('comment-form-inline',tmpl)
775 775
776 776 // create event for hide button
777 777 form = new YAHOO.util.Element(form);
778 778 var form_hide_button = new YAHOO.util.Element(YUD.getElementsByClassName('hide-inline-form',null,form)[0]);
779 779 form_hide_button.on('click', function(e) {
780 780 var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
781 781 if(YUD.hasClass(newtr.nextElementSibling,'inline-comments-button')){
782 782 YUD.setStyle(newtr.nextElementSibling,'display','');
783 783 }
784 784 removeInlineForm(newtr);
785 785 YUD.removeClass(parent_tr, 'form-open');
786 786 YUD.removeClass(parent_tr, 'hl-comment');
787 787
788 788 });
789 789
790 790 return form
791 791 };
792 792
793 793 /**
794 794 * Inject inline comment for on given TR this tr should be always an .line
795 795 * tr containing the line. Code will detect comment, and always put the comment
796 796 * block at the very bottom
797 797 */
798 798 var injectInlineForm = function(tr){
799 799 if(!YUD.hasClass(tr, 'line')){
800 800 return
801 801 }
802 802 var submit_url = AJAX_COMMENT_URL;
803 803 var _td = YUD.getElementsByClassName('code',null,tr)[0];
804 804 if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(_td,'no-comment')){
805 805 return
806 806 }
807 807 YUD.addClass(tr,'form-open');
808 808 YUD.addClass(tr,'hl-comment');
809 809 var node = YUD.getElementsByClassName('full_f_path',null,tr.parentNode.parentNode.parentNode)[0];
810 810 var f_path = YUD.getAttribute(node,'path');
811 811 var lineno = getLineNo(tr);
812 812 var form = createInlineForm(tr, f_path, lineno, submit_url);
813 813
814 814 var parent = tr;
815 815 while (1){
816 816 var n = parent.nextElementSibling;
817 817 // next element are comments !
818 818 if(YUD.hasClass(n,'inline-comments')){
819 819 parent = n;
820 820 }
821 821 else{
822 822 break;
823 823 }
824 824 }
825 825 YUD.insertAfter(form,parent);
826 826 var f = YUD.get(form);
827 827 var overlay = YUD.getElementsByClassName('overlay',null,f)[0];
828 828 var _form = YUD.getElementsByClassName('inline-form',null,f)[0];
829 829
830 830 YUE.on(YUD.get(_form), 'submit',function(e){
831 831 YUE.preventDefault(e);
832 832
833 833 //ajax submit
834 834 var text = YUD.get('text_'+lineno).value;
835 835 var postData = {
836 836 'text':text,
837 837 'f_path':f_path,
838 838 'line':lineno
839 839 };
840 840
841 841 if(lineno === undefined){
842 842 alert('missing line !');
843 843 return
844 844 }
845 845 if(f_path === undefined){
846 846 alert('missing file path !');
847 847 return
848 848 }
849 849
850 850 if(text == ""){
851 851 return
852 852 }
853 853
854 854 var success = function(o){
855 855 YUD.removeClass(tr, 'form-open');
856 856 removeInlineForm(f);
857 857 var json_data = JSON.parse(o.responseText);
858 858 renderInlineComment(json_data);
859 859 };
860 860
861 861 if (YUD.hasClass(overlay,'overlay')){
862 862 var w = _form.offsetWidth;
863 863 var h = _form.offsetHeight;
864 864 YUD.setStyle(overlay,'width',w+'px');
865 865 YUD.setStyle(overlay,'height',h+'px');
866 866 }
867 867 YUD.addClass(overlay, 'submitting');
868 868
869 869 ajaxPOST(submit_url, postData, success);
870 870 });
871 871
872 872 YUE.on('preview-btn_'+lineno, 'click', function(e){
873 873 var _text = YUD.get('text_'+lineno).value;
874 874 if(!_text){
875 875 return
876 876 }
877 877 var post_data = {'text': _text};
878 878 YUD.addClass('preview-box_'+lineno, 'unloaded');
879 879 YUD.get('preview-box_'+lineno).innerHTML = _TM['Loading ...'];
880 880 YUD.setStyle('edit-container_'+lineno, 'display', 'none');
881 881 YUD.setStyle('preview-container_'+lineno, 'display', '');
882 882
883 883 var url = pyroutes.url('changeset_comment_preview', {'repo_name': REPO_NAME});
884 884 ajaxPOST(url,post_data,function(o){
885 885 YUD.get('preview-box_'+lineno).innerHTML = o.responseText;
886 886 YUD.removeClass('preview-box_'+lineno, 'unloaded');
887 887 })
888 888 })
889 889 YUE.on('edit-btn_'+lineno, 'click', function(e){
890 890 YUD.setStyle('edit-container_'+lineno, 'display', '');
891 891 YUD.setStyle('preview-container_'+lineno, 'display', 'none');
892 892 })
893 893
894 894
895 895 setTimeout(function(){
896 896 // callbacks
897 897 tooltip_activate();
898 898 MentionsAutoComplete('text_'+lineno, 'mentions_container_'+lineno,
899 899 _USERS_AC_DATA, _GROUPS_AC_DATA);
900 900 var _e = YUD.get('text_'+lineno);
901 901 if(_e){
902 902 _e.focus();
903 903 }
904 904 },10)
905 905 };
906 906
907 907 var deleteComment = function(comment_id){
908 908 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__',comment_id);
909 909 var postData = {'_method':'delete'};
910 910 var success = function(o){
911 911 var n = YUD.get('comment-tr-'+comment_id);
912 912 var root = prevElementSibling(prevElementSibling(n));
913 913 n.parentNode.removeChild(n);
914 914
915 915 // scann nodes, and attach add button to last one only for TR
916 916 // which are the inline comments
917 917 if(root && root.tagName == 'TR'){
918 918 placeAddButton(root);
919 919 }
920 920 }
921 921 ajaxPOST(url,postData,success);
922 922 }
923 923
924 924 var createInlineAddButton = function(tr){
925 925
926 926 var label = TRANSLATION_MAP['Add another comment'];
927 927
928 928 var html_el = document.createElement('div');
929 929 YUD.addClass(html_el, 'add-comment');
930 930 html_el.innerHTML = '<span class="ui-btn">{0}</span>'.format(label);
931 931
932 932 var add = new YAHOO.util.Element(html_el);
933 933 add.on('click', function(e) {
934 934 injectInlineForm(tr);
935 935 });
936 936 return add;
937 937 };
938 938
939 939 var getLineNo = function(tr) {
940 940 var line;
941 941 var o = tr.children[0].id.split('_');
942 942 var n = tr.children[1].id.split('_');
943 943
944 944 if (n.length >= 2) {
945 945 line = n[n.length-1];
946 946 } else if (o.length >= 2) {
947 947 line = o[o.length-1];
948 948 }
949 949
950 950 return line
951 951 };
952 952
953 953 var placeAddButton = function(target_tr){
954 954 if(!target_tr){
955 955 return
956 956 }
957 957 var last_node = target_tr;
958 958 //scann
959 959 while (1){
960 960 var n = last_node.nextElementSibling;
961 961 // next element are comments !
962 962 if(YUD.hasClass(n,'inline-comments')){
963 963 last_node = n;
964 964 //also remove the comment button from previous
965 965 var comment_add_buttons = YUD.getElementsByClassName('add-comment',null,last_node);
966 966 for(var i=0;i<comment_add_buttons.length;i++){
967 967 var b = comment_add_buttons[i];
968 968 b.parentNode.removeChild(b);
969 969 }
970 970 }
971 971 else{
972 972 break;
973 973 }
974 974 }
975 975
976 976 var add = createInlineAddButton(target_tr);
977 977 // get the comment div
978 978 var comment_block = YUD.getElementsByClassName('comment',null,last_node)[0];
979 979 // attach add button
980 980 YUD.insertAfter(add,comment_block);
981 981 }
982 982
983 983 /**
984 984 * Places the inline comment into the changeset block in proper line position
985 985 */
986 986 var placeInline = function(target_container,lineno,html){
987 987 var lineid = "{0}_{1}".format(target_container,lineno);
988 988 var target_line = YUD.get(lineid);
989 989 var comment = new YAHOO.util.Element(tableTr('inline-comments',html))
990 990
991 991 // check if there are comments already !
992 992 var parent = target_line.parentNode;
993 993 var root_parent = parent;
994 994 while (1){
995 995 var n = parent.nextElementSibling;
996 996 // next element are comments !
997 997 if(YUD.hasClass(n,'inline-comments')){
998 998 parent = n;
999 999 }
1000 1000 else{
1001 1001 break;
1002 1002 }
1003 1003 }
1004 1004 // put in the comment at the bottom
1005 1005 YUD.insertAfter(comment,parent);
1006 1006
1007 1007 // scann nodes, and attach add button to last one
1008 1008 placeAddButton(root_parent);
1009 1009
1010 1010 return target_line;
1011 1011 }
1012 1012
1013 1013 /**
1014 1014 * make a single inline comment and place it inside
1015 1015 */
1016 1016 var renderInlineComment = function(json_data){
1017 1017 try{
1018 1018 var html = json_data['rendered_text'];
1019 1019 var lineno = json_data['line_no'];
1020 1020 var target_id = json_data['target_id'];
1021 1021 placeInline(target_id, lineno, html);
1022 1022
1023 1023 }catch(e){
1024 1024 console.log(e);
1025 1025 }
1026 1026 }
1027 1027
1028 1028 /**
1029 1029 * Iterates over all the inlines, and places them inside proper blocks of data
1030 1030 */
1031 1031 var renderInlineComments = function(file_comments){
1032 1032 for (f in file_comments){
1033 1033 // holding all comments for a FILE
1034 1034 var box = file_comments[f];
1035 1035
1036 1036 var target_id = YUD.getAttribute(box,'target_id');
1037 1037 // actually comments with line numbers
1038 1038 var comments = box.children;
1039 1039 for(var i=0; i<comments.length; i++){
1040 1040 var data = {
1041 1041 'rendered_text': comments[i].outerHTML,
1042 1042 'line_no': YUD.getAttribute(comments[i],'line'),
1043 1043 'target_id': target_id
1044 1044 }
1045 1045 renderInlineComment(data);
1046 1046 }
1047 1047 }
1048 1048 }
1049 1049
1050 1050 var fileBrowserListeners = function(current_url, node_list_url, url_base){
1051 1051 var current_url_branch = +"?branch=__BRANCH__";
1052 1052
1053 1053 YUE.on('stay_at_branch','click',function(e){
1054 1054 if(e.target.checked){
1055 1055 var uri = current_url_branch;
1056 1056 uri = uri.replace('__BRANCH__',e.target.value);
1057 1057 window.location = uri;
1058 1058 }
1059 1059 else{
1060 1060 window.location = current_url;
1061 1061 }
1062 1062 })
1063 1063
1064 1064 var n_filter = YUD.get('node_filter');
1065 1065 var F = YAHOO.namespace('node_filter');
1066 1066
1067 1067 F.filterTimeout = null;
1068 1068 var nodes = null;
1069 1069
1070 1070 F.initFilter = function(){
1071 1071 YUD.setStyle('node_filter_box_loading','display','');
1072 1072 YUD.setStyle('search_activate_id','display','none');
1073 1073 YUD.setStyle('add_node_id','display','none');
1074 1074 YUC.initHeader('X-PARTIAL-XHR',true);
1075 1075 YUC.asyncRequest('GET', node_list_url, {
1076 1076 success:function(o){
1077 1077 nodes = JSON.parse(o.responseText).nodes;
1078 1078 YUD.setStyle('node_filter_box_loading','display','none');
1079 1079 YUD.setStyle('node_filter_box','display','');
1080 1080 n_filter.focus();
1081 1081 if(YUD.hasClass(n_filter,'init')){
1082 1082 n_filter.value = '';
1083 1083 YUD.removeClass(n_filter,'init');
1084 1084 }
1085 1085 },
1086 1086 failure:function(o){
1087 1087 console.log('failed to load');
1088 1088 }
1089 1089 },null);
1090 1090 }
1091 1091
1092 1092 F.updateFilter = function(e) {
1093 1093
1094 1094 return function(){
1095 1095 // Reset timeout
1096 1096 F.filterTimeout = null;
1097 1097 var query = e.target.value.toLowerCase();
1098 1098 var match = [];
1099 1099 var matches = 0;
1100 1100 var matches_max = 20;
1101 1101 if (query != ""){
1102 1102 for(var i=0;i<nodes.length;i++){
1103 1103
1104 1104 var pos = nodes[i].name.toLowerCase().indexOf(query)
1105 1105 if(query && pos != -1){
1106 1106
1107 1107 matches++
1108 1108 //show only certain amount to not kill browser
1109 1109 if (matches > matches_max){
1110 1110 break;
1111 1111 }
1112 1112
1113 1113 var n = nodes[i].name;
1114 1114 var t = nodes[i].type;
1115 1115 var n_hl = n.substring(0,pos)
1116 1116 +"<b>{0}</b>".format(n.substring(pos,pos+query.length))
1117 1117 +n.substring(pos+query.length)
1118 1118 var new_url = url_base.replace('__FPATH__',n);
1119 1119 match.push('<tr><td><a class="browser-{0}" href="{1}">{2}</a></td><td colspan="5"></td></tr>'.format(t,new_url,n_hl));
1120 1120 }
1121 1121 if(match.length >= matches_max){
1122 1122 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['Search truncated']));
1123 1123 }
1124 1124 }
1125 1125 }
1126 1126 if(query != ""){
1127 1127 YUD.setStyle('tbody','display','none');
1128 1128 YUD.setStyle('tbody_filtered','display','');
1129 1129
1130 1130 if (match.length==0){
1131 1131 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['No matching files']));
1132 1132 }
1133 1133
1134 1134 YUD.get('tbody_filtered').innerHTML = match.join("");
1135 1135 }
1136 1136 else{
1137 1137 YUD.setStyle('tbody','display','');
1138 1138 YUD.setStyle('tbody_filtered','display','none');
1139 1139 }
1140 1140
1141 1141 }
1142 1142 };
1143 1143
1144 1144 YUE.on(YUD.get('filter_activate'),'click',function(){
1145 1145 F.initFilter();
1146 1146 })
1147 1147 YUE.on(n_filter,'click',function(){
1148 1148 if(YUD.hasClass(n_filter,'init')){
1149 1149 n_filter.value = '';
1150 1150 YUD.removeClass(n_filter,'init');
1151 1151 }
1152 1152 });
1153 1153 YUE.on(n_filter,'keyup',function(e){
1154 1154 clearTimeout(F.filterTimeout);
1155 1155 F.filterTimeout = setTimeout(F.updateFilter(e),600);
1156 1156 });
1157 1157 };
1158 1158
1159 1159
1160 1160 var initCodeMirror = function(textAreadId,resetUrl){
1161 1161 var myCodeMirror = CodeMirror.fromTextArea(YUD.get(textAreadId),{
1162 1162 mode: "null",
1163 1163 lineNumbers:true
1164 1164 });
1165 1165 YUE.on('reset','click',function(e){
1166 1166 window.location=resetUrl
1167 1167 });
1168 1168
1169 1169 YUE.on('file_enable','click',function(){
1170 1170 YUD.setStyle('editor_container','display','');
1171 1171 YUD.setStyle('upload_file_container','display','none');
1172 1172 YUD.setStyle('filename_container','display','');
1173 1173 });
1174 1174
1175 1175 YUE.on('upload_file_enable','click',function(){
1176 1176 YUD.setStyle('editor_container','display','none');
1177 1177 YUD.setStyle('upload_file_container','display','');
1178 1178 YUD.setStyle('filename_container','display','none');
1179 1179 });
1180 1180 };
1181 1181
1182 1182
1183 1183
1184 1184 var getIdentNode = function(n){
1185 1185 //iterate thru nodes untill matched interesting node !
1186 1186
1187 1187 if (typeof n == 'undefined'){
1188 1188 return -1
1189 1189 }
1190 1190
1191 1191 if(typeof n.id != "undefined" && n.id.match('L[0-9]+')){
1192 1192 return n
1193 1193 }
1194 1194 else{
1195 1195 return getIdentNode(n.parentNode);
1196 1196 }
1197 1197 };
1198 1198
1199 1199 var getSelectionLink = function(e) {
1200 1200
1201 1201 //get selection from start/to nodes
1202 1202 if (typeof window.getSelection != "undefined") {
1203 1203 s = window.getSelection();
1204 1204
1205 1205 from = getIdentNode(s.anchorNode);
1206 1206 till = getIdentNode(s.focusNode);
1207 1207
1208 1208 f_int = parseInt(from.id.replace('L',''));
1209 1209 t_int = parseInt(till.id.replace('L',''));
1210 1210
1211 1211 if (f_int > t_int){
1212 1212 //highlight from bottom
1213 1213 offset = -35;
1214 1214 ranges = [t_int,f_int];
1215 1215
1216 1216 }
1217 1217 else{
1218 1218 //highligth from top
1219 1219 offset = 35;
1220 1220 ranges = [f_int,t_int];
1221 1221 }
1222 1222 // if we select more than 2 lines
1223 1223 if (ranges[0] != ranges[1]){
1224 1224 if(YUD.get('linktt') == null){
1225 1225 hl_div = document.createElement('div');
1226 1226 hl_div.id = 'linktt';
1227 1227 }
1228 1228 hl_div.innerHTML = '';
1229 1229
1230 1230 anchor = '#L'+ranges[0]+'-'+ranges[1];
1231 1231 var link = document.createElement('a');
1232 1232 link.href = location.href.substring(0,location.href.indexOf('#'))+anchor;
1233 1233 link.innerHTML = _TM['Selection link'];
1234 1234 hl_div.appendChild(link);
1235 1235 YUD.get('body').appendChild(hl_div);
1236 1236
1237 1237 xy = YUD.getXY(till.id);
1238 1238
1239 1239 YUD.addClass('linktt', 'hl-tip-box');
1240 1240 YUD.setStyle('linktt','top',xy[1]+offset+'px');
1241 1241 YUD.setStyle('linktt','left',xy[0]+'px');
1242 1242 YUD.setStyle('linktt','visibility','visible');
1243 1243
1244 1244 }
1245 1245 else{
1246 1246 YUD.setStyle('linktt','visibility','hidden');
1247 1247 }
1248 1248 }
1249 1249 };
1250 1250
1251 1251 var deleteNotification = function(url, notification_id,callbacks){
1252 1252 var callback = {
1253 1253 success:function(o){
1254 1254 var obj = YUD.get(String("notification_"+notification_id));
1255 1255 if(obj.parentNode !== undefined){
1256 1256 obj.parentNode.removeChild(obj);
1257 1257 }
1258 1258 _run_callbacks(callbacks);
1259 1259 },
1260 1260 failure:function(o){
1261 1261 alert("error");
1262 1262 },
1263 1263 };
1264 1264 var postData = '_method=delete';
1265 1265 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1266 1266 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1267 1267 callback, postData);
1268 1268 };
1269 1269
1270 1270 var readNotification = function(url, notification_id,callbacks){
1271 1271 var callback = {
1272 1272 success:function(o){
1273 1273 var obj = YUD.get(String("notification_"+notification_id));
1274 1274 YUD.removeClass(obj, 'unread');
1275 1275 var r_button = YUD.getElementsByClassName('read-notification',null,obj.children[0])[0];
1276 1276
1277 1277 if(r_button.parentNode !== undefined){
1278 1278 r_button.parentNode.removeChild(r_button);
1279 1279 }
1280 1280 _run_callbacks(callbacks);
1281 1281 },
1282 1282 failure:function(o){
1283 1283 alert("error");
1284 1284 },
1285 1285 };
1286 1286 var postData = '_method=put';
1287 1287 var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
1288 1288 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl,
1289 1289 callback, postData);
1290 1290 };
1291 1291
1292 1292 /** MEMBERS AUTOCOMPLETE WIDGET **/
1293 1293
1294 1294 var MembersAutoComplete = function (divid, cont, users_list, groups_list) {
1295 1295 var myUsers = users_list;
1296 1296 var myGroups = groups_list;
1297 1297
1298 1298 // Define a custom search function for the DataSource of users
1299 1299 var matchUsers = function (sQuery) {
1300 1300 // Case insensitive matching
1301 1301 var query = sQuery.toLowerCase();
1302 1302 var i = 0;
1303 1303 var l = myUsers.length;
1304 1304 var matches = [];
1305 1305
1306 1306 // Match against each name of each contact
1307 1307 for (; i < l; i++) {
1308 1308 contact = myUsers[i];
1309 1309 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1310 1310 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1311 1311 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1312 1312 matches[matches.length] = contact;
1313 1313 }
1314 1314 }
1315 1315 return matches;
1316 1316 };
1317 1317
1318 1318 // Define a custom search function for the DataSource of userGroups
1319 1319 var matchGroups = function (sQuery) {
1320 1320 // Case insensitive matching
1321 1321 var query = sQuery.toLowerCase();
1322 1322 var i = 0;
1323 1323 var l = myGroups.length;
1324 1324 var matches = [];
1325 1325
1326 1326 // Match against each name of each contact
1327 1327 for (; i < l; i++) {
1328 1328 matched_group = myGroups[i];
1329 1329 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1330 1330 matches[matches.length] = matched_group;
1331 1331 }
1332 1332 }
1333 1333 return matches;
1334 1334 };
1335 1335
1336 1336 //match all
1337 1337 var matchAll = function (sQuery) {
1338 1338 u = matchUsers(sQuery);
1339 1339 g = matchGroups(sQuery);
1340 1340 return u.concat(g);
1341 1341 };
1342 1342
1343 1343 // DataScheme for members
1344 1344 var memberDS = new YAHOO.util.FunctionDataSource(matchAll);
1345 1345 memberDS.responseSchema = {
1346 1346 fields: ["id", "fname", "lname", "nname", "grname", "grmembers", "gravatar_lnk"]
1347 1347 };
1348 1348
1349 1349 // DataScheme for owner
1350 1350 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1351 1351 ownerDS.responseSchema = {
1352 1352 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1353 1353 };
1354 1354
1355 1355 // Instantiate AutoComplete for perms
1356 1356 var membersAC = new YAHOO.widget.AutoComplete(divid, cont, memberDS);
1357 1357 membersAC.useShadow = false;
1358 1358 membersAC.resultTypeList = false;
1359 1359 membersAC.animVert = false;
1360 1360 membersAC.animHoriz = false;
1361 1361 membersAC.animSpeed = 0.1;
1362 1362
1363 1363 // Instantiate AutoComplete for owner
1364 1364 var ownerAC = new YAHOO.widget.AutoComplete("user", "owner_container", ownerDS);
1365 1365 ownerAC.useShadow = false;
1366 1366 ownerAC.resultTypeList = false;
1367 1367 ownerAC.animVert = false;
1368 1368 ownerAC.animHoriz = false;
1369 1369 ownerAC.animSpeed = 0.1;
1370 1370
1371 1371 // Helper highlight function for the formatter
1372 1372 var highlightMatch = function (full, snippet, matchindex) {
1373 1373 return full.substring(0, matchindex)
1374 1374 + "<span class='match'>"
1375 1375 + full.substr(matchindex, snippet.length)
1376 1376 + "</span>" + full.substring(matchindex + snippet.length);
1377 1377 };
1378 1378
1379 1379 // Custom formatter to highlight the matching letters
1380 1380 var custom_formatter = function (oResultData, sQuery, sResultMatch) {
1381 1381 var query = sQuery.toLowerCase();
1382 1382 var _gravatar = function(res, em, group){
1383 1383 if (group !== undefined){
1384 1384 em = '/images/icons/group.png'
1385 1385 }
1386 1386 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1387 1387 return tmpl.format(em,res)
1388 1388 }
1389 1389 // group
1390 1390 if (oResultData.grname != undefined) {
1391 1391 var grname = oResultData.grname;
1392 1392 var grmembers = oResultData.grmembers;
1393 1393 var grnameMatchIndex = grname.toLowerCase().indexOf(query);
1394 1394 var grprefix = "{0}: ".format(_TM['Group']);
1395 1395 var grsuffix = " (" + grmembers + " )";
1396 1396 var grsuffix = " ({0} {1})".format(grmembers, _TM['members']);
1397 1397
1398 1398 if (grnameMatchIndex > -1) {
1399 1399 return _gravatar(grprefix + highlightMatch(grname, query, grnameMatchIndex) + grsuffix,null,true);
1400 1400 }
1401 1401 return _gravatar(grprefix + oResultData.grname + grsuffix, null,true);
1402 1402 // Users
1403 1403 } else if (oResultData.nname != undefined) {
1404 1404 var fname = oResultData.fname || "";
1405 1405 var lname = oResultData.lname || "";
1406 1406 var nname = oResultData.nname;
1407 1407
1408 1408 // Guard against null value
1409 1409 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1410 1410 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1411 1411 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1412 1412 displayfname, displaylname, displaynname;
1413 1413
1414 1414 if (fnameMatchIndex > -1) {
1415 1415 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1416 1416 } else {
1417 1417 displayfname = fname;
1418 1418 }
1419 1419
1420 1420 if (lnameMatchIndex > -1) {
1421 1421 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1422 1422 } else {
1423 1423 displaylname = lname;
1424 1424 }
1425 1425
1426 1426 if (nnameMatchIndex > -1) {
1427 1427 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1428 1428 } else {
1429 1429 displaynname = nname ? "(" + nname + ")" : "";
1430 1430 }
1431 1431
1432 1432 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1433 1433 } else {
1434 1434 return '';
1435 1435 }
1436 1436 };
1437 1437 membersAC.formatResult = custom_formatter;
1438 1438 ownerAC.formatResult = custom_formatter;
1439 1439
1440 1440 var myHandler = function (sType, aArgs) {
1441 1441 var nextId = divid.split('perm_new_member_name_')[1];
1442 1442 var myAC = aArgs[0]; // reference back to the AC instance
1443 1443 var elLI = aArgs[1]; // reference to the selected LI element
1444 1444 var oData = aArgs[2]; // object literal of selected item's result data
1445 1445 //fill the autocomplete with value
1446 1446 if (oData.nname != undefined) {
1447 1447 //users
1448 1448 myAC.getInputEl().value = oData.nname;
1449 1449 YUD.get('perm_new_member_type_'+nextId).value = 'user';
1450 1450 } else {
1451 1451 //groups
1452 1452 myAC.getInputEl().value = oData.grname;
1453 1453 YUD.get('perm_new_member_type_'+nextId).value = 'users_group';
1454 1454 }
1455 1455 };
1456 1456
1457 1457 membersAC.itemSelectEvent.subscribe(myHandler);
1458 1458 if(ownerAC.itemSelectEvent){
1459 1459 ownerAC.itemSelectEvent.subscribe(myHandler);
1460 1460 }
1461 1461
1462 1462 return {
1463 1463 memberDS: memberDS,
1464 1464 ownerDS: ownerDS,
1465 1465 membersAC: membersAC,
1466 1466 ownerAC: ownerAC,
1467 1467 };
1468 1468 }
1469 1469
1470 1470
1471 1471 var MentionsAutoComplete = function (divid, cont, users_list, groups_list) {
1472 1472 var myUsers = users_list;
1473 1473 var myGroups = groups_list;
1474 1474
1475 1475 // Define a custom search function for the DataSource of users
1476 1476 var matchUsers = function (sQuery) {
1477 1477 var org_sQuery = sQuery;
1478 1478 if(this.mentionQuery == null){
1479 1479 return []
1480 1480 }
1481 1481 sQuery = this.mentionQuery;
1482 1482 // Case insensitive matching
1483 1483 var query = sQuery.toLowerCase();
1484 1484 var i = 0;
1485 1485 var l = myUsers.length;
1486 1486 var matches = [];
1487 1487
1488 1488 // Match against each name of each contact
1489 1489 for (; i < l; i++) {
1490 1490 contact = myUsers[i];
1491 1491 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1492 1492 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1493 1493 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1494 1494 matches[matches.length] = contact;
1495 1495 }
1496 1496 }
1497 1497 return matches
1498 1498 };
1499 1499
1500 1500 //match all
1501 1501 var matchAll = function (sQuery) {
1502 1502 u = matchUsers(sQuery);
1503 1503 return u
1504 1504 };
1505 1505
1506 1506 // DataScheme for owner
1507 1507 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1508 1508
1509 1509 ownerDS.responseSchema = {
1510 1510 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1511 1511 };
1512 1512
1513 1513 // Instantiate AutoComplete for mentions
1514 1514 var ownerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1515 1515 ownerAC.useShadow = false;
1516 1516 ownerAC.resultTypeList = false;
1517 1517 ownerAC.suppressInputUpdate = true;
1518 1518 ownerAC.animVert = false;
1519 1519 ownerAC.animHoriz = false;
1520 1520 ownerAC.animSpeed = 0.1;
1521 1521
1522 1522 // Helper highlight function for the formatter
1523 1523 var highlightMatch = function (full, snippet, matchindex) {
1524 1524 return full.substring(0, matchindex)
1525 1525 + "<span class='match'>"
1526 1526 + full.substr(matchindex, snippet.length)
1527 1527 + "</span>" + full.substring(matchindex + snippet.length);
1528 1528 };
1529 1529
1530 1530 // Custom formatter to highlight the matching letters
1531 1531 ownerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1532 1532 var org_sQuery = sQuery;
1533 1533 if(this.dataSource.mentionQuery != null){
1534 1534 sQuery = this.dataSource.mentionQuery;
1535 1535 }
1536 1536
1537 1537 var query = sQuery.toLowerCase();
1538 1538 var _gravatar = function(res, em, group){
1539 1539 if (group !== undefined){
1540 1540 em = '/images/icons/group.png'
1541 1541 }
1542 1542 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1543 1543 return tmpl.format(em,res)
1544 1544 }
1545 1545 if (oResultData.nname != undefined) {
1546 1546 var fname = oResultData.fname || "";
1547 1547 var lname = oResultData.lname || "";
1548 1548 var nname = oResultData.nname;
1549 1549
1550 1550 // Guard against null value
1551 1551 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1552 1552 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1553 1553 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1554 1554 displayfname, displaylname, displaynname;
1555 1555
1556 1556 if (fnameMatchIndex > -1) {
1557 1557 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1558 1558 } else {
1559 1559 displayfname = fname;
1560 1560 }
1561 1561
1562 1562 if (lnameMatchIndex > -1) {
1563 1563 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1564 1564 } else {
1565 1565 displaylname = lname;
1566 1566 }
1567 1567
1568 1568 if (nnameMatchIndex > -1) {
1569 1569 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1570 1570 } else {
1571 1571 displaynname = nname ? "(" + nname + ")" : "";
1572 1572 }
1573 1573
1574 1574 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1575 1575 } else {
1576 1576 return '';
1577 1577 }
1578 1578 };
1579 1579
1580 1580 if(ownerAC.itemSelectEvent){
1581 1581 ownerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1582 1582
1583 1583 var myAC = aArgs[0]; // reference back to the AC instance
1584 1584 var elLI = aArgs[1]; // reference to the selected LI element
1585 1585 var oData = aArgs[2]; // object literal of selected item's result data
1586 1586 //fill the autocomplete with value
1587 1587 if (oData.nname != undefined) {
1588 1588 //users
1589 1589 //Replace the mention name with replaced
1590 1590 var re = new RegExp();
1591 1591 var org = myAC.getInputEl().value;
1592 1592 var chunks = myAC.dataSource.chunks
1593 1593 // replace middle chunk(the search term) with actuall match
1594 1594 chunks[1] = chunks[1].replace('@'+myAC.dataSource.mentionQuery,
1595 1595 '@'+oData.nname+' ');
1596 1596 myAC.getInputEl().value = chunks.join('')
1597 1597 YUD.get(myAC.getInputEl()).focus(); // Y U NO WORK !?
1598 1598 } else {
1599 1599 //groups
1600 1600 myAC.getInputEl().value = oData.grname;
1601 1601 YUD.get('perm_new_member_type').value = 'users_group';
1602 1602 }
1603 1603 });
1604 1604 }
1605 1605
1606 1606 // in this keybuffer we will gather current value of search !
1607 1607 // since we need to get this just when someone does `@` then we do the
1608 1608 // search
1609 1609 ownerAC.dataSource.chunks = [];
1610 1610 ownerAC.dataSource.mentionQuery = null;
1611 1611
1612 1612 ownerAC.get_mention = function(msg, max_pos) {
1613 1613 var org = msg;
1614 1614 var re = new RegExp('(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)$')
1615 1615 var chunks = [];
1616 1616
1617 1617
1618 1618 // cut first chunk until curret pos
1619 1619 var to_max = msg.substr(0, max_pos);
1620 1620 var at_pos = Math.max(0,to_max.lastIndexOf('@')-1);
1621 1621 var msg2 = to_max.substr(at_pos);
1622 1622
1623 1623 chunks.push(org.substr(0,at_pos))// prefix chunk
1624 1624 chunks.push(msg2) // search chunk
1625 1625 chunks.push(org.substr(max_pos)) // postfix chunk
1626 1626
1627 1627 // clean up msg2 for filtering and regex match
1628 1628 var msg2 = msg2.lstrip(' ').lstrip('\n');
1629 1629
1630 1630 if(re.test(msg2)){
1631 1631 var unam = re.exec(msg2)[1];
1632 1632 return [unam, chunks];
1633 1633 }
1634 1634 return [null, null];
1635 1635 };
1636 1636
1637 1637 if (ownerAC.textboxKeyUpEvent){
1638 1638 ownerAC.textboxKeyUpEvent.subscribe(function(type, args){
1639 1639
1640 1640 var ac_obj = args[0];
1641 1641 var currentMessage = args[1];
1642 1642 var currentCaretPosition = args[0]._elTextbox.selectionStart;
1643 1643
1644 1644 var unam = ownerAC.get_mention(currentMessage, currentCaretPosition);
1645 1645 var curr_search = null;
1646 1646 if(unam[0]){
1647 1647 curr_search = unam[0];
1648 1648 }
1649 1649
1650 1650 ownerAC.dataSource.chunks = unam[1];
1651 1651 ownerAC.dataSource.mentionQuery = curr_search;
1652 1652
1653 1653 })
1654 1654 }
1655 1655 return {
1656 1656 ownerDS: ownerDS,
1657 1657 ownerAC: ownerAC,
1658 1658 };
1659 1659 }
1660 1660
1661 1661 var addReviewMember = function(id,fname,lname,nname,gravatar_link){
1662 1662 var members = YUD.get('review_members');
1663 1663 var tmpl = '<li id="reviewer_{2}">'+
1664 1664 '<div class="reviewers_member">'+
1665 1665 '<div class="gravatar"><img alt="gravatar" src="{0}"/> </div>'+
1666 1666 '<div style="float:left">{1}</div>'+
1667 1667 '<input type="hidden" value="{2}" name="review_members" />'+
1668 1668 '<span class="delete_icon action_button" onclick="removeReviewMember({2})"></span>'+
1669 1669 '</div>'+
1670 1670 '</li>' ;
1671 1671 var displayname = "{0} {1} ({2})".format(fname,lname,nname);
1672 1672 var element = tmpl.format(gravatar_link,displayname,id);
1673 1673 // check if we don't have this ID already in
1674 1674 var ids = [];
1675 1675 var _els = YUQ('#review_members li');
1676 1676 for (el in _els){
1677 1677 ids.push(_els[el].id)
1678 1678 }
1679 1679 if(ids.indexOf('reviewer_'+id) == -1){
1680 1680 //only add if it's not there
1681 1681 members.innerHTML += element;
1682 1682 }
1683 1683
1684 1684 }
1685 1685
1686 1686 var removeReviewMember = function(reviewer_id, repo_name, pull_request_id){
1687 1687 var el = YUD.get('reviewer_{0}'.format(reviewer_id));
1688 1688 if (el.parentNode !== undefined){
1689 1689 el.parentNode.removeChild(el);
1690 1690 }
1691 1691 }
1692 1692
1693 1693 var updateReviewers = function(reviewers_ids, repo_name, pull_request_id){
1694 1694 if (reviewers_ids === undefined){
1695 1695 var reviewers_ids = [];
1696 1696 var ids = YUQ('#review_members input');
1697 1697 for(var i=0; i<ids.length;i++){
1698 1698 var id = ids[i].value
1699 1699 reviewers_ids.push(id);
1700 1700 }
1701 1701 }
1702 1702 var url = pyroutes.url('pullrequest_update', {"repo_name":repo_name,
1703 1703 "pull_request_id": pull_request_id});
1704 1704 var postData = {'_method':'put',
1705 1705 'reviewers_ids': reviewers_ids};
1706 1706 var success = function(o){
1707 1707 window.location.reload();
1708 1708 }
1709 1709 ajaxPOST(url,postData,success);
1710 1710 }
1711 1711
1712 1712 var PullRequestAutoComplete = function (divid, cont, users_list, groups_list) {
1713 1713 var myUsers = users_list;
1714 1714 var myGroups = groups_list;
1715 1715
1716 1716 // Define a custom search function for the DataSource of users
1717 1717 var matchUsers = function (sQuery) {
1718 1718 // Case insensitive matching
1719 1719 var query = sQuery.toLowerCase();
1720 1720 var i = 0;
1721 1721 var l = myUsers.length;
1722 1722 var matches = [];
1723 1723
1724 1724 // Match against each name of each contact
1725 1725 for (; i < l; i++) {
1726 1726 contact = myUsers[i];
1727 1727 if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
1728 1728 ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
1729 1729 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
1730 1730 matches[matches.length] = contact;
1731 1731 }
1732 1732 }
1733 1733 return matches;
1734 1734 };
1735 1735
1736 1736 // Define a custom search function for the DataSource of userGroups
1737 1737 var matchGroups = function (sQuery) {
1738 1738 // Case insensitive matching
1739 1739 var query = sQuery.toLowerCase();
1740 1740 var i = 0;
1741 1741 var l = myGroups.length;
1742 1742 var matches = [];
1743 1743
1744 1744 // Match against each name of each contact
1745 1745 for (; i < l; i++) {
1746 1746 matched_group = myGroups[i];
1747 1747 if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
1748 1748 matches[matches.length] = matched_group;
1749 1749 }
1750 1750 }
1751 1751 return matches;
1752 1752 };
1753 1753
1754 1754 //match all
1755 1755 var matchAll = function (sQuery) {
1756 1756 u = matchUsers(sQuery);
1757 1757 return u
1758 1758 };
1759 1759
1760 1760 // DataScheme for owner
1761 1761 var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
1762 1762
1763 1763 ownerDS.responseSchema = {
1764 1764 fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
1765 1765 };
1766 1766
1767 1767 // Instantiate AutoComplete for mentions
1768 1768 var reviewerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
1769 1769 reviewerAC.useShadow = false;
1770 1770 reviewerAC.resultTypeList = false;
1771 1771 reviewerAC.suppressInputUpdate = true;
1772 1772 reviewerAC.animVert = false;
1773 1773 reviewerAC.animHoriz = false;
1774 1774 reviewerAC.animSpeed = 0.1;
1775 1775
1776 1776 // Helper highlight function for the formatter
1777 1777 var highlightMatch = function (full, snippet, matchindex) {
1778 1778 return full.substring(0, matchindex)
1779 1779 + "<span class='match'>"
1780 1780 + full.substr(matchindex, snippet.length)
1781 1781 + "</span>" + full.substring(matchindex + snippet.length);
1782 1782 };
1783 1783
1784 1784 // Custom formatter to highlight the matching letters
1785 1785 reviewerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1786 1786 var org_sQuery = sQuery;
1787 1787 if(this.dataSource.mentionQuery != null){
1788 1788 sQuery = this.dataSource.mentionQuery;
1789 1789 }
1790 1790
1791 1791 var query = sQuery.toLowerCase();
1792 1792 var _gravatar = function(res, em, group){
1793 1793 if (group !== undefined){
1794 1794 em = '/images/icons/group.png'
1795 1795 }
1796 1796 tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
1797 1797 return tmpl.format(em,res)
1798 1798 }
1799 1799 if (oResultData.nname != undefined) {
1800 1800 var fname = oResultData.fname || "";
1801 1801 var lname = oResultData.lname || "";
1802 1802 var nname = oResultData.nname;
1803 1803
1804 1804 // Guard against null value
1805 1805 var fnameMatchIndex = fname.toLowerCase().indexOf(query),
1806 1806 lnameMatchIndex = lname.toLowerCase().indexOf(query),
1807 1807 nnameMatchIndex = nname.toLowerCase().indexOf(query),
1808 1808 displayfname, displaylname, displaynname;
1809 1809
1810 1810 if (fnameMatchIndex > -1) {
1811 1811 displayfname = highlightMatch(fname, query, fnameMatchIndex);
1812 1812 } else {
1813 1813 displayfname = fname;
1814 1814 }
1815 1815
1816 1816 if (lnameMatchIndex > -1) {
1817 1817 displaylname = highlightMatch(lname, query, lnameMatchIndex);
1818 1818 } else {
1819 1819 displaylname = lname;
1820 1820 }
1821 1821
1822 1822 if (nnameMatchIndex > -1) {
1823 1823 displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
1824 1824 } else {
1825 1825 displaynname = nname ? "(" + nname + ")" : "";
1826 1826 }
1827 1827
1828 1828 return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
1829 1829 } else {
1830 1830 return '';
1831 1831 }
1832 1832 };
1833 1833
1834 1834 //members cache to catch duplicates
1835 1835 reviewerAC.dataSource.cache = [];
1836 1836 // hack into select event
1837 1837 if(reviewerAC.itemSelectEvent){
1838 1838 reviewerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1839 1839
1840 1840 var myAC = aArgs[0]; // reference back to the AC instance
1841 1841 var elLI = aArgs[1]; // reference to the selected LI element
1842 1842 var oData = aArgs[2]; // object literal of selected item's result data
1843 1843
1844 1844 //fill the autocomplete with value
1845 1845
1846 1846 if (oData.nname != undefined) {
1847 1847 addReviewMember(oData.id, oData.fname, oData.lname, oData.nname,
1848 1848 oData.gravatar_lnk);
1849 1849 myAC.dataSource.cache.push(oData.id);
1850 1850 YUD.get('user').value = ''
1851 1851 }
1852 1852 });
1853 1853 }
1854 1854 return {
1855 1855 ownerDS: ownerDS,
1856 1856 reviewerAC: reviewerAC,
1857 1857 };
1858 1858 }
1859 1859
1860 1860 /**
1861 1861 * QUICK REPO MENU
1862 1862 */
1863 1863 var quick_repo_menu = function(){
1864 1864 YUE.on(YUQ('.quick_repo_menu'),'mouseenter',function(e){
1865 1865 var menu = e.currentTarget.firstElementChild.firstElementChild;
1866 1866 if(YUD.hasClass(menu,'hidden')){
1867 1867 YUD.replaceClass(e.currentTarget,'hidden', 'active');
1868 1868 YUD.replaceClass(menu, 'hidden', 'active');
1869 1869 }
1870 1870 })
1871 1871 YUE.on(YUQ('.quick_repo_menu'),'mouseleave',function(e){
1872 1872 var menu = e.currentTarget.firstElementChild.firstElementChild;
1873 1873 if(YUD.hasClass(menu,'active')){
1874 1874 YUD.replaceClass(e.currentTarget, 'active', 'hidden');
1875 1875 YUD.replaceClass(menu, 'active', 'hidden');
1876 1876 }
1877 1877 })
1878 1878 };
1879 1879
1880 1880
1881 1881 /**
1882 1882 * TABLE SORTING
1883 1883 */
1884 1884
1885 1885 // returns a node from given html;
1886 1886 var fromHTML = function(html){
1887 1887 var _html = document.createElement('element');
1888 1888 _html.innerHTML = html;
1889 1889 return _html;
1890 1890 }
1891 1891 var get_rev = function(node){
1892 1892 var n = node.firstElementChild.firstElementChild;
1893 1893
1894 1894 if (n===null){
1895 1895 return -1
1896 1896 }
1897 1897 else{
1898 1898 out = n.firstElementChild.innerHTML.split(':')[0].replace('r','');
1899 1899 return parseInt(out);
1900 1900 }
1901 1901 }
1902 1902
1903 1903 var get_name = function(node){
1904 1904 var name = node.firstElementChild.children[2].innerHTML;
1905 1905 return name
1906 1906 }
1907 1907 var get_group_name = function(node){
1908 1908 var name = node.firstElementChild.children[1].innerHTML;
1909 1909 return name
1910 1910 }
1911 1911 var get_date = function(node){
1912 1912 var date_ = YUD.getAttribute(node.firstElementChild,'date');
1913 1913 return date_
1914 1914 }
1915 1915
1916 1916 var get_age = function(node){
1917 1917 return node
1918 1918 }
1919 1919
1920 1920 var get_link = function(node){
1921 1921 return node.firstElementChild.text;
1922 1922 }
1923 1923
1924 1924 var revisionSort = function(a, b, desc, field) {
1925 1925
1926 1926 var a_ = fromHTML(a.getData(field));
1927 1927 var b_ = fromHTML(b.getData(field));
1928 1928
1929 1929 // extract revisions from string nodes
1930 1930 a_ = get_rev(a_)
1931 1931 b_ = get_rev(b_)
1932 1932
1933 1933 var comp = YAHOO.util.Sort.compare;
1934 1934 var compState = comp(a_, b_, desc);
1935 1935 return compState;
1936 1936 };
1937 1937 var ageSort = function(a, b, desc, field) {
1938 1938 var a_ = fromHTML(a.getData(field));
1939 1939 var b_ = fromHTML(b.getData(field));
1940 1940
1941 1941 // extract name from table
1942 1942 a_ = get_date(a_)
1943 1943 b_ = get_date(b_)
1944 1944
1945 1945 var comp = YAHOO.util.Sort.compare;
1946 1946 var compState = comp(a_, b_, desc);
1947 1947 return compState;
1948 1948 };
1949 1949
1950 1950 var lastLoginSort = function(a, b, desc, field) {
1951 1951 var a_ = a.getData('last_login_raw') || 0;
1952 1952 var b_ = b.getData('last_login_raw') || 0;
1953 1953
1954 1954 var comp = YAHOO.util.Sort.compare;
1955 1955 var compState = comp(a_, b_, desc);
1956 1956 return compState;
1957 1957 };
1958 1958
1959 1959 var nameSort = function(a, b, desc, field) {
1960 1960 var a_ = fromHTML(a.getData(field));
1961 1961 var b_ = fromHTML(b.getData(field));
1962 1962
1963 1963 // extract name from table
1964 1964 a_ = get_name(a_)
1965 1965 b_ = get_name(b_)
1966 1966
1967 1967 var comp = YAHOO.util.Sort.compare;
1968 1968 var compState = comp(a_, b_, desc);
1969 1969 return compState;
1970 1970 };
1971 1971
1972 1972 var permNameSort = function(a, b, desc, field) {
1973 1973 var a_ = fromHTML(a.getData(field));
1974 1974 var b_ = fromHTML(b.getData(field));
1975 1975 // extract name from table
1976 1976
1977 1977 a_ = a_.children[0].innerHTML;
1978 1978 b_ = b_.children[0].innerHTML;
1979 1979
1980 1980 var comp = YAHOO.util.Sort.compare;
1981 1981 var compState = comp(a_, b_, desc);
1982 1982 return compState;
1983 1983 };
1984 1984
1985 1985 var groupNameSort = function(a, b, desc, field) {
1986 1986 var a_ = fromHTML(a.getData(field));
1987 1987 var b_ = fromHTML(b.getData(field));
1988 1988
1989 1989 // extract name from table
1990 1990 a_ = get_group_name(a_)
1991 1991 b_ = get_group_name(b_)
1992 1992
1993 1993 var comp = YAHOO.util.Sort.compare;
1994 1994 var compState = comp(a_, b_, desc);
1995 1995 return compState;
1996 1996 };
1997 1997 var dateSort = function(a, b, desc, field) {
1998 1998 var a_ = fromHTML(a.getData(field));
1999 1999 var b_ = fromHTML(b.getData(field));
2000 2000
2001 2001 // extract name from table
2002 2002 a_ = get_date(a_)
2003 2003 b_ = get_date(b_)
2004 2004
2005 2005 var comp = YAHOO.util.Sort.compare;
2006 2006 var compState = comp(a_, b_, desc);
2007 2007 return compState;
2008 2008 };
2009 2009
2010 2010 var usernamelinkSort = function(a, b, desc, field) {
2011 2011 var a_ = fromHTML(a.getData(field));
2012 2012 var b_ = fromHTML(b.getData(field));
2013 2013
2014 2014 // extract url text from string nodes
2015 2015 a_ = get_link(a_)
2016 2016 b_ = get_link(b_)
2017 2017 var comp = YAHOO.util.Sort.compare;
2018 2018 var compState = comp(a_, b_, desc);
2019 2019 return compState;
2020 2020 }
2021 2021
2022 2022 var addPermAction = function(_html, users_list, groups_list){
2023 2023 var elmts = YUD.getElementsByClassName('last_new_member');
2024 2024 var last_node = elmts[elmts.length-1];
2025 2025 if (last_node){
2026 2026 var next_id = (YUD.getElementsByClassName('new_members')).length;
2027 2027 _html = _html.format(next_id);
2028 2028 last_node.innerHTML = _html;
2029 2029 YUD.setStyle(last_node, 'display', '');
2030 2030 YUD.removeClass(last_node, 'last_new_member');
2031 2031 MembersAutoComplete("perm_new_member_name_"+next_id,
2032 2032 "perm_container_"+next_id, users_list, groups_list);
2033 2033 //create new last NODE
2034 2034 var el = document.createElement('tr');
2035 2035 el.id = 'add_perm_input';
2036 2036 YUD.addClass(el,'last_new_member');
2037 2037 YUD.addClass(el,'new_members');
2038 2038 YUD.insertAfter(el, last_node);
2039 2039 }
2040 2040 }
2041 2041 function ajaxActionRevokePermission(url, obj_id, obj_type, field_id, extra_data) {
2042 2042 var callback = {
2043 2043 success: function (o) {
2044 2044 var tr = YUD.get(String(field_id));
2045 2045 tr.parentNode.removeChild(tr);
2046 2046 },
2047 2047 failure: function (o) {
2048 2048 alert(_TM['Failed to remoke permission'] + ": " + o.status);
2049 2049 },
2050 2050 };
2051 2051 query_params = {
2052 2052 '_method': 'delete'
2053 2053 }
2054 2054 // put extra data into POST
2055 2055 if (extra_data !== undefined && (typeof extra_data === 'object')){
2056 2056 for(k in extra_data){
2057 2057 query_params[k] = extra_data[k];
2058 2058 }
2059 2059 }
2060 2060
2061 2061 if (obj_type=='user'){
2062 2062 query_params['user_id'] = obj_id;
2063 2063 query_params['obj_type'] = 'user';
2064 2064 }
2065 2065 else if (obj_type=='user_group'){
2066 2066 query_params['user_group_id'] = obj_id;
2067 2067 query_params['obj_type'] = 'user_group';
2068 2068 }
2069 2069
2070 2070 var request = YAHOO.util.Connect.asyncRequest('POST', url, callback,
2071 2071 toQueryString(query_params));
2072 2072 };
2073 2073 /* Multi selectors */
2074 2074
2075 2075 var MultiSelectWidget = function(selected_id, available_id, form_id){
2076 2076
2077 2077
2078 2078 //definition of containers ID's
2079 2079 var selected_container = selected_id;
2080 2080 var available_container = available_id;
2081 2081
2082 2082 //temp container for selected storage.
2083 2083 var cache = new Array();
2084 2084 var av_cache = new Array();
2085 2085 var c = YUD.get(selected_container);
2086 2086 var ac = YUD.get(available_container);
2087 2087
2088 2088 //get only selected options for further fullfilment
2089 2089 for(var i = 0;node =c.options[i];i++){
2090 2090 if(node.selected){
2091 2091 //push selected to my temp storage left overs :)
2092 2092 cache.push(node);
2093 2093 }
2094 2094 }
2095 2095
2096 2096 //get all available options to cache
2097 2097 for(var i = 0;node =ac.options[i];i++){
2098 2098 //push selected to my temp storage left overs :)
2099 2099 av_cache.push(node);
2100 2100 }
2101 2101
2102 2102 //fill available only with those not in chosen
2103 2103 ac.options.length=0;
2104 2104 tmp_cache = new Array();
2105 2105
2106 2106 for(var i = 0;node = av_cache[i];i++){
2107 2107 var add = true;
2108 2108 for(var i2 = 0;node_2 = cache[i2];i2++){
2109 2109 if(node.value == node_2.value){
2110 2110 add=false;
2111 2111 break;
2112 2112 }
2113 2113 }
2114 2114 if(add){
2115 2115 tmp_cache.push(new Option(node.text, node.value, false, false));
2116 2116 }
2117 2117 }
2118 2118
2119 2119 for(var i = 0;node = tmp_cache[i];i++){
2120 2120 ac.options[i] = node;
2121 2121 }
2122 2122
2123 2123 function prompts_action_callback(e){
2124 2124
2125 2125 var chosen = YUD.get(selected_container);
2126 2126 var available = YUD.get(available_container);
2127 2127
2128 2128 //get checked and unchecked options from field
2129 2129 function get_checked(from_field){
2130 2130 //temp container for storage.
2131 2131 var sel_cache = new Array();
2132 2132 var oth_cache = new Array();
2133 2133
2134 2134 for(var i = 0;node = from_field.options[i];i++){
2135 2135 if(node.selected){
2136 2136 //push selected fields :)
2137 2137 sel_cache.push(node);
2138 2138 }
2139 2139 else{
2140 2140 oth_cache.push(node)
2141 2141 }
2142 2142 }
2143 2143
2144 2144 return [sel_cache,oth_cache]
2145 2145 }
2146 2146
2147 2147 //fill the field with given options
2148 2148 function fill_with(field,options){
2149 2149 //clear firtst
2150 2150 field.options.length=0;
2151 2151 for(var i = 0;node = options[i];i++){
2152 2152 field.options[i]=new Option(node.text, node.value,
2153 2153 false, false);
2154 2154 }
2155 2155
2156 2156 }
2157 2157 //adds to current field
2158 2158 function add_to(field,options){
2159 2159 for(var i = 0;node = options[i];i++){
2160 2160 field.appendChild(new Option(node.text, node.value,
2161 2161 false, false));
2162 2162 }
2163 2163 }
2164 2164
2165 2165 // add action
2166 2166 if (this.id=='add_element'){
2167 2167 var c = get_checked(available);
2168 2168 add_to(chosen,c[0]);
2169 2169 fill_with(available,c[1]);
2170 2170 }
2171 2171 // remove action
2172 2172 if (this.id=='remove_element'){
2173 2173 var c = get_checked(chosen);
2174 2174 add_to(available,c[0]);
2175 2175 fill_with(chosen,c[1]);
2176 2176 }
2177 2177 // add all elements
2178 2178 if(this.id=='add_all_elements'){
2179 2179 for(var i=0; node = available.options[i];i++){
2180 2180 chosen.appendChild(new Option(node.text,
2181 2181 node.value, false, false));
2182 2182 }
2183 2183 available.options.length = 0;
2184 2184 }
2185 2185 //remove all elements
2186 2186 if(this.id=='remove_all_elements'){
2187 2187 for(var i=0; node = chosen.options[i];i++){
2188 2188 available.appendChild(new Option(node.text,
2189 2189 node.value, false, false));
2190 2190 }
2191 2191 chosen.options.length = 0;
2192 2192 }
2193 2193
2194 2194 }
2195 2195
2196 2196 YUE.addListener(['add_element','remove_element',
2197 2197 'add_all_elements','remove_all_elements'],'click',
2198 2198 prompts_action_callback)
2199 2199 if (form_id !== undefined) {
2200 2200 YUE.addListener(form_id,'submit',function(){
2201 2201 var chosen = YUD.get(selected_container);
2202 2202 for (var i = 0; i < chosen.options.length; i++) {
2203 2203 chosen.options[i].selected = 'selected';
2204 2204 }
2205 2205 });
2206 2206 }
2207 2207 }
2208 2208
2209
2210
2209 // custom paginator
2210 var YUI_paginator = function(links_per_page, containers){
2211 2211
2212 var YUI_paginator = function(links_per_page, containers){
2213 // my custom paginator
2214 2212 (function () {
2215 2213
2216 2214 var Paginator = YAHOO.widget.Paginator,
2217 2215 l = YAHOO.lang,
2218 2216 setId = YAHOO.util.Dom.generateId;
2219 2217
2220 2218 Paginator.ui.MyFirstPageLink = function (p) {
2221 2219 this.paginator = p;
2222 2220
2223 2221 p.subscribe('recordOffsetChange',this.update,this,true);
2224 2222 p.subscribe('rowsPerPageChange',this.update,this,true);
2225 2223 p.subscribe('totalRecordsChange',this.update,this,true);
2226 2224 p.subscribe('destroy',this.destroy,this,true);
2227 2225
2228 2226 // TODO: make this work
2229 2227 p.subscribe('firstPageLinkLabelChange',this.update,this,true);
2230 2228 p.subscribe('firstPageLinkClassChange',this.update,this,true);
2231 2229 };
2232 2230
2233 2231 Paginator.ui.MyFirstPageLink.init = function (p) {
2234 2232 p.setAttributeConfig('firstPageLinkLabel', {
2235 2233 value : 1,
2236 2234 validator : l.isString
2237 2235 });
2238 2236 p.setAttributeConfig('firstPageLinkClass', {
2239 2237 value : 'yui-pg-first',
2240 2238 validator : l.isString
2241 2239 });
2242 2240 p.setAttributeConfig('firstPageLinkTitle', {
2243 2241 value : 'First Page',
2244 2242 validator : l.isString
2245 2243 });
2246 2244 };
2247 2245
2248 2246 // Instance members and methods
2249 2247 Paginator.ui.MyFirstPageLink.prototype = {
2250 2248 current : null,
2251 2249 leftmost_page: null,
2252 2250 rightmost_page: null,
2253 2251 link : null,
2254 2252 span : null,
2255 2253 dotdot : null,
2256 2254 getPos : function(cur_page, max_page, items){
2257 2255 var edge = parseInt(items / 2) + 1;
2258 2256 if (cur_page <= edge){
2259 2257 var radius = Math.max(parseInt(items / 2), items - cur_page);
2260 2258 }
2261 2259 else if ((max_page - cur_page) < edge) {
2262 2260 var radius = (items - 1) - (max_page - cur_page);
2263 2261 }
2264 2262 else{
2265 2263 var radius = parseInt(items / 2);
2266 2264 }
2267 2265
2268 2266 var left = Math.max(1, (cur_page - (radius)))
2269 2267 var right = Math.min(max_page, cur_page + (radius))
2270 2268 return [left, cur_page, right]
2271 2269 },
2272 2270 render : function (id_base) {
2273 2271 var p = this.paginator,
2274 2272 c = p.get('firstPageLinkClass'),
2275 2273 label = p.get('firstPageLinkLabel'),
2276 2274 title = p.get('firstPageLinkTitle');
2277 2275
2278 2276 this.link = document.createElement('a');
2279 this.span = document.createElement();
2277 this.span = document.createElement('span');
2278 YUD.setStyle(this.span, 'display', 'none');
2280 2279
2281 2280 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2282 2281 this.leftmost_page = _pos[0];
2283 2282 this.rightmost_page = _pos[2];
2284 2283
2285 2284 setId(this.link, id_base + '-first-link');
2286 2285 this.link.href = '#';
2287 2286 this.link.className = c;
2288 2287 this.link.innerHTML = label;
2289 2288 this.link.title = title;
2290 2289 YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
2291 2290
2292 2291 setId(this.span, id_base + '-first-span');
2293 2292 this.span.className = c;
2294 2293 this.span.innerHTML = label;
2295 2294
2296 2295 this.current = p.getCurrentPage() > 1 ? this.link : this.span;
2297 2296 return this.current;
2298 2297 },
2299 2298 update : function (e) {
2300 2299 var p = this.paginator;
2301 2300 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2302 2301 this.leftmost_page = _pos[0];
2303 2302 this.rightmost_page = _pos[2];
2304 2303
2305 2304 if (e && e.prevValue === e.newValue) {
2306 2305 return;
2307 2306 }
2308 2307
2309 2308 var par = this.current ? this.current.parentNode : null;
2310 2309 if (this.leftmost_page > 1) {
2311 2310 if (par && this.current === this.span) {
2312 2311 par.replaceChild(this.link,this.current);
2313 2312 this.current = this.link;
2314 2313 }
2315 2314 } else {
2316 2315 if (par && this.current === this.link) {
2317 2316 par.replaceChild(this.span,this.current);
2318 2317 this.current = this.span;
2319 2318 }
2320 2319 }
2321 2320 },
2322 2321 destroy : function () {
2323 2322 YAHOO.util.Event.purgeElement(this.link);
2324 2323 this.current.parentNode.removeChild(this.current);
2325 2324 this.link = this.span = null;
2326 2325 },
2327 2326 onClick : function (e) {
2328 2327 YAHOO.util.Event.stopEvent(e);
2329 2328 this.paginator.setPage(1);
2330 2329 }
2331 2330 };
2332 2331
2333 2332 })();
2334 2333 (function () {
2335 2334
2336 2335 var Paginator = YAHOO.widget.Paginator,
2337 2336 l = YAHOO.lang,
2338 2337 setId = YAHOO.util.Dom.generateId;
2339 2338
2340 2339 Paginator.ui.MyLastPageLink = function (p) {
2341 2340 this.paginator = p;
2342 2341
2343 2342 p.subscribe('recordOffsetChange',this.update,this,true);
2344 2343 p.subscribe('rowsPerPageChange',this.update,this,true);
2345 2344 p.subscribe('totalRecordsChange',this.update,this,true);
2346 2345 p.subscribe('destroy',this.destroy,this,true);
2347 2346
2348 2347 // TODO: make this work
2349 2348 p.subscribe('lastPageLinkLabelChange',this.update,this,true);
2350 2349 p.subscribe('lastPageLinkClassChange', this.update,this,true);
2351 2350 };
2352 2351
2353 2352 Paginator.ui.MyLastPageLink.init = function (p) {
2354 2353 p.setAttributeConfig('lastPageLinkLabel', {
2355 2354 value : -1,
2356 2355 validator : l.isString
2357 2356 });
2358 2357 p.setAttributeConfig('lastPageLinkClass', {
2359 2358 value : 'yui-pg-last',
2360 2359 validator : l.isString
2361 2360 });
2362 2361 p.setAttributeConfig('lastPageLinkTitle', {
2363 2362 value : 'Last Page',
2364 2363 validator : l.isString
2365 2364 });
2366 2365
2367 2366 };
2368 2367
2369 2368 Paginator.ui.MyLastPageLink.prototype = {
2370 2369
2371 2370 current : null,
2372 2371 leftmost_page: null,
2373 2372 rightmost_page: null,
2374 2373 link : null,
2375 2374 span : null,
2376 2375 dotdot : null,
2377 2376 na : null,
2378 2377 getPos : function(cur_page, max_page, items){
2379 2378 var edge = parseInt(items / 2) + 1;
2380 2379 if (cur_page <= edge){
2381 2380 var radius = Math.max(parseInt(items / 2), items - cur_page);
2382 2381 }
2383 2382 else if ((max_page - cur_page) < edge) {
2384 2383 var radius = (items - 1) - (max_page - cur_page);
2385 2384 }
2386 2385 else{
2387 2386 var radius = parseInt(items / 2);
2388 2387 }
2389 2388
2390 2389 var left = Math.max(1, (cur_page - (radius)))
2391 2390 var right = Math.min(max_page, cur_page + (radius))
2392 2391 return [left, cur_page, right]
2393 2392 },
2394 2393 render : function (id_base) {
2395 2394 var p = this.paginator,
2396 2395 c = p.get('lastPageLinkClass'),
2397 2396 label = p.get('lastPageLinkLabel'),
2398 2397 last = p.getTotalPages(),
2399 2398 title = p.get('lastPageLinkTitle');
2400 2399
2401 2400 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2402 2401 this.leftmost_page = _pos[0];
2403 2402 this.rightmost_page = _pos[2];
2404 2403
2405 2404 this.link = document.createElement('a');
2406 this.span = document.createElement();
2405 this.span = document.createElement('span');
2406 YUD.setStyle(this.span, 'display', 'none');
2407
2407 2408 this.na = this.span.cloneNode(false);
2408 2409
2409 2410 setId(this.link, id_base + '-last-link');
2410 2411 this.link.href = '#';
2411 2412 this.link.className = c;
2412 2413 this.link.innerHTML = label;
2413 2414 this.link.title = title;
2414 2415 YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
2415 2416
2416 2417 setId(this.span, id_base + '-last-span');
2417 2418 this.span.className = c;
2418 2419 this.span.innerHTML = label;
2419 2420
2420 2421 setId(this.na, id_base + '-last-na');
2421 2422
2422 2423 if (this.rightmost_page < p.getTotalPages()){
2423 2424 this.current = this.link;
2424 2425 }
2425 2426 else{
2426 2427 this.current = this.span;
2427 2428 }
2428 2429
2429 2430 this.current.innerHTML = p.getTotalPages();
2430 2431 return this.current;
2431 2432 },
2432 2433
2433 2434 update : function (e) {
2434 2435 var p = this.paginator;
2435 2436
2436 2437 var _pos = this.getPos(p.getCurrentPage(), p.getTotalPages(), 5);
2437 2438 this.leftmost_page = _pos[0];
2438 2439 this.rightmost_page = _pos[2];
2439 2440
2440 2441 if (e && e.prevValue === e.newValue) {
2441 2442 return;
2442 2443 }
2443 2444
2444 2445 var par = this.current ? this.current.parentNode : null,
2445 2446 after = this.link;
2446 2447 if (par) {
2447 2448
2448 2449 // only show the last page if the rightmost one is
2449 2450 // lower, so we don't have doubled entries at the end
2450 2451 if (!(this.rightmost_page < p.getTotalPages())){
2451 2452 after = this.span
2452 2453 }
2453 2454
2454 2455 if (this.current !== after) {
2455 2456 par.replaceChild(after,this.current);
2456 2457 this.current = after;
2457 2458 }
2458 2459 }
2459 2460 this.current.innerHTML = this.paginator.getTotalPages();
2460 2461
2461 2462 },
2462 2463 destroy : function () {
2463 2464 YAHOO.util.Event.purgeElement(this.link);
2464 2465 this.current.parentNode.removeChild(this.current);
2465 2466 this.link = this.span = null;
2466 2467 },
2467 2468 onClick : function (e) {
2468 2469 YAHOO.util.Event.stopEvent(e);
2469 2470 this.paginator.setPage(this.paginator.getTotalPages());
2470 2471 }
2471 2472 };
2472 2473
2473 2474 })();
2474 2475
2475 2476 var pagi = new YAHOO.widget.Paginator({
2476 2477 rowsPerPage: links_per_page,
2477 2478 alwaysVisible: false,
2478 2479 template : "{PreviousPageLink} {MyFirstPageLink} {PageLinks} {MyLastPageLink} {NextPageLink}",
2479 2480 pageLinks: 5,
2480 2481 containerClass: 'pagination-wh',
2481 2482 currentPageClass: 'pager_curpage',
2482 2483 pageLinkClass: 'pager_link',
2483 2484 nextPageLinkLabel: '&gt;',
2484 2485 previousPageLinkLabel: '&lt;',
2485 2486 containers:containers
2486 2487 })
2487 2488
2488 2489 return pagi
2489 2490 }
2490 2491
2491 2492
2492 2493
2493 2494 // global hooks after DOM is loaded
2494 2495
2495 2496 YUE.onDOMReady(function(){
2496 2497 YUE.on(YUQ('.diff-collapse-button'), 'click', function(e){
2497 2498 var button = e.currentTarget;
2498 2499 var t = YUD.get(button).getAttribute('target');
2499 2500 console.log(t);
2500 2501 if(YUD.hasClass(t, 'hidden')){
2501 2502 YUD.removeClass(t, 'hidden');
2502 2503 YUD.get(button).innerHTML = "&uarr; {0} &uarr;".format(_TM['Collapse diff']);
2503 2504 }
2504 2505 else if(!YUD.hasClass(t, 'hidden')){
2505 2506 YUD.addClass(t, 'hidden');
2506 2507 YUD.get(button).innerHTML = "&darr; {0} &darr;".format(_TM['Expand diff']);
2507 2508 }
2508 2509 });
2509 2510
2510 2511
2511 2512
2512 2513 });
General Comments 0
You need to be logged in to leave comments. Login now