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