[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 /* jshint undef: false, unused:false */ 2 /* @version 1.7.0 */ 3 /* @version 8.0.0 */ 4 // AJAX Functions 5 var jq = jQuery; 6 7 // Global variable to prevent multiple AJAX requests 8 var bp_ajax_request = null; 9 10 // Global variables to temporarily store newest activities 11 var newest_activities = ''; 12 var activity_last_recorded = 0; 13 14 var directoryPreferences = {}; 15 16 jq( function() { 17 var activity_oldestpage = 1; 18 19 /**** Page Load Actions *******************************************************/ 20 21 /* Activity filter and scope set */ 22 bp_init_activity(); 23 24 var objects = [ 'members', 'groups', 'blogs', 'group_members' ], 25 $whats_new = jq('#whats-new'); 26 27 /* Object filter and scope set. */ 28 bp_init_objects( objects ); 29 30 /* @mention Compose Scrolling */ 31 if ( $whats_new.length && bp_get_querystring('r') ) { 32 var $member_nicename = $whats_new.val(); 33 34 jq('#whats-new-options').slideDown(); 35 36 $whats_new.animate({ 37 height:'3.8em' 38 }); 39 40 jq.scrollTo( $whats_new, 500, { 41 offset:-125, 42 easing:'swing' 43 } ); 44 45 $whats_new.val('').trigger( 'focus' ).val( $member_nicename ); 46 } else { 47 jq('#whats-new-options').hide(); 48 } 49 50 /**** Activity Posting ********************************************************/ 51 52 /* Textarea focus */ 53 $whats_new.on( 'focus', function() { 54 jq( '#whats-new-options' ).slideDown(); 55 56 jq( this ).animate({ 57 height:'3.8em' 58 }); 59 60 jq('#aw-whats-new-submit').prop('disabled', false); 61 62 jq( this ).parent().addClass( 'active' ); 63 jq( '#whats-new-content' ).addClass( 'active' ); 64 65 var $whats_new_form = jq('form#whats-new-form'), 66 $activity_all = jq( '#activity-all' ); 67 68 if ( $whats_new_form.hasClass('submitted') ) { 69 $whats_new_form.removeClass('submitted'); 70 } 71 72 // Return to the 'All Members' tab and 'Everything' filter, 73 // to avoid inconsistencies with the heartbeat integration 74 if ( $activity_all.length ) { 75 if ( ! $activity_all.hasClass( 'selected' ) ) { 76 // reset to everything 77 jq( '#activity-filter-select select' ).val( '-1' ); 78 $activity_all.children( 'a' ).trigger( 'click' ); 79 } else if ( '-1' !== jq( '#activity-filter-select select' ).val() ) { 80 jq( '#activity-filter-select select' ).val( '-1' ); 81 jq( '#activity-filter-select select' ).trigger( 'change' ); 82 } 83 } 84 } ); 85 86 /* For the "What's New" form, do the following on focusout. */ 87 jq( '#whats-new-form' ).on( 'focusout', function( e ) { 88 var elem = jq( this ); 89 90 // Let child hover actions passthrough. 91 // This allows click events to go through without focusout. 92 setTimeout( function () { 93 if ( ! elem.find(':hover').length ) { 94 // Do not slide up if textarea has content. 95 if ( '' !== $whats_new.val() ) { 96 return; 97 } 98 99 $whats_new.animate({ 100 height:'2.2em' 101 }); 102 103 jq( '#whats-new-options' ).slideUp(); 104 105 jq('#aw-whats-new-submit').prop( 'disabled', true ); 106 107 jq( '#whats-new-content' ).removeClass( 'active' ); 108 $whats_new.parent().removeClass( 'active' ); 109 } 110 }, 0 ); 111 } ); 112 113 /* New posts */ 114 jq('#aw-whats-new-submit').on( 'click', function() { 115 var last_date_recorded = 0, 116 button = jq(this), 117 form = button.closest('form#whats-new-form'), 118 inputs = {}, post_data; 119 120 // Get all inputs and organize them into an object {name: value} 121 jq.each( form.serializeArray(), function( key, input ) { 122 // Only include public extra data 123 if ( '_' !== input.name.substr( 0, 1 ) && 'whats-new' !== input.name.substr( 0, 9 ) ) { 124 if ( ! inputs[ input.name ] ) { 125 inputs[ input.name ] = input.value; 126 } else { 127 // Checkboxes/dropdown list can have multiple selected value 128 if ( ! Array.isArray( inputs[ input.name ] ) ) { 129 inputs[ input.name ] = new Array( inputs[ input.name ], input.value ); 130 } else { 131 inputs[ input.name ].push( input.value ); 132 } 133 } 134 } 135 } ); 136 137 form.find( '*' ).each( function( i, elem ) { 138 if ( elem.nodeName.toLowerCase() === 'textarea' || elem.nodeName.toLowerCase() ==='input' ) { 139 jq( elem ).prop( 'disabled', true ); 140 } 141 } ); 142 143 /* Remove any errors */ 144 jq('div.error').remove(); 145 button.addClass('loading'); 146 button.prop('disabled', true); 147 form.addClass('submitted'); 148 149 /* Default POST values */ 150 object = ''; 151 item_id = jq('#whats-new-post-in').val(); 152 content = jq('#whats-new').val(); 153 firstrow = jq( '#buddypress ul.activity-list li' ).first(); 154 activity_row = firstrow; 155 timestamp = null; 156 157 // Checks if at least one activity exists 158 if ( firstrow.length ) { 159 160 if ( activity_row.hasClass( 'load-newest' ) ) { 161 activity_row = firstrow.next(); 162 } 163 164 timestamp = activity_row.prop( 'class' ).match( /date-recorded-([0-9]+)/ ); 165 } 166 167 if ( timestamp ) { 168 last_date_recorded = timestamp[1]; 169 } 170 171 /* Set object for non-profile posts */ 172 if ( item_id > 0 ) { 173 object = jq('#whats-new-post-object').val(); 174 } 175 176 post_data = jq.extend( { 177 action: 'post_update', 178 'cookie': bp_get_cookies(), 179 '_wpnonce_post_update': jq('#_wpnonce_post_update').val(), 180 'content': content, 181 'object': object, 182 'item_id': item_id, 183 'since': last_date_recorded, 184 '_bp_as_nonce': jq('#_bp_as_nonce').val() || '' 185 }, inputs ); 186 187 jq.post( ajaxurl, post_data, function( response ) { 188 form.find( '*' ).each( function( i, elem ) { 189 if ( elem.nodeName.toLowerCase() === 'textarea' || elem.nodeName.toLowerCase() ==='input' ) { 190 jq( elem ).prop( 'disabled', false ); 191 } 192 } ); 193 194 /* Check for errors and append if found. */ 195 if ( response[0] + response[1] === '-1' ) { 196 form.prepend( response.substr( 2, response.length ) ); 197 jq( '#' + form.attr('id') + ' div.error').hide().fadeIn( 200 ); 198 } else { 199 if ( 0 === jq('ul.activity-list').length ) { 200 jq('div.error').slideUp(100).remove(); 201 jq('#message').slideUp(100).remove(); 202 jq('div.activity').append( '<ul id="activity-stream" class="activity-list item-list">' ); 203 } 204 205 if ( firstrow.hasClass( 'load-newest' ) ) { 206 firstrow.remove(); 207 } 208 209 jq('#activity-stream').prepend(response); 210 211 if ( ! last_date_recorded ) { 212 jq('#activity-stream li:first').addClass('new-update just-posted'); 213 } 214 215 if ( 0 !== jq('#latest-update').length ) { 216 var l = jq('#activity-stream li.new-update .activity-content .activity-inner p').html(), 217 v = jq('#activity-stream li.new-update .activity-content .activity-header p a.view').attr('href'), 218 ltext = jq('#activity-stream li.new-update .activity-content .activity-inner p').text(), 219 u = ''; 220 221 if ( ltext !== '' ) { 222 u = l + ' '; 223 } 224 225 u += '<a href="' + v + '" rel="nofollow">' + BP_DTheme.view + '</a>'; 226 227 jq('#latest-update').slideUp(300,function(){ 228 jq('#latest-update').html( u ); 229 jq('#latest-update').slideDown(300); 230 }); 231 } 232 233 jq('li.new-update').hide().slideDown( 300 ); 234 jq('li.new-update').removeClass( 'new-update' ); 235 jq('#whats-new').val(''); 236 form.get(0).reset(); 237 238 // reset vars to get newest activities 239 newest_activities = ''; 240 activity_last_recorded = 0; 241 } 242 243 jq('#whats-new-options').slideUp(); 244 jq('#whats-new-form textarea').animate({ 245 height:'2.2em' 246 }); 247 jq('#aw-whats-new-submit').prop('disabled', true).removeClass('loading'); 248 jq( '#whats-new-content' ).removeClass( 'active' ); 249 }); 250 251 return false; 252 }); 253 254 /* List tabs event delegation */ 255 jq('div.activity-type-tabs').on( 'click', function(event) { 256 var target = jq(event.target).parent(), 257 scope, filter; 258 259 if ( event.target.nodeName === 'STRONG' || event.target.nodeName === 'SPAN' ) { 260 target = target.parent(); 261 } else if ( event.target.nodeName !== 'A' ) { 262 return false; 263 } 264 265 /* Activity Stream Tabs */ 266 scope = target.attr('id').substr( 9, target.attr('id').length ); 267 filter = jq('#activity-filter-select select').val(); 268 269 if ( scope === 'mentions' ) { 270 jq( '#' + target.attr('id') + ' a strong' ).remove(); 271 } 272 273 bp_activity_request(scope, filter); 274 275 return false; 276 }); 277 278 /* Activity filter select */ 279 jq( '#activity-filter-select select' ).on( 'change', function() { 280 var selected_tab = jq( 'div.activity-type-tabs li.selected' ), 281 filter = jq(this).val(), 282 scope; 283 284 if ( !selected_tab.length ) { 285 scope = null; 286 } else { 287 scope = selected_tab.attr('id').substr( 9, selected_tab.attr('id').length ); 288 } 289 290 bp_activity_request(scope, filter); 291 292 return false; 293 } ); 294 295 /* Stream event delegation */ 296 jq('div.activity').on( 'click', function(event) { 297 var target = jq(event.target), 298 type, parent, parent_id, 299 li, id, link_href, nonce, timestamp, 300 oldest_page, just_posted; 301 302 /* Favoriting activity stream items */ 303 if ( target.hasClass('fav') || target.hasClass('unfav') ) { 304 /* Bail if a request is in progress */ 305 if ( target.hasClass( 'loading' ) ) { 306 return false; 307 } 308 309 type = target.hasClass('fav') ? 'fav' : 'unfav'; 310 parent = target.closest('.activity-item'); 311 parent_id = parent.attr('id').substr( 9, parent.attr('id').length ); 312 nonce = bp_get_query_var( '_wpnonce', target.attr( 'href' ) ); 313 314 target.addClass('loading'); 315 316 jq.post( ajaxurl, { 317 action: 'activity_mark_' + type, 318 'cookie': bp_get_cookies(), 319 'id': parent_id, 320 nonce: nonce 321 }, 322 function(response) { 323 target.removeClass('loading'); 324 325 target.fadeOut( 200, function() { 326 jq(this).html(response); 327 jq(this).attr('title', 'fav' === type ? BP_DTheme.remove_fav : BP_DTheme.mark_as_fav); 328 jq(this).fadeIn(200); 329 }); 330 331 if ( 'fav' === type ) { 332 if ( !jq('.item-list-tabs #activity-favs-personal-li').length ) { 333 if ( !jq('.item-list-tabs #activity-favorites').length ) { 334 jq('.item-list-tabs ul #activity-mentions').before( '<li id="activity-favorites"><a href="#">' + BP_DTheme.my_favs + ' <span>0</span></a></li>'); 335 } 336 337 jq('.item-list-tabs ul #activity-favorites span').html( Number( jq('.item-list-tabs ul #activity-favorites span').html() ) + 1 ); 338 } 339 340 target.removeClass('fav'); 341 target.addClass('unfav'); 342 343 } else { 344 target.removeClass('unfav'); 345 target.addClass('fav'); 346 347 jq('.item-list-tabs ul #activity-favorites span').html( Number( jq('.item-list-tabs ul #activity-favorites span').html() ) - 1 ); 348 349 if ( !Number( jq('.item-list-tabs ul #activity-favorites span').html() ) ) { 350 if ( jq('.item-list-tabs ul #activity-favorites').hasClass('selected') ) { 351 bp_activity_request( null, null ); 352 } 353 354 jq('.item-list-tabs ul #activity-favorites').remove(); 355 } 356 } 357 358 if ( 'activity-favorites' === jq( '.item-list-tabs li.selected').attr('id') ) { 359 target.closest( '.activity-item' ).slideUp( 100 ); 360 } 361 }); 362 363 return false; 364 } 365 366 /* Delete activity stream items */ 367 if ( target.hasClass('delete-activity') ) { 368 li = target.parents('div.activity ul li'); 369 id = li.attr('id').substr( 9, li.attr('id').length ); 370 link_href = target.attr('href'); 371 nonce = link_href.split('_wpnonce='); 372 timestamp = li.prop( 'class' ).match( /date-recorded-([0-9]+)/ ); 373 nonce = nonce[1]; 374 375 target.addClass('loading'); 376 377 jq.post( ajaxurl, { 378 action: 'delete_activity', 379 'cookie': bp_get_cookies(), 380 'id': id, 381 '_wpnonce': nonce 382 }, 383 function(response) { 384 385 if ( response[0] + response[1] === '-1' ) { 386 li.prepend( response.substr( 2, response.length ) ); 387 li.children('#message').hide().fadeIn(300); 388 } else { 389 li.slideUp(300); 390 391 // reset vars to get newest activities 392 if ( timestamp && activity_last_recorded === timestamp[1] ) { 393 newest_activities = ''; 394 activity_last_recorded = 0; 395 } 396 } 397 }); 398 399 return false; 400 } 401 402 // Spam activity stream items 403 if ( target.hasClass( 'spam-activity' ) ) { 404 li = target.parents( 'div.activity ul li' ); 405 timestamp = li.prop( 'class' ).match( /date-recorded-([0-9]+)/ ); 406 target.addClass( 'loading' ); 407 408 jq.post( ajaxurl, { 409 action: 'bp_spam_activity', 410 'cookie': encodeURIComponent( document.cookie ), 411 'id': li.attr( 'id' ).substr( 9, li.attr( 'id' ).length ), 412 '_wpnonce': target.attr( 'href' ).split( '_wpnonce=' )[1] 413 }, 414 415 function(response) { 416 if ( response[0] + response[1] === '-1' ) { 417 li.prepend( response.substr( 2, response.length ) ); 418 li.children( '#message' ).hide().fadeIn(300); 419 } else { 420 li.slideUp( 300 ); 421 // reset vars to get newest activities 422 if ( timestamp && activity_last_recorded === timestamp[1] ) { 423 newest_activities = ''; 424 activity_last_recorded = 0; 425 } 426 } 427 }); 428 429 return false; 430 } 431 432 /* Load more updates at the end of the page */ 433 if ( target.parent().hasClass('load-more') ) { 434 if ( bp_ajax_request ) { 435 bp_ajax_request.abort(); 436 } 437 438 jq('#buddypress li.load-more').addClass('loading'); 439 440 oldest_page = activity_oldestpage + 1; 441 just_posted = []; 442 443 jq('.activity-list li.just-posted').each( function(){ 444 just_posted.push( jq(this).attr('id').replace( 'activity-','' ) ); 445 }); 446 447 load_more_args = { 448 action: 'activity_get_older_updates', 449 'cookie': bp_get_cookies(), 450 'page': oldest_page, 451 'exclude_just_posted': just_posted.join(',') 452 }; 453 454 load_more_search = bp_get_querystring('s'); 455 456 if ( load_more_search ) { 457 load_more_args.search_terms = load_more_search; 458 } 459 460 bp_ajax_request = jq.post( ajaxurl, load_more_args, 461 function(response) 462 { 463 jq('#buddypress li.load-more').removeClass('loading'); 464 activity_oldestpage = oldest_page; 465 jq('#buddypress ul.activity-list').append(response.contents); 466 467 target.parent().hide(); 468 }, 'json' ); 469 470 return false; 471 } 472 473 /* Load newest updates at the top of the list */ 474 if ( target.parent().hasClass('load-newest') ) { 475 476 event.preventDefault(); 477 478 target.parent().hide(); 479 480 /** 481 * If a plugin is updating the recorded_date of an activity 482 * it will be loaded as a new one. We need to look in the 483 * stream and eventually remove similar ids to avoid "double". 484 */ 485 activity_html = jq.parseHTML( newest_activities ); 486 487 jq.each( activity_html, function( i, el ){ 488 if( 'LI' === el.nodeName && jq(el).hasClass( 'just-posted' ) ) { 489 if( jq( '#' + jq(el).attr( 'id' ) ).length ) { 490 jq( '#' + jq(el).attr( 'id' ) ).remove(); 491 } 492 } 493 } ); 494 495 // Now the stream is cleaned, prepend newest 496 jq( '#buddypress ul.activity-list' ).prepend( newest_activities ); 497 498 // reset the newest activities now they're displayed 499 newest_activities = ''; 500 } 501 }); 502 503 // Activity "Read More" links 504 jq('div.activity').on('click', '.activity-read-more a', function(event) { 505 var target = jq(event.target), 506 link_id = target.parent().attr('id').split('-'), 507 a_id = link_id[3], 508 type = link_id[0], /* activity or acomment */ 509 inner_class, a_inner; 510 511 inner_class = type === 'acomment' ? 'acomment-content' : 'activity-inner'; 512 a_inner = jq('#' + type + '-' + a_id + ' .' + inner_class + ':first' ); 513 jq(target).addClass('loading'); 514 515 jq.post( ajaxurl, { 516 action: 'get_single_activity_content', 517 'activity_id': a_id 518 }, 519 function(response) { 520 jq(a_inner).slideUp(300).html(response).slideDown(300); 521 }); 522 523 return false; 524 }); 525 526 /**** Activity Comments *******************************************************/ 527 528 /* Hide all activity comment forms */ 529 jq('form.ac-form').hide(); 530 531 /* Hide excess comments */ 532 if ( jq('.activity-comments').length ) { 533 bp_legacy_theme_hide_comments(); 534 } 535 536 /* Activity list event delegation */ 537 jq('div.activity').on( 'click', function(event) { 538 var target = jq(event.target), 539 id, ids, a_id, c_id, form, 540 form_parent, form_id, 541 tmp_id, comment_id, comment, 542 ajaxdata, 543 ak_nonce, 544 show_all_a, new_count, 545 link_href, comment_li, nonce; 546 547 /* Comment / comment reply links */ 548 if ( target.hasClass('acomment-reply') || target.parent().hasClass('acomment-reply') ) { 549 if ( target.parent().hasClass('acomment-reply') ) { 550 target = target.parent(); 551 } 552 553 id = target.attr('id'); 554 ids = id.split('-'); 555 556 a_id = ids[2]; 557 c_id = target.attr('href').substr( 10, target.attr('href').length ); 558 form = jq( '#ac-form-' + a_id ); 559 560 form.css( 'display', 'none' ); 561 form.removeClass('root'); 562 jq('.ac-form').hide(); 563 564 /* Hide any error messages */ 565 form.children('div').each( function() { 566 if ( jq(this).hasClass( 'error' ) ) { 567 jq(this).hide(); 568 } 569 }); 570 571 if ( ids[1] !== 'comment' ) { 572 jq('#acomment-' + c_id).append( form ); 573 } else { 574 jq('#activity-' + a_id + ' .activity-comments').append( form ); 575 } 576 577 if ( form.parent().hasClass( 'activity-comments' ) ) { 578 form.addClass('root'); 579 } 580 581 form.slideDown( 200 ); 582 jq.scrollTo( form, 500, { 583 offset:-100, 584 easing:'swing' 585 } ); 586 jq('#ac-form-' + ids[2] + ' textarea').trigger( 'focus' ); 587 588 return false; 589 } 590 591 /* Activity comment posting */ 592 if ( target.attr('name') === 'ac_form_submit' ) { 593 form = target.parents( 'form' ); 594 form_parent = form.parent(); 595 form_id = form.attr('id').split('-'); 596 597 if ( !form_parent.hasClass('activity-comments') ) { 598 tmp_id = form_parent.attr('id').split('-'); 599 comment_id = tmp_id[1]; 600 } else { 601 comment_id = form_id[2]; 602 } 603 604 content = jq( '#' + form.attr('id') + ' textarea' ); 605 606 /* Hide any error messages */ 607 jq( '#' + form.attr('id') + ' div.error').hide(); 608 target.addClass('loading').prop('disabled', true); 609 content.addClass('loading').prop('disabled', true); 610 611 ajaxdata = { 612 action: 'new_activity_comment', 613 'cookie': bp_get_cookies(), 614 '_wpnonce_new_activity_comment': jq('#_wpnonce_new_activity_comment' + '_' + form_id[2] ).val(), 615 'comment_id': comment_id, 616 'form_id': form_id[2], 617 'content': content.val() 618 }; 619 620 // Akismet 621 ak_nonce = jq('#_bp_as_nonce_' + comment_id).val(); 622 if ( ak_nonce ) { 623 ajaxdata['_bp_as_nonce_' + comment_id] = ak_nonce; 624 } 625 626 jq.post( ajaxurl, ajaxdata, function(response) { 627 target.removeClass('loading'); 628 content.removeClass('loading'); 629 630 /* Check for errors and append if found. */ 631 if ( response[0] + response[1] === '-1' ) { 632 form.append( jq( response.substr( 2, response.length ) ).hide().fadeIn( 200 ) ); 633 } else { 634 var activity_comments = form.parent(); 635 form.fadeOut( 200, function() { 636 if ( 0 === activity_comments.children('ul').length ) { 637 if ( activity_comments.hasClass('activity-comments') ) { 638 activity_comments.prepend('<ul></ul>'); 639 } else { 640 activity_comments.append('<ul></ul>'); 641 } 642 } 643 644 /* Preceding whitespace breaks output with jQuery 1.9.0 */ 645 var the_comment = jq.trim( response ); 646 647 activity_comments.children('ul').append( jq( the_comment ).hide().fadeIn( 200 ) ); 648 form.children('textarea').val(''); 649 activity_comments.parent().addClass('has-comments'); 650 } ); 651 jq( '#' + form.attr('id') + ' textarea').val(''); 652 653 /* Increase the "Reply (X)" button count */ 654 new_count = Number( jq('#activity-' + form_id[2] + ' a.acomment-reply span').html() ) + 1; 655 jq('#activity-' + form_id[2] + ' a.acomment-reply span').html( new_count ); 656 657 // Increment the 'Show all x comments' string, if present 658 show_all_a = activity_comments.parents('.activity-comments').find('.show-all a'); 659 if ( show_all_a ) { 660 show_all_a.html( BP_DTheme.show_x_comments.replace( '%d', new_count ) ); 661 } 662 } 663 664 jq(target).prop('disabled', false); 665 jq(content).prop('disabled', false); 666 }); 667 668 return false; 669 } 670 671 /* Deleting an activity comment */ 672 if ( target.hasClass('acomment-delete') ) { 673 link_href = target.attr('href'); 674 comment_li = target.parent().parent(); 675 form = comment_li.parents('div.activity-comments').children('form'); 676 677 nonce = link_href.split('_wpnonce='); 678 nonce = nonce[1]; 679 680 comment_id = link_href.split('cid='); 681 comment_id = comment_id[1].split('&'); 682 comment_id = comment_id[0]; 683 684 target.addClass('loading'); 685 686 /* Remove any error messages */ 687 jq('.activity-comments ul .error').remove(); 688 689 /* Reset the form position */ 690 comment_li.parents('.activity-comments').append(form); 691 692 jq.post( ajaxurl, { 693 action: 'delete_activity_comment', 694 'cookie': bp_get_cookies(), 695 '_wpnonce': nonce, 696 'id': comment_id 697 }, 698 function(response) { 699 /* Check for errors and append if found. */ 700 if ( response[0] + response[1] === '-1' ) { 701 comment_li.prepend( jq( response.substr( 2, response.length ) ).hide().fadeIn( 200 ) ); 702 } else { 703 var children = jq( '#' + comment_li.attr('id') + ' ul' ).children('li'), 704 child_count = 0, 705 count_span, new_count, show_all_a; 706 707 jq(children).each( function() { 708 if ( !jq(this).is(':hidden') ) { 709 child_count++; 710 } 711 }); 712 comment_li.fadeOut(200, function() { 713 comment_li.remove(); 714 }); 715 716 /* Decrease the "Reply (X)" button count */ 717 count_span = jq('#' + comment_li.parents('#activity-stream > li').attr('id') + ' a.acomment-reply span'); 718 new_count = count_span.html() - ( 1 + child_count ); 719 count_span.html(new_count); 720 721 // Change the 'Show all x comments' text 722 show_all_a = comment_li.parents('.activity-comments').find('.show-all a'); 723 if ( show_all_a ) { 724 show_all_a.html( BP_DTheme.show_x_comments.replace( '%d', new_count ) ); 725 } 726 727 /* If that was the last comment for the item, remove the has-comments class to clean up the styling */ 728 if ( 0 === new_count ) { 729 jq(comment_li.parents('#activity-stream > li')).removeClass('has-comments'); 730 } 731 } 732 }); 733 734 return false; 735 } 736 737 // Spam an activity stream comment 738 if ( target.hasClass( 'spam-activity-comment' ) ) { 739 link_href = target.attr( 'href' ); 740 comment_li = target.parent().parent(); 741 742 target.addClass('loading'); 743 744 // Remove any error messages 745 jq( '.activity-comments ul div.error' ).remove(); 746 747 // Reset the form position 748 comment_li.parents( '.activity-comments' ).append( comment_li.parents( '.activity-comments' ).children( 'form' ) ); 749 750 jq.post( ajaxurl, { 751 action: 'bp_spam_activity_comment', 752 'cookie': encodeURIComponent( document.cookie ), 753 '_wpnonce': link_href.split( '_wpnonce=' )[1], 754 'id': link_href.split( 'cid=' )[1].split( '&' )[0] 755 }, 756 757 function ( response ) { 758 // Check for errors and append if found. 759 if ( response[0] + response[1] === '-1' ) { 760 comment_li.prepend( jq( response.substr( 2, response.length ) ).hide().fadeIn( 200 ) ); 761 762 } else { 763 var children = jq( '#' + comment_li.attr( 'id' ) + ' ul' ).children( 'li' ), 764 child_count = 0, 765 parent_li; 766 767 jq(children).each( function() { 768 if ( !jq( this ).is( ':hidden' ) ) { 769 child_count++; 770 } 771 }); 772 comment_li.fadeOut( 200 ); 773 774 // Decrease the "Reply (X)" button count 775 parent_li = comment_li.parents( '#activity-stream > li' ); 776 jq( '#' + parent_li.attr( 'id' ) + ' a.acomment-reply span' ).html( jq( '#' + parent_li.attr( 'id' ) + ' a.acomment-reply span' ).html() - ( 1 + child_count ) ); 777 } 778 }); 779 780 return false; 781 } 782 783 /* Showing hidden comments - pause for half a second */ 784 if ( target.parent().hasClass('show-all') ) { 785 target.parent().addClass('loading'); 786 787 setTimeout( function() { 788 target.parent().parent().children('li').fadeIn(200, function() { 789 target.parent().remove(); 790 }); 791 }, 600 ); 792 793 return false; 794 } 795 796 // Canceling an activity comment 797 if ( target.hasClass( 'ac-reply-cancel' ) ) { 798 jq(target).closest('.ac-form').slideUp( 200 ); 799 return false; 800 } 801 }); 802 803 /* Escape Key Press for cancelling comment forms */ 804 jq(document).on( 'keydown', function(e) { 805 e = e || window.event; 806 if (e.target) { 807 element = e.target; 808 } else if (e.srcElement) { 809 element = e.srcElement; 810 } 811 812 if( element.nodeType === 3) { 813 element = element.parentNode; 814 } 815 816 if( e.ctrlKey === true || e.altKey === true || e.metaKey === true ) { 817 return; 818 } 819 820 var keyCode = (e.keyCode) ? e.keyCode : e.which; 821 822 if ( keyCode === 27 ) { 823 if (element.tagName === 'TEXTAREA') { 824 if ( jq(element).hasClass('ac-input') ) { 825 jq(element).parent().parent().parent().slideUp( 200 ); 826 } 827 } 828 } 829 }); 830 831 /**** Directory Search ****************************************************/ 832 833 /* The search form on all directory pages */ 834 jq( '.dir-search, .groups-members-search' ).on( 'click', function(event) { 835 if ( jq(this).hasClass('no-ajax') ) { 836 return; 837 } 838 839 var target = jq(event.target), 840 css_id, object, template, search_terms; 841 842 if ( target.attr('type') === 'submit' ) { 843 css_id = jq('.item-list-tabs li.selected').attr('id').split( '-' ); 844 object = css_id[0]; 845 template = null; 846 search_terms = target.parent().find( '#' + object + '_search' ).val(); 847 848 // The Group Members page specifies its own template 849 if ( event.currentTarget.className === 'groups-members-search' ) { 850 object = 'group_members'; 851 template = 'groups/single/members'; 852 } 853 854 var scope = bp_get_directory_preference( object, 'scope' ); 855 var filter = bp_get_directory_preference( object, 'filter' ); 856 var extras = bp_get_directory_preference( object, 'extras' ); 857 858 bp_filter_request( object, filter, scope, 'div.' + object, search_terms, 1, extras, null, template ); 859 860 return false; 861 } 862 }); 863 864 /**** Tabs and Filters ****************************************************/ 865 866 /* When a navigation tab is clicked - e.g. | All Groups | My Groups | */ 867 jq('div.item-list-tabs').on( 'click', function(event) { 868 // If on a directory page with a type filter, add no-ajax class. 869 if ( jq( 'body' ).hasClass( 'type' ) && jq( 'body' ).hasClass( 'directory' ) ) { 870 jq(this).addClass( 'no-ajax' ); 871 } 872 873 if ( jq(this).hasClass('no-ajax') || jq( event.target ).hasClass('no-ajax') ) { 874 return; 875 } 876 877 var targetElem = ( event.target.nodeName === 'SPAN' ) ? event.target.parentNode : event.target, 878 target = jq( targetElem ).parent(), 879 css_id, object, scope, filter, search_terms; 880 881 if ( 'LI' === target[0].nodeName && !target.hasClass( 'last' ) ) { 882 css_id = target.attr('id').split( '-' ); 883 object = css_id[0]; 884 885 if ( 'activity' === object ) { 886 return false; 887 } 888 889 scope = css_id[1]; 890 filter = jq('#' + object + '-order-select select').val(); 891 search_terms = jq('#' + object + '_search').val(); 892 893 var extras = bp_get_directory_preference( object, 'extras' ); 894 895 bp_filter_request( object, filter, scope, 'div.' + object, search_terms, 1, extras ); 896 897 return false; 898 } 899 }); 900 901 /* When the filter select box is changed re-query */ 902 jq( 'li.filter select' ).on( 'change', function() { 903 var el, 904 css_id, object, scope, filter, search_terms, template, 905 $gm_search; 906 907 if ( jq('.item-list-tabs li.selected').length ) { 908 el = jq('.item-list-tabs li.selected'); 909 } else { 910 el = jq(this); 911 } 912 913 css_id = el.attr('id').split('-'); 914 object = css_id[0]; 915 scope = css_id[1]; 916 filter = jq(this).val(); 917 search_terms = false; 918 template = null; 919 920 if ( jq('.dir-search input').length ) { 921 search_terms = jq('.dir-search input').val(); 922 } 923 924 // The Group Members page has a different selector for its 925 // search terms box 926 $gm_search = jq( '.groups-members-search input' ); 927 if ( $gm_search.length ) { 928 search_terms = $gm_search.val(); 929 object = 'members'; 930 scope = 'groups'; 931 } 932 933 // On the Groups Members page, we specify a template 934 if ( 'members' === object && 'groups' === scope ) { 935 object = 'group_members'; 936 template = 'groups/single/members'; 937 } 938 939 if ( 'friends' === object ) { 940 object = 'members'; 941 } 942 943 var extras = bp_get_directory_preference( object, 'extras' ); 944 945 bp_filter_request( object, filter, scope, 'div.' + object, search_terms, 1, extras, null, template ); 946 947 return false; 948 } ); 949 950 /* All pagination links run through this function */ 951 jq('#buddypress').on( 'click', function(event) { 952 var target = jq(event.target), 953 el, 954 css_id, object, search_terms, pagination_id, template, 955 page_number, 956 $gm_search, 957 caller; 958 959 if ( target.hasClass('button') ) { 960 return true; 961 } 962 963 if ( target.parent().parent().hasClass('pagination') && !target.parent().parent().hasClass('no-ajax') ) { 964 if ( target.hasClass('dots') || target.hasClass('current') ) { 965 return false; 966 } 967 968 if ( jq('.item-list-tabs li.selected').length ) { 969 el = jq('.item-list-tabs li.selected'); 970 } else { 971 el = jq('li.filter select'); 972 } 973 974 css_id = el.attr('id').split( '-' ); 975 object = css_id[0]; 976 search_terms = false; 977 pagination_id = jq(target).closest('.pagination-links').attr('id'); 978 template = null; 979 980 // Search terms 981 if ( jq('div.dir-search input').length ) { 982 search_terms = jq('.dir-search input'); 983 984 if ( ! search_terms.val() && bp_get_querystring( search_terms.attr( 'name' ) ) ) { 985 search_terms = jq('.dir-search input').prop('placeholder'); 986 } else { 987 search_terms = search_terms.val(); 988 } 989 } 990 991 // Page number 992 if ( jq(target).hasClass('next') || jq(target).hasClass('prev') ) { 993 page_number = jq('.pagination span.current').html(); 994 } else { 995 page_number = jq(target).html(); 996 } 997 998 // Remove any non-numeric characters from page number text (commas, etc.) 999 page_number = Number( page_number.replace(/\D/g,'') ); 1000 1001 if ( jq(target).hasClass('next') ) { 1002 page_number++; 1003 } else if ( jq(target).hasClass('prev') ) { 1004 page_number--; 1005 } 1006 1007 // The Group Members page has a different selector for 1008 // its search terms box 1009 $gm_search = jq( '.groups-members-search input' ); 1010 if ( $gm_search.length ) { 1011 search_terms = $gm_search.val(); 1012 object = 'members'; 1013 } 1014 1015 // On the Groups Members page, we specify a template 1016 if ( 'members' === object && 'groups' === css_id[1] ) { 1017 object = 'group_members'; 1018 template = 'groups/single/members'; 1019 } 1020 1021 // On the Admin > Requests page, we need to reset the object, 1022 // since "admin" isn't specific enough 1023 if ( 'admin' === object && jq( 'body' ).hasClass( 'membership-requests' ) ) { 1024 object = 'requests'; 1025 } 1026 1027 if ( pagination_id.indexOf( 'pag-bottom' ) !== -1 ) { 1028 caller = 'pag-bottom'; 1029 } else { 1030 caller = null; 1031 } 1032 1033 var scope = bp_get_directory_preference( object, 'scope' ); 1034 var filter = bp_get_directory_preference( object, 'filter' ); 1035 var extras = bp_get_directory_preference( object, 'extras' ); 1036 1037 bp_filter_request( object, filter, scope, 'div.' + object, search_terms, page_number, extras, caller, template ); 1038 1039 return false; 1040 } 1041 1042 }); 1043 1044 /** Invite Friends Interface ****************************************/ 1045 1046 /* Select a user from the list of friends and add them to the invite list */ 1047 jq('#send-invite-form').on( 'click', '#invite-list input', function() { 1048 // invites-loop template contains a div with the .invite class 1049 // We use the existence of this div to check for old- vs new- 1050 // style templates. 1051 var invites_new_template = jq( '#send-invite-form > .invite' ).length, 1052 friend_id, friend_action; 1053 1054 jq('.ajax-loader').toggle(); 1055 1056 // Dim the form until the response arrives 1057 if ( invites_new_template ) { 1058 jq( this ).parents( 'ul' ).find( 'input' ).prop( 'disabled', true ); 1059 } 1060 1061 friend_id = jq(this).val(); 1062 1063 if ( jq(this).prop('checked') === true ) { 1064 friend_action = 'invite'; 1065 } else { 1066 friend_action = 'uninvite'; 1067 } 1068 1069 if ( ! invites_new_template ) { 1070 jq( '.item-list-tabs li.selected' ).addClass( 'loading' ); 1071 } 1072 1073 jq.post( ajaxurl, { 1074 action: 'groups_invite_user', 1075 'friend_action': friend_action, 1076 'cookie': bp_get_cookies(), 1077 '_wpnonce': jq('#_wpnonce_invite_uninvite_user').val(), 1078 'friend_id': friend_id, 1079 'group_id': jq('#group_id').val() 1080 }, 1081 function(response) 1082 { 1083 if ( jq('#message') ) { 1084 jq('#message').hide(); 1085 } 1086 1087 if ( invites_new_template ) { 1088 // With new-style templates, we refresh the 1089 // entire list 1090 bp_filter_request( 'invite', 'bp-invite-filter', 'bp-invite-scope', 'div.invite', false, 1, '', '', '' ); 1091 } else { 1092 // Old-style templates manipulate only the 1093 // single invitation element 1094 jq('.ajax-loader').toggle(); 1095 1096 if ( friend_action === 'invite' ) { 1097 jq('#friend-list').append(response); 1098 } else if ( friend_action === 'uninvite' ) { 1099 jq('#friend-list li#uid-' + friend_id).remove(); 1100 } 1101 1102 jq('.item-list-tabs li.selected').removeClass('loading'); 1103 } 1104 }); 1105 }); 1106 1107 /* Remove a user from the list of users to invite to a group */ 1108 jq('#send-invite-form').on('click', 'a.remove', function() { 1109 // invites-loop template contains a div with the .invite class 1110 // We use the existence of this div to check for old- vs new- 1111 // style templates. 1112 var invites_new_template = jq('#send-invite-form > .invite').length, 1113 friend_id = jq(this).attr('id'); 1114 1115 jq('.ajax-loader').toggle(); 1116 1117 friend_id = friend_id.split('-'); 1118 friend_id = friend_id[1]; 1119 1120 jq.post( ajaxurl, { 1121 action: 'groups_invite_user', 1122 'friend_action': 'uninvite', 1123 'cookie': bp_get_cookies(), 1124 '_wpnonce': jq('#_wpnonce_invite_uninvite_user').val(), 1125 'friend_id': friend_id, 1126 'group_id': jq('#group_id').val() 1127 }, 1128 function() 1129 { 1130 if ( invites_new_template ) { 1131 // With new-style templates, we refresh the 1132 // entire list 1133 bp_filter_request( 'invite', 'bp-invite-filter', 'bp-invite-scope', 'div.invite', false, 1, '', '', '' ); 1134 } else { 1135 // Old-style templates manipulate only the 1136 // single invitation element 1137 jq('.ajax-loader').toggle(); 1138 jq('#friend-list #uid-' + friend_id).remove(); 1139 jq('#invite-list #f-' + friend_id).prop('checked', false); 1140 } 1141 }); 1142 1143 return false; 1144 }); 1145 1146 /** Profile Visibility Settings *********************************/ 1147 jq( '.visibility-toggle-link' ).on( 'click', function( event ) { 1148 event.preventDefault(); 1149 1150 jq( this ).attr( 'aria-expanded', 'true' ).parent().hide().addClass( 'field-visibility-settings-hide' ) 1151 .siblings( '.field-visibility-settings' ).show().addClass( 'field-visibility-settings-open' ); 1152 } ); 1153 1154 jq( '.field-visibility-settings-close' ).on( 'click', function( event ) { 1155 event.preventDefault(); 1156 1157 jq( '.visibility-toggle-link' ).attr( 'aria-expanded', 'false' ); 1158 1159 var settings_div = jq( this ).parent(), 1160 vis_setting_text = settings_div.find( 'input:checked' ).parent().text(); 1161 1162 settings_div.hide().removeClass( 'field-visibility-settings-open' ) 1163 .siblings( '.field-visibility-settings-toggle' ) 1164 .find( '.current-visibility-level' ).text( vis_setting_text ).end() 1165 .show().removeClass( 'field-visibility-settings-hide' ); 1166 } ); 1167 1168 jq( '#profile-edit-form input:not(:submit), #profile-edit-form textarea, #profile-edit-form select, #signup_form input:not(:submit), #signup_form textarea, #signup_form select' ).on( 'change', function() { 1169 var shouldconfirm = true; 1170 1171 jq('#profile-edit-form input:submit, #signup_form input:submit').on( 'click', function() { 1172 shouldconfirm = false; 1173 }); 1174 1175 window.onbeforeunload = function(e) { 1176 if ( shouldconfirm ) { 1177 return BP_DTheme.unsaved_changes; 1178 } 1179 }; 1180 } ); 1181 1182 /** Friendship Requests **************************************/ 1183 1184 /* Accept and Reject friendship request buttons */ 1185 jq('#friend-list a.accept, #friend-list a.reject').on( 'click', function() { 1186 var button = jq(this), 1187 li = jq(this).parents('#friend-list li'), 1188 action_div = jq(this).parents('li div.action'), 1189 id = li.attr('id').substr( 11, li.attr('id').length ), 1190 link_href = button.attr('href'), 1191 nonce = link_href.split('_wpnonce=')[1], 1192 action; 1193 1194 if ( jq(this).hasClass('accepted') || jq(this).hasClass('rejected') ) { 1195 return false; 1196 } 1197 1198 if ( jq(this).hasClass('accept') ) { 1199 action = 'accept_friendship'; 1200 action_div.children('a.reject').css( 'visibility', 'hidden' ); 1201 } else { 1202 action = 'reject_friendship'; 1203 action_div.children('a.accept').css( 'visibility', 'hidden' ); 1204 } 1205 1206 button.addClass('loading'); 1207 1208 jq.post( ajaxurl, { 1209 action: action, 1210 'cookie': bp_get_cookies(), 1211 'id': id, 1212 '_wpnonce': nonce 1213 }, 1214 function(response) { 1215 button.removeClass('loading'); 1216 1217 if ( response[0] + response[1] === '-1' ) { 1218 li.prepend( response.substr( 2, response.length ) ); 1219 li.children('#message').hide().fadeIn(200); 1220 } else { 1221 button.fadeOut( 100, function() { 1222 if ( jq(this).hasClass('accept') ) { 1223 action_div.children('a.reject').hide(); 1224 jq(this).html( BP_DTheme.accepted ).contents().unwrap(); 1225 } else { 1226 action_div.children('a.accept').hide(); 1227 jq(this).html( BP_DTheme.rejected ).contents().unwrap(); 1228 } 1229 }); 1230 } 1231 }); 1232 1233 return false; 1234 }); 1235 1236 /* Add / Remove friendship buttons */ 1237 jq( '#members-dir-list, #members-group-list, #item-header' ).on('click', '.friendship-button a', function() { 1238 jq(this).parent().addClass('loading'); 1239 var fid = jq(this).attr('id'), 1240 nonce = jq(this).attr('href'), 1241 thelink = jq(this); 1242 1243 fid = fid.split('-'); 1244 fid = fid[1]; 1245 1246 nonce = nonce.split('?_wpnonce='); 1247 nonce = nonce[1].split('&'); 1248 nonce = nonce[0]; 1249 1250 jq.post( ajaxurl, { 1251 action: 'addremove_friend', 1252 'cookie': bp_get_cookies(), 1253 'fid': fid, 1254 '_wpnonce': nonce 1255 }, 1256 function(response) 1257 { 1258 var action = thelink.attr('rel'); 1259 parentdiv = thelink.parent(); 1260 1261 if ( action === 'add' ) { 1262 jq(parentdiv).fadeOut(200, 1263 function() { 1264 parentdiv.removeClass('add_friend'); 1265 parentdiv.removeClass('loading'); 1266 parentdiv.addClass('pending_friend'); 1267 parentdiv.fadeIn(200).html(response); 1268 } 1269 ); 1270 1271 } else if ( action === 'remove' ) { 1272 jq(parentdiv).fadeOut(200, 1273 function() { 1274 parentdiv.removeClass('remove_friend'); 1275 parentdiv.removeClass('loading'); 1276 parentdiv.addClass('add'); 1277 parentdiv.fadeIn(200).html(response); 1278 } 1279 ); 1280 } 1281 }); 1282 return false; 1283 } ); 1284 1285 /** Group Join / Leave Buttons **************************************/ 1286 1287 // Confirmation when clicking Leave Group in group headers 1288 jq('#buddypress').on('click', '.group-button .leave-group', function() { 1289 if ( false === confirm( BP_DTheme.leave_group_confirm ) ) { 1290 return false; 1291 } 1292 }); 1293 1294 jq('#groups-dir-list').on('click', '.group-button a', function() { 1295 var gid = jq(this).parent().attr('id'), 1296 nonce = jq(this).attr('href'), 1297 thelink = jq(this); 1298 1299 gid = gid.split('-'); 1300 gid = gid[1]; 1301 1302 nonce = nonce.split('?_wpnonce='); 1303 nonce = nonce[1].split('&'); 1304 nonce = nonce[0]; 1305 1306 // Leave Group confirmation within directories - must intercept 1307 // AJAX request 1308 if ( thelink.hasClass( 'leave-group' ) && false === confirm( BP_DTheme.leave_group_confirm ) ) { 1309 return false; 1310 } 1311 1312 jq.post( ajaxurl, { 1313 action: 'joinleave_group', 1314 'cookie': bp_get_cookies(), 1315 'gid': gid, 1316 '_wpnonce': nonce 1317 }, 1318 function(response) 1319 { 1320 var parentdiv = thelink.parent(); 1321 1322 // user groups page 1323 if ( ! jq('body.directory').length ) { 1324 window.location.reload(); 1325 1326 // groups directory 1327 } else { 1328 jq(parentdiv).fadeOut(200, 1329 function() { 1330 parentdiv.fadeIn(200).html(response); 1331 1332 var mygroups = jq('#groups-personal span'), 1333 add = 1; 1334 1335 if( thelink.hasClass( 'leave-group' ) ) { 1336 // hidden groups slide up 1337 if ( parentdiv.hasClass( 'hidden' ) ) { 1338 parentdiv.closest('li').slideUp( 200 ); 1339 } 1340 1341 add = 0; 1342 } else if ( thelink.hasClass( 'request-membership' ) ) { 1343 add = false; 1344 } 1345 1346 // change the "My Groups" value 1347 if ( mygroups.length && add !== false ) { 1348 if ( add ) { 1349 mygroups.text( ( mygroups.text() >> 0 ) + 1 ); 1350 } else { 1351 mygroups.text( ( mygroups.text() >> 0 ) - 1 ); 1352 } 1353 } 1354 1355 } 1356 ); 1357 } 1358 }); 1359 return false; 1360 } ); 1361 1362 // Fix hidden group visibility with themes using the .hidden CSS rule. 1363 jq('#groups-list li.hidden').each(function() { 1364 if ( jq(this).css('display') === 'none' ) { 1365 jq(this).css('cssText', 'display: list-item !important'); 1366 } 1367 }); 1368 1369 /** Button disabling ************************************************/ 1370 1371 jq('#buddypress').on( 'click', '.pending', function() { 1372 return false; 1373 }); 1374 1375 /** Registration ***********************************************/ 1376 1377 if ( jq('body').hasClass('register') ) { 1378 var blog_checked = jq('#signup_with_blog'); 1379 1380 // hide "Blog Details" block if not checked by default 1381 if ( ! blog_checked.prop('checked') ) { 1382 jq('#blog-details').toggle(); 1383 } 1384 1385 // toggle "Blog Details" block whenever checkbox is checked 1386 blog_checked.on( 'change', function() { 1387 jq('#blog-details').toggle(); 1388 }); 1389 } 1390 1391 /** Private Messaging ******************************************/ 1392 1393 /** Message search */ 1394 jq('.message-search').on( 'click', function(event) { 1395 if ( jq(this).hasClass('no-ajax') ) { 1396 return; 1397 } 1398 1399 var target = jq(event.target), 1400 object; 1401 1402 if ( target.attr('type') === 'submit' || target.attr('type') === 'button' ) { 1403 object = 'messages'; 1404 1405 var scope = bp_get_directory_preference( object, 'scope' ); 1406 var filter = bp_get_directory_preference( object, 'filter' ); 1407 var extras = bp_get_directory_preference( object, 'extras' ); 1408 1409 bp_filter_request( 1410 object, 1411 filter, 1412 scope, 1413 'div.' + object, jq('#messages_search').val(), 1414 1, 1415 extras 1416 ); 1417 1418 return false; 1419 } 1420 }); 1421 1422 /* AJAX send reply functionality */ 1423 jq( '#send_reply_button' ).on( 'click', 1424 function() { 1425 var order = jq('#messages_order').val() || 'ASC', 1426 offset = jq('#message-recipients').offset(), 1427 button = jq('#send_reply_button'); 1428 1429 jq(button).addClass('loading').prop( 'disabled', true ); 1430 1431 jq.post( ajaxurl, { 1432 action: 'messages_send_reply', 1433 'cookie': bp_get_cookies(), 1434 '_wpnonce': jq('#send_message_nonce').val(), 1435 1436 'content': jq('#message_content').val(), 1437 'send_to': jq('#send_to').val(), 1438 'subject': jq('#subject').val(), 1439 'thread_id': jq('#thread_id').val() 1440 }, 1441 function(response) 1442 { 1443 if ( response[0] + response[1] === '-1' ) { 1444 jq('#send-reply').prepend( response.substr( 2, response.length ) ); 1445 } else { 1446 jq('#send-reply #message').remove(); 1447 jq('#message_content').val(''); 1448 1449 if ( 'ASC' === order ) { 1450 jq('#send-reply').before( response ); 1451 } else { 1452 jq('#message-recipients').after( response ); 1453 jq(window).scrollTop(offset.top); 1454 } 1455 1456 jq('.new-message').hide().slideDown( 200, function() { 1457 jq('.new-message').removeClass('new-message'); 1458 }); 1459 } 1460 jq(button).removeClass('loading').prop( 'disabled', false ); 1461 }); 1462 1463 return false; 1464 } 1465 ); 1466 1467 /* Selecting unread and read messages in inbox */ 1468 jq( 'body.messages #item-body div.messages' ).on( 'change', '#message-type-select', function() { 1469 var selection = this.value, 1470 checkboxes = jq( 'td input[type="checkbox"]' ), 1471 checked_value = 'checked'; 1472 1473 checkboxes.each( function(i) { 1474 checkboxes[i].checked = ''; 1475 }); 1476 1477 switch ( selection ) { 1478 case 'unread': 1479 checkboxes = jq('tr.unread td input[type="checkbox"]'); 1480 break; 1481 case 'read': 1482 checkboxes = jq('tr.read td input[type="checkbox"]'); 1483 break; 1484 case '': 1485 checked_value = ''; 1486 break; 1487 } 1488 1489 checkboxes.each( function(i) { 1490 checkboxes[i].checked = checked_value; 1491 }); 1492 }); 1493 1494 /* Selecting/Deselecting all messages */ 1495 jq( '#select-all-messages' ).on( 'click', function() { 1496 if ( this.checked ) { 1497 jq( '.message-check' ).each( function() { 1498 this.checked = true; 1499 } ); 1500 } else { 1501 jq( '.message-check' ).each( function() { 1502 this.checked = false; 1503 } ); 1504 } 1505 } ); 1506 1507 /* Make sure a 'Bulk Action' is selected before submitting the messages bulk action form */ 1508 jq('#messages-bulk-manage').attr('disabled', 'disabled'); 1509 1510 /* Remove the disabled attribute from the messages form submit button when bulk action has a value */ 1511 jq('#messages-select').on('change', function(){ 1512 jq('#messages-bulk-manage').attr('disabled', jq(this).val().length <= 0); 1513 }); 1514 1515 /* Star action function */ 1516 starAction = function() { 1517 var link = jq(this); 1518 1519 jq.post( ajaxurl, { 1520 action: 'messages_star', 1521 'message_id': link.data('message-id'), 1522 'star_status': link.data('star-status'), 1523 'nonce': link.data('star-nonce'), 1524 'bulk': link.data('star-bulk') 1525 }, 1526 function(response) { 1527 if ( 1 === parseInt( response, 10 ) ) { 1528 if ( 'unstar' === link.data('star-status') ) { 1529 link.data('star-status', 'star'); 1530 link.removeClass('message-action-unstar').addClass('message-action-star'); 1531 link.find('.bp-screen-reader-text').text( BP_PM_Star.strings.text_star ); 1532 1533 if ( 1 === BP_PM_Star.is_single_thread ) { 1534 link.attr('data-bp-tooltip', BP_PM_Star.strings.title_star ); 1535 } else { 1536 link.attr('data-bp-tooltip', BP_PM_Star.strings.title_star_thread ); 1537 } 1538 1539 } else { 1540 link.data('star-status', 'unstar'); 1541 link.removeClass('message-action-star').addClass('message-action-unstar'); 1542 link.find('.bp-screen-reader-text').text(BP_PM_Star.strings.text_unstar); 1543 1544 if ( 1 === BP_PM_Star.is_single_thread ) { 1545 link.attr('data-bp-tooltip', BP_PM_Star.strings.title_unstar ); 1546 } else { 1547 link.attr('data-bp-tooltip', BP_PM_Star.strings.title_unstar_thread ); 1548 } 1549 } 1550 } 1551 }); 1552 return false; 1553 }; 1554 1555 /* Star actions */ 1556 jq('#message-threads').on('click', 'td.thread-star a', starAction ); 1557 jq('#message-thread').on('click', '.message-star-actions a', starAction ); 1558 1559 /* Star bulk manage - Show only the valid action based on the starred item. */ 1560 jq('#message-threads td.bulk-select-check :checkbox').on('change', function() { 1561 var box = jq(this), 1562 star = box.closest('tr').find('.thread-star a'); 1563 1564 if ( box.prop('checked') ) { 1565 if( 'unstar' === star.data('star-status') ) { 1566 BP_PM_Star.star_counter++; 1567 } else { 1568 BP_PM_Star.unstar_counter++; 1569 } 1570 } else { 1571 if( 'unstar' === star.data('star-status') ) { 1572 BP_PM_Star.star_counter--; 1573 } else { 1574 BP_PM_Star.unstar_counter--; 1575 } 1576 } 1577 1578 if ( BP_PM_Star.star_counter > 0 && parseInt( BP_PM_Star.unstar_counter, 10 ) === 0 ) { 1579 jq('option[value="star"]').hide(); 1580 } else { 1581 jq('option[value="star"]').show(); 1582 } 1583 1584 if ( BP_PM_Star.unstar_counter > 0 && parseInt( BP_PM_Star.star_counter, 10 ) === 0 ) { 1585 jq('option[value="unstar"]').hide(); 1586 } else { 1587 jq('option[value="unstar"]').show(); 1588 } 1589 }); 1590 1591 /** Notifications **********************************************/ 1592 1593 /* Selecting/Deselecting all notifications */ 1594 jq( '#select-all-notifications' ).on( 'click', function() { 1595 if ( this.checked ) { 1596 jq( '.notification-check' ).each( function() { 1597 this.checked = true; 1598 } ); 1599 } else { 1600 jq( '.notification-check' ).each( function() { 1601 this.checked = false; 1602 } ); 1603 } 1604 } ); 1605 1606 /* Make sure a 'Bulk Action' is selected before submitting the form */ 1607 jq('#notification-bulk-manage').attr('disabled', 'disabled'); 1608 1609 /* Remove the disabled attribute from the form submit button when bulk action has a value */ 1610 jq('#notification-select').on('change', function(){ 1611 jq('#notification-bulk-manage').attr('disabled', jq(this).val().length <= 0); 1612 }); 1613 1614 /* Close site wide notices in the sidebar */ 1615 jq('#close-notice').on( 'click', function() { 1616 jq(this).addClass('loading'); 1617 jq('#sidebar div.error').remove(); 1618 1619 jq.post( ajaxurl, { 1620 action: 'messages_close_notice', 1621 'notice_id': jq('.notice').attr('rel').substr( 2, jq('.notice').attr('rel').length ), 1622 nonce: jq( '#close-notice-nonce' ).val() 1623 }, 1624 function(response) { 1625 jq('#close-notice').removeClass('loading'); 1626 1627 if ( response[0] + response[1] === '-1' ) { 1628 jq('.notice').prepend( response.substr( 2, response.length ) ); 1629 jq( '#sidebar div.error').hide().fadeIn( 200 ); 1630 } else { 1631 jq('.notice').slideUp( 100 ); 1632 } 1633 }); 1634 return false; 1635 }); 1636 1637 /* Toolbar & wp_list_pages JavaScript IE6 hover class */ 1638 jq('#wp-admin-bar ul.main-nav li, #nav li').on( 'mouseover', function() { 1639 jq(this).addClass('sfhover'); 1640 }); 1641 1642 jq('#wp-admin-bar ul.main-nav li, #nav li').on( 'mouseout', function() { 1643 jq(this).removeClass('sfhover'); 1644 }); 1645 1646 /* Clear BP cookies on logout */ 1647 jq('#wp-admin-bar-logout, a.logout').on( 'click', function() { 1648 jq.removeCookie('bp-activity-scope', { 1649 path: '/', 1650 secure: ( 'https:' === window.location.protocol ) 1651 }); 1652 jq.removeCookie('bp-activity-filter', { 1653 path: '/', 1654 secure: ( 'https:' === window.location.protocol ) 1655 }); 1656 jq.removeCookie('bp-activity-oldestpage', { 1657 path: '/', 1658 secure: ( 'https:' === window.location.protocol ) 1659 }); 1660 1661 var objects = [ 'members', 'groups', 'blogs', 'forums' ]; 1662 jq(objects).each( function(i) { 1663 jq.removeCookie('bp-' + objects[i] + '-scope', { 1664 path: '/', 1665 secure: ( 'https:' === window.location.protocol ) 1666 } ); 1667 jq.removeCookie('bp-' + objects[i] + '-filter', { 1668 path: '/', 1669 secure: ( 'https:' === window.location.protocol ) 1670 } ); 1671 jq.removeCookie('bp-' + objects[i] + '-extras', { 1672 path: '/', 1673 secure: ( 'https:' === window.location.protocol ) 1674 } ); 1675 }); 1676 }); 1677 1678 /* if js is enabled then replace the no-js class by a js one */ 1679 if( jq('body').hasClass('no-js') ) { 1680 jq('body').attr('class', jq('body').attr('class').replace( /no-js/,'js' ) ); 1681 } 1682 1683 /** Activity HeartBeat ************************************************/ 1684 1685 // Set the interval and the namespace event 1686 if ( typeof wp !== 'undefined' && typeof wp.heartbeat !== 'undefined' && typeof BP_DTheme.pulse !== 'undefined' ) { 1687 1688 wp.heartbeat.interval( Number( BP_DTheme.pulse ) ); 1689 1690 jq.fn.extend({ 1691 'heartbeat-send': function() { 1692 return this.bind( 'heartbeat-send.buddypress' ); 1693 } 1694 }); 1695 } 1696 1697 // Set the last id to request after 1698 var first_item_recorded = 0; 1699 jq( document ).on( 'heartbeat-send.buddypress', function( e, data ) { 1700 1701 first_item_recorded = 0; 1702 1703 // First row is default latest activity id 1704 if ( jq( '#buddypress ul.activity-list li' ).first().prop( 'id' ) ) { 1705 // getting the timestamp 1706 timestamp = jq( '#buddypress ul.activity-list li' ).first().prop( 'class' ).match( /date-recorded-([0-9]+)/ ); 1707 1708 if ( timestamp ) { 1709 first_item_recorded = timestamp[1]; 1710 } 1711 } 1712 1713 if ( 0 === activity_last_recorded || Number( first_item_recorded ) > activity_last_recorded ) { 1714 activity_last_recorded = Number( first_item_recorded ); 1715 } 1716 1717 data.bp_activity_last_recorded = activity_last_recorded; 1718 1719 last_recorded_search = bp_get_querystring('s'); 1720 1721 if ( last_recorded_search ) { 1722 data.bp_activity_last_recorded_search_terms = last_recorded_search; 1723 } 1724 }); 1725 1726 // Increment newest_activities and activity_last_recorded if data has been returned 1727 jq( document ).on( 'heartbeat-tick', function( e, data ) { 1728 1729 // Only proceed if we have newest activities 1730 if ( ! data.bp_activity_newest_activities ) { 1731 return; 1732 } 1733 1734 newest_activities = data.bp_activity_newest_activities.activities + newest_activities; 1735 activity_last_recorded = Number( data.bp_activity_newest_activities.last_recorded ); 1736 1737 if ( jq( '#buddypress ul.activity-list li' ).first().hasClass( 'load-newest' ) ) { 1738 return; 1739 } 1740 1741 jq( '#buddypress ul.activity-list' ).prepend( '<li class="load-newest"><a href="#newest">' + BP_DTheme.newest + '</a></li>' ); 1742 }); 1743 }); 1744 1745 /** 1746 * Gets the user's current preference for a directory option. 1747 */ 1748 function bp_get_directory_preference( directoryType, pref ) { 1749 var defaultPrefs = { 1750 filter: '', 1751 scope: '', 1752 extras: '' 1753 }; 1754 1755 if ( ! directoryPreferences.hasOwnProperty( directoryType ) ) { 1756 var newPreferences = {}; 1757 for ( var prefName in defaultPrefs ) { 1758 if ( defaultPrefs.hasOwnProperty( prefName ) ) { 1759 newPreferences[ prefName ] = defaultPrefs[ prefName ]; 1760 } 1761 } 1762 directoryPreferences[ directoryType ] = newPreferences; 1763 } 1764 1765 if ( BP_DTheme.store_filter_settings ) { 1766 directoryPreferences[ directoryType ][ pref ] = jq.cookie( 'bp-' + directoryType + '-' + pref ); 1767 } 1768 1769 return directoryPreferences[ directoryType ][ pref ]; 1770 } 1771 1772 /** 1773 * Sets the user's current preference for a directory option. 1774 */ 1775 function bp_set_directory_preference( directoryType, pref, value ) { 1776 var defaultPrefs = { 1777 filter: '', 1778 scope: '', 1779 extras: '' 1780 }; 1781 1782 if ( ! directoryPreferences.hasOwnProperty( directoryType ) ) { 1783 var newPreferences = {}; 1784 for ( var prefName in defaultPrefs ) { 1785 if ( defaultPrefs.hasOwnProperty( prefName ) ) { 1786 newPreferences[ prefName ] = defaultPrefs[ prefName ]; 1787 } 1788 } 1789 directoryPreferences[ directoryType ] = newPreferences; 1790 } 1791 1792 if ( BP_DTheme.store_filter_settings ) { 1793 jq.cookie( 'bp-' + directoryType + '-' + pref, value, { 1794 path: '/', 1795 secure: ( 'https:' === window.location.protocol ) 1796 } ); 1797 } 1798 1799 directoryPreferences[ directoryType ][ pref ] = value; 1800 } 1801 1802 /* Setup activity scope and filter based on the current cookie settings. */ 1803 function bp_init_activity() { 1804 var scope = bp_get_directory_preference( 'activity', 'scope' ); 1805 var filter = bp_get_directory_preference( 'activity', 'filter' ); 1806 1807 if ( undefined !== filter && jq('#activity-filter-select').length ) { 1808 jq('#activity-filter-select select option[value="' + filter + '"]').prop( 'selected', true ); 1809 } 1810 1811 /* Activity Tab Set */ 1812 if ( undefined !== scope && jq('.activity-type-tabs').length ) { 1813 jq('.activity-type-tabs li').each( function() { 1814 jq(this).removeClass('selected'); 1815 }); 1816 jq('#activity-' + scope + ', .item-list-tabs li.current').addClass('selected'); 1817 } 1818 } 1819 1820 /* Setup object scope and filter based on the current cookie settings for the object. */ 1821 function bp_init_objects(objects) { 1822 jq(objects).each( function(i) { 1823 var scope = bp_get_directory_preference( objects[i], 'scope' ); 1824 var filter = bp_get_directory_preference( objects[i], 'filter' ); 1825 1826 if ( undefined !== filter && jq('#' + objects[i] + '-order-select select').length ) { 1827 jq('#' + objects[i] + '-order-select select option[value="' + filter + '"]').prop( 'selected', true ); 1828 } 1829 1830 if ( undefined !== scope && jq('div.' + objects[i]).length ) { 1831 jq('.item-list-tabs li').each( function() { 1832 jq(this).removeClass('selected'); 1833 }); 1834 jq('#' + objects[i] + '-' + scope + ', #object-nav li.current').addClass('selected'); 1835 } 1836 }); 1837 } 1838 1839 /* Filter the current content list (groups/members/blogs/topics) */ 1840 function bp_filter_request( object, filter, scope, target, search_terms, page, extras, caller, template ) { 1841 if ( 'activity' === object ) { 1842 return false; 1843 } 1844 1845 if ( null === scope ) { 1846 scope = 'all'; 1847 } 1848 1849 /* Save the settings we want to remain persistent */ 1850 bp_set_directory_preference( object, 'scope', scope ); 1851 bp_set_directory_preference( object, 'filter', filter ); 1852 bp_set_directory_preference( object, 'extras', extras ); 1853 1854 /* Set the correct selected nav and filter */ 1855 jq('.item-list-tabs li').each( function() { 1856 jq(this).removeClass('selected'); 1857 }); 1858 jq('#' + object + '-' + scope + ', #object-nav li.current').addClass('selected'); 1859 jq('.item-list-tabs li.selected').addClass('loading'); 1860 jq('.item-list-tabs select option[value="' + filter + '"]').prop( 'selected', true ); 1861 1862 if ( 'friends' === object || 'group_members' === object ) { 1863 object = 'members'; 1864 } 1865 1866 if ( bp_ajax_request ) { 1867 bp_ajax_request.abort(); 1868 } 1869 1870 // Get directory preferences (called "cookie" for legacy reasons). 1871 var cookies = {}; 1872 cookies['bp-' + object + '-filter'] = bp_get_directory_preference( object, 'filter' ); 1873 cookies['bp-' + object + '-scope'] = bp_get_directory_preference( object, 'scope' ); 1874 1875 var cookie = encodeURIComponent( jq.param( cookies ) ); 1876 1877 bp_ajax_request = jq.post( ajaxurl, { 1878 action: object + '_filter', 1879 'cookie': cookie, 1880 'object': object, 1881 'filter': filter, 1882 'search_terms': search_terms, 1883 'scope': scope, 1884 'page': page, 1885 'extras': extras, 1886 'template': template 1887 }, 1888 function(response) 1889 { 1890 /* animate to top if called from bottom pagination */ 1891 if ( caller === 'pag-bottom' && jq('#subnav').length ) { 1892 var top = jq('#subnav').parent(); 1893 jq('html,body').animate({scrollTop: top.offset().top}, 'slow', function() { 1894 jq(target).fadeOut( 100, function() { 1895 jq(this).html(response); 1896 jq(this).fadeIn(100); 1897 }); 1898 }); 1899 1900 } else { 1901 jq(target).fadeOut( 100, function() { 1902 jq(this).html(response); 1903 jq(this).fadeIn(100); 1904 }); 1905 } 1906 1907 jq('.item-list-tabs li.selected').removeClass('loading'); 1908 }); 1909 } 1910 1911 /* Activity Loop Requesting */ 1912 function bp_activity_request(scope, filter) { 1913 /* Save the type and filter */ 1914 bp_set_directory_preference( 'activity', 'scope', scope ); 1915 bp_set_directory_preference( 'activity', 'filter', filter ); 1916 1917 /* Remove selected and loading classes from tabs */ 1918 jq('.item-list-tabs li').each( function() { 1919 jq(this).removeClass('selected loading'); 1920 }); 1921 /* Set the correct selected nav and filter */ 1922 jq('#activity-' + scope + ', .item-list-tabs li.current').addClass('selected'); 1923 jq('#object-nav.item-list-tabs li.selected, div.activity-type-tabs li.selected').addClass('loading'); 1924 jq('#activity-filter-select select option[value="' + filter + '"]').prop( 'selected', true ); 1925 1926 /* Reload the activity stream based on the selection */ 1927 jq('.widget_bp_activity_widget h2 span.ajax-loader').show(); 1928 1929 if ( bp_ajax_request ) { 1930 bp_ajax_request.abort(); 1931 } 1932 1933 // Get directory preferences (called "cookie" for legacy reasons). 1934 var cookies = { 1935 'bp-activity-filter': bp_get_directory_preference( 'activity', 'filter' ), 1936 'bp-activity-scope': bp_get_directory_preference( 'activity', 'scope' ) 1937 }; 1938 1939 var cookie = encodeURIComponent( jq.param( cookies ) ); 1940 1941 bp_ajax_request = jq.post( ajaxurl, { 1942 action: 'activity_widget_filter', 1943 'cookie': cookie, 1944 '_wpnonce_activity_filter': jq('#_wpnonce_activity_filter').val(), 1945 'scope': scope, 1946 'filter': filter 1947 }, 1948 function(response) 1949 { 1950 jq('.widget_bp_activity_widget h2 span.ajax-loader').hide(); 1951 1952 jq('div.activity').fadeOut( 100, function() { 1953 jq(this).html(response.contents); 1954 jq(this).fadeIn(100); 1955 1956 /* Selectively hide comments */ 1957 bp_legacy_theme_hide_comments(); 1958 }); 1959 1960 /* Update the feed link */ 1961 if ( undefined !== response.feed_url ) { 1962 jq('.directory #subnav li.feed a, .home-page #subnav li.feed a').attr('href', response.feed_url); 1963 } 1964 1965 jq('.item-list-tabs li.selected').removeClass('loading'); 1966 1967 }, 'json' ); 1968 } 1969 1970 /* Hide long lists of activity comments, only show the latest five root comments. */ 1971 function bp_legacy_theme_hide_comments() { 1972 var comments_divs = jq('div.activity-comments'), 1973 parent_li, comment_lis, comment_count; 1974 1975 if ( !comments_divs.length ) { 1976 return false; 1977 } 1978 1979 comments_divs.each( function() { 1980 if ( jq(this).children('ul').children('li').length < 5 ) { 1981 return; 1982 } 1983 1984 comments_div = jq(this); 1985 parent_li = comments_div.parents('#activity-stream > li'); 1986 comment_lis = jq(this).children('ul').children('li'); 1987 comment_count = ' '; 1988 1989 if ( jq('#' + parent_li.attr('id') + ' li').length ) { 1990 comment_count = jq('#' + parent_li.attr('id') + ' li').length; 1991 } 1992 1993 comment_lis.each( function(i) { 1994 /* Show the latest 5 root comments */ 1995 if ( i < comment_lis.length - 5 ) { 1996 jq(this).hide(); 1997 1998 if ( !i ) { 1999 jq(this).before( '<li class="show-all"><a href="#' + parent_li.attr('id') + '/show-all/">' + BP_DTheme.show_x_comments.replace( '%d', comment_count ) + '</a></li>' ); 2000 } 2001 } 2002 }); 2003 2004 }); 2005 } 2006 2007 /* Helper Functions */ 2008 2009 function checkAll() { 2010 var checkboxes = document.getElementsByTagName('input'), 2011 i; 2012 2013 for(i=0; i<checkboxes.length; i++) { 2014 if(checkboxes[i].type === 'checkbox') { 2015 if($('check_all').checked === '') { 2016 checkboxes[i].checked = ''; 2017 } 2018 else { 2019 checkboxes[i].checked = 'checked'; 2020 } 2021 } 2022 } 2023 } 2024 2025 /** 2026 * Deselects any select options or input options for the specified field element. 2027 * 2028 * @param {String} container HTML ID of the field 2029 * @since 1.2.0 2030 */ 2031 function clear( container ) { 2032 container = document.getElementById( container ); 2033 if ( ! container ) { 2034 return; 2035 } 2036 2037 var radioButtons = container.getElementsByTagName( 'INPUT' ), 2038 options = container.getElementsByTagName( 'OPTION' ), 2039 i = 0; 2040 2041 if ( radioButtons ) { 2042 for ( i = 0; i < radioButtons.length; i++ ) { 2043 radioButtons[i].checked = ''; 2044 } 2045 } 2046 2047 if ( options ) { 2048 for ( i = 0; i < options.length; i++ ) { 2049 options[i].selected = false; 2050 } 2051 } 2052 } 2053 2054 /* Returns a querystring of BP cookies (cookies beginning with 'bp-') */ 2055 function bp_get_cookies() { 2056 var allCookies = document.cookie.split(';'), // get all cookies and split into an array 2057 bpCookies = {}, 2058 cookiePrefix = 'bp-', 2059 i, cookie, delimiter, name, value; 2060 2061 // loop through cookies 2062 for (i = 0; i < allCookies.length; i++) { 2063 cookie = allCookies[i]; 2064 delimiter = cookie.indexOf('='); 2065 name = jq.trim( unescape( cookie.slice(0, delimiter) ) ); 2066 value = unescape( cookie.slice(delimiter + 1) ); 2067 2068 // if BP cookie, store it 2069 if ( name.indexOf(cookiePrefix) === 0 ) { 2070 bpCookies[name] = value; 2071 } 2072 } 2073 2074 // returns BP cookies as querystring 2075 return encodeURIComponent( jq.param(bpCookies) ); 2076 } 2077 2078 /** 2079 * Get a querystring parameter from a URL. 2080 * 2081 * @param {String} Query string parameter name. 2082 * @param {String} URL to parse. Defaults to current URL. 2083 */ 2084 function bp_get_query_var( param, url ) { 2085 var qs = {}; 2086 2087 // Use current URL if no URL passed. 2088 if ( typeof url === 'undefined' ) { 2089 url = location.search.substr(1).split('&'); 2090 } else { 2091 url = url.split('?')[1].split('&'); 2092 } 2093 2094 // Parse querystring into object props. 2095 // http://stackoverflow.com/a/21152762 2096 url.forEach(function(item) { 2097 qs[item.split('=')[0]] = item.split('=')[1] && decodeURIComponent( item.split('=')[1] ); 2098 }); 2099 2100 if ( qs.hasOwnProperty( param ) && qs[param] != null ) { 2101 return qs[param]; 2102 } else { 2103 return false; 2104 } 2105 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Mar 4 01:01:38 2021 | Cross-referenced by PHPXref 0.7.1 |