1function commentFiltering( $, element, order, rating, pageNumber ) { 2 3 var settings = { 4 allow_comment_reviews: element.data( 'allow-comment-reviews' ), 5 show_comment_count_title: element.data( 'show-comment-count-title' ), 6 comment_reply_type: element.data( 'comment-reply-type' ), 7 review_reply_type: element.data( 'review-reply-type' ), 8 avatar_size: { size: element.data( 'avatar-size' ) }, 9 show_verified_user_icon: element.data( 'show-verified-user-icon' ), 10 verified_user_icon_type: element.data( 'verified-user-icon-type' ), 11 verified_user_icon: { value: element.data( 'verified-user-icon' ) }, 12 verified_user_image: { url: element.data( 'verified-user-image' ) }, 13 comment_approval_label: element.data( 'comment-approval-label' ), 14 comment_list_rating_template: element.data( 'comment-list-rating-template' ), 15 allow_up_down_voting: element.data( 'allow-up-down-voting' ), 16 up_down_voting_template: element.data( 'up-down-voting-template' ), 17 reply_link_label: element.data( 'reply-link-label' ), 18 login_reply_link_label: element.data( 'login-reply-link-label' ), 19 comment_count_title_singular: element.data( 'comment-count-title-singular' ), 20 comment_count_title_plural: element.data( 'comment-count-title-plural' ), 21 no_comments_found_label: element.data( 'no-comments-found-label' ), 22 good_points_field_label: element.data( 'good-points-field-label' ), 23 bad_points_field_label: element.data( 'bad-points-field-label' ), 24 good_points_icon: element.data( 'good-points-icon' ), 25 bad_points_icon: element.data( 'bad-points-icon' ), 26 comment_permissions: element.data( 'comment-permissions' ), 27 comment_permission_roles: element.data( 'comment-permission-roles' ), 28 comment_permission_pmpro_levels: element.data( 'comment-permission-pmpro-levels' ) 29 }; 30 31 $.ajax({ 32 type: 'GET', 33 data: { 34 action: 'comment_filtering', 35 postID: element.data( 'post-id' ), 36 userID: element.data( 'user-id' ), 37 settings: settings, 38 order: order, 39 rating: rating, 40 pageNumber: pageNumber, 41 nonce: element.data( 'nonce' ) 42 }, 43 dataType: 'html', 44 url: ghostpool_comment_params.ajax_url, 45 success: function( data, textStatus ) { 46 47 if ( 'success' === textStatus ) { 48 49 // Hide PHP comment pagination 50 $( '.gp-comment-list-wrapper .gp-pagination' ).hide(); 51 52 // Add loading class to comments list 53 $( '.gp-comment-list-wrapper' ).addClass( 'gp-loading' ); 54 55 setTimeout( function() { 56 57 // Add new comment list data 58 var filteredComments = $( data ); 59 $( '.gp-comment-list-inner' ).replaceWith( filteredComments ).removeClass( 'gp-loading' ).fadeIn(); 60 61 //$( '.gp-comments-count-title' ).html( $( data ).find( '.gp-comments-count-title' ) ); 62 63 // Reload ratings script 64 if ( filteredComments.find( '.rating' ).length ) { 65 filteredComments.find( '.rating' ).rating(); 66 } 67 68 $( '.gp-comment-list-wrapper' ).removeClass( 'gp-loading' ); 69 70 }, 800 ); 71 72 } 73 74 }, 75 error: function(e) { 76 //console.log(e); 77 } 78 79 }); 80 81} 82 83jQuery( document ).ready( function( $ ) { 84 85 'use strict'; 86 87 // Review title character limit message 88 $( document ).on( 'keyup', '#gp-review-title', function() { 89 var textLength = $( this ).attr( 'maxlength' ) - $( this ).val().length; 90 $( this ).next( '.gp-character-limit-message' ).find( '.gp-characters-remaining' ).text( textLength ); 91 }); 92 93 // Good points character limit message 94 $( document ).on( 'keyup', '#gp-good-points', function() { 95 var textLength = $( this ).attr( 'maxlength' ) - $( this ).val().length; 96 $( this ).next( '.gp-character-limit-message' ).find( '.gp-characters-remaining' ).text( textLength ); 97 }); 98 99 // Bad points character limit message 100 $( document ).on( 'keyup', '#gp-bad-points', function() { 101 var textLength = $( this ).attr( 'maxlength' ) - $( this ).val().length; 102 $( this ).next( '.gp-character-limit-message' ).find( '.gp-characters-remaining' ).text( textLength ); 103 }); 104 105 106 // Review text character limit message 107 $( document ).on( 'keyup', 'textarea#comment', function() { 108 var textLength = $( this ).attr( 'maxlength' ) - $( this ).val().length; 109 $( this ).next( '.gp-character-limit-message' ).find( '.gp-characters-remaining' ).text( textLength ); 110 }); 111 112 // Remove review title and rating fields from standard replies 113 var reviewTitleField = '', 114 ratingField = '', 115 goodBadPointsField = ''; 116 $( document ).on( 'click touchstart', '.gp-standard-reply a.comment-reply-link', function() { 117 var commentLi = $( this ).closest( 'li' ); 118 reviewTitleField = commentLi.find( '.gp-comment-form-review-title' ).children().detach(); 119 ratingField = commentLi.find( '.gp-form-rating' ).children().detach(); 120 goodBadPointsField = commentLi.find( '.gp-comment-form-good-bad-points' ).children().detach(); 121 }); 122 123 // Readd fields to main comment form when comment cancel link is clicked 124 $( document ).on( 'click touchstart', 'a#cancel-comment-reply-link', function() {
125 if ( '' !== reviewTitleField ) { 126 reviewTitleField.appendTo( '.gp-comment-form-review-title' ); 127 } 128 if ( '' !== ratingField ) { 129 ratingField.appendTo( '.gp-form-rating' ); 130 } 131 if ( '' !== goodBadPointsField ) { 132 goodBadPointsField.appendTo( '.gp-comment-form-good-bad-points' ); 133 } 134 }); 135 136 // Filter comment order 137 $( document ).on( 'change', 'select[name="gp-comment-filter-order-dropdown"]', function() { 138 var element = $( this ).closest( '.gp-comment-filters' ), 139 order = $( this ).val(), 140 rating = ''; 141 if ( $( 'select[name="gp-comment-filter-rating-dropdown"]' ).length ) { 142 rating = $( this ).parent().find( 'select[name="gp-comment-filter-rating-dropdown"]' ).val(); 143 } 144 $( this ).find( 'option[value="' + order + '"]' ).attr( 'selected', 'selected' ); 145 commentFiltering( $, element, order, rating, '' ); 146 return false; 147 }); 148 149 // Filter by comment rating 150 $( document ).on( 'change', 'select[name="gp-comment-filter-rating-dropdown"]', function() { 151 var element = $( this ).closest( '.gp-comment-filters' ), 152 rating = $( this ).val(), 153 order = ''; 154 if ( $( 'select[name="gp-comment-filter-order-dropdown"]' ).length ) { 155 order = $( this ).parent().find( 'select[name="gp-comment-filter-order-dropdown"]' ).val(); 156 } 157 $( this ).find( 'option[value="' + rating + '"]' ).attr( 'selected', 'selected' ); 158 commentFiltering( $, element, order, rating, 1 ); 159 return false; 160 }); 161 162 // Ajax comment pagination 163 $( document ).on( 'click', '.gp-comments-pagination .page-numbers a', function( e ) { 164 165 e.preventDefault(); 166 167 var element = $( this ).closest( '.gp-comment-list-wrapper' ).find( '.gp-comment-filters' ), 168 page_link = $( this ), 169 url = page_link.attr( 'href' ), 170 current_container = page_link.parent(), 171 order = '', 172 rating = ''; 173 174 var pageNumber = ''; 175 if ( page_link.hasClass( 'prev' ) ) { 176 pageNumber = url.split('/comment-page-')[1].split( '/' )[0]; 177 } else if ( page_link.hasClass( 'next' ) ) { 178 pageNumber = url.split('/comment-page-')[1].split( '/' )[0]; 179 } else { 180 pageNumber = page_link.text(); 181 } 182 183 if ( $( 'select[name="gp-comment-filter-order-dropdown"]' ).length ) { 184 order = element.find( 'select[name="gp-comment-filter-order-dropdown"]' ).val(); 185 } 186 187 if ( $( 'select[name="gp-comment-filter-rating-dropdown"]' ).length ) { 188 rating = element.find( 'select[name="gp-comment-filter-rating-dropdown"]' ).val(); 189 } 190 191 page_link.attr( 'href', '#' ); 192 193 commentFiltering( $, element, order, rating, pageNumber ); 194 195 return false; 196 197 }); 198 199 // Submitting comment form 200 $( 'body' ).on( 'submit', '.comments-area #commentform', function( e ) { 201 202 e.preventDefault(); 203 204 var commentForm = $( this ), 205 commentElement = $( this ).closest( '.gp-element-comments' ), 206 action = commentForm.attr( 'action' ), 207 formData = commentForm.serializeArray(), 208 nameField = commentForm.find( '#author' ), 209 emailField = commentForm.find( '#email' ), 210 reviewTitleField = commentForm.find( '#gp-review-title' ), 211 ratingField = commentForm.find( '.gp-element-add-rating' ), 212 goodPointsField = commentForm.find( '#gp-good-points' ), 213 badPointsField = commentForm.find( '#gp-bad-points' ), 214 gp_comment_element_params = commentForm.find( '.gp_comment_element_params' ).data( 'params' ), 215 ratingInputField = commentForm.find( '.gp-element-add-rating .rating' ), 216 commentField = commentForm.find( '#comment' ), 217 hasError = false; 218 219 // Hide success/error messages upon comment submission 220 commentForm.find( '.gp-comment-success-message' ).hide(); 221 commentElement.find( '.gp-comment-error-message' ).hide(); 222 nameField.removeClass( 'gp-required' ); 223 emailField.removeClass( 'gp-required' ); 224 reviewTitleField.removeClass( 'gp-required' ); 225 ratingField.removeClass( 'gp-required' ); 226 goodPointsField.removeClass( 'gp-required' ); 227 badPointsField.removeClass( 'gp-required' ); 228 commentField.removeClass( 'gp-required' ); 229 commentForm.addClass( 'gp-loading' ); 230 231 // Check if name field is empty 232 if ( nameField.length && ( nameField.val() === '' && ( 'true' === nameField.attr( 'aria-required' ) || nameField.attr( 'required' ) ) && ! commentform.closest( 'ol' ).hasClass( 'comment-list' ) ) ) { 233 nameField.addClass( 'gp-required' ); 234 hasError = true; 235 } 236 237 // Check if email field is empty 238 if ( emailField.length && ( emailField.val() === '' && ( 'true' === emailField.attr( 'aria-required' ) || emailField.attr( 'required' ) ) && ! commentform.closest( 'ol' ).hasClass( 'comment-list' ) ) ) { 239 emailField.addClass( 'gp-required' ); 240 hasError = true; 241 } 242 243 // Check if review title field is empty 244 if ( '' === reviewTitleField.val() && 'true' === reviewTitleField.attr( 'required' ) && ! commentForm.closest( 'ol' ).hasClass( 'comment-list' ) ) { 245 reviewTitleField.addClass( 'gp-required' ); 246 hasError = true; 247 } 248 249 // Check if good points field is empty 250 if ( '' === goodPointsField.val() && 'true' === goodPointsField.attr( 'required' ) && ! commentForm.closest( 'ol' ).hasClass( 'comment-list' ) ) { 251 goodPointsField.addClass( 'gp-required' ); 252 hasError = true; 253 } 254 255 // Check if bad points field is empty 256 if ( '' === badPointsField.val() && 'true' === badPointsField.attr( 'required' ) && ! commentForm.closest( 'ol' ).hasClass( 'comment-list' ) ) { 257 badPointsField.addClass( 'gp-required' ); 258 hasError = true; 259 } 260 261 // Check if rating field is empty 262 if ( ratingField.length && ratingField.closest( '.gp-form-rating' ).hasClass( 'gp-required' ) && ! commentForm.closest( 'ol' ).hasClass( 'comment-list' ) ) { 263 264 ratingInputField.each( function( index ) { 265
266 var ratingValue = parseFloat( $( this ).val() ); 267 268 // Set rating to zero if rating is empty 269 if ( '' === ratingValue || 0 === ratingValue ) { 270 hasError = true; 271 ratingField.addClass( 'gp-required' ); 272 return false; 273 } 274 275 // Prevent rating lower than minimum 276 if ( ratingValue < ratingField.data( 'min-rating' ) ) { 277 hasError = true; 278 ratingField.addClass( 'gp-required' ); 279 return false; 280 } 281 282 // Prevent rating higher than maximum 283 if ( ratingValue > ratingField.data( 'max-rating' ) ) { 284 hasError = true; 285 ratingField.addClass( 'gp-required' ); 286 return false; 287 } 288 289 // Final check to make sure a valid rating is being submitted 290 if ( ! $.isNumeric( ratingValue ) ) { 291 hasError = true; 292 ratingField.addClass( 'gp-required' ); 293 return false; 294 } 295 296 }); 297 298 } 299 300 // Check if comment field is empty 301 if ( commentField.val() === '' ) { 302 commentField.addClass( 'gp-required' ); 303 hasError = true; 304 } 305 306 // Show error messages if there is an error 307 if ( true === hasError ) { 308 309 // Show error messages 310 setTimeout( function() { 311 commentForm.removeClass( 'gp-loading' ); 312 commentElement.find( '.gp-comment-success-message' ).hide(); 313 commentElement.find( '.gp-comment-error-message' ).text( commentElement.data( 'error-message' ) ).css({ opacity: 0, display: 'block' }).animate({ opacity:1 }, 600 ); 314 }, 800 ); 315 316 } else { 317 318 // If there's no error, submit comment 319 $.ajax({ 320 type: 'post', 321 url: action, 322 clearForm: true, 323 data: formData, 324 beforeSend: function() {}, 325 success: function( data, textStatus ) { 326 327 if ( textStatus === 'success' ) { 328
329 // Submit comment rating 330 if ( commentElement.find( '.rating' ).length && $.isFunction( window.submitRating ) ) { 331 submitRating( $, ratingField ); 332 } 333 334 // Prevent another rating being sent 335 commentForm.find( 'input, textarea' ).attr( 'disabled', true ); 336 commentForm.find( '.rating' ).attr( 'data-readonly', '' ); 337 338 // Reload comment list from ajax data 339 commentElement.find( '.gp-comment-list' ).replaceWith( $( data ).find( '.comments-area .gp-comment-list' ) ); 340 341 //console.log(data); 342 343 // Reload comment form from ajax data 344 if ( commentElement.find( '#wp-temp-form-div' ).length ) { 345 // If reply comment form 346 commentElement.find( '#wp-temp-form-div' ).replaceWith( $( data ).find( '.comments-area #respond' ) ); 347 } else { 348 // If main comment form 349 commentElement.find( '#respond' ).replaceWith( $( data ).find( '.comments-area #respond' ) ); 350 } 351 352 // Reload ratings script 353 if ( commentElement.find( '.rating' ).length ) { 354 commentElement.find( '.rating' ).rating(); 355 } 356 357 // Add loading class to comment form 358 commentElement.find( '#respond' ).addClass( 'gp-loading' ); 359 360 // Hide already voted messages from showing 361 commentElement.find( '.gp-already-voted' ).hide(); 362 363 // If it's a not a normal reply comment, proceed to update comment breakdown 364 if ( ! commentForm.closest( 'li' ).hasClass( 'gp-standard-reply' ) && $( '.gp-element-show-rating-breakdown' ).length ) { 365 366 var breakdownContainer = $( '.gp-element-show-rating-breakdown' ), 367 postID = breakdownContainer.data( 'post-id' ), 368 maxRating = parseFloat( breakdownContainer.data( 'max-rating' ) ), 369 fractions = parseFloat( breakdownContainer.data( 'fractions' ) ), 370 decimalPlaces = parseFloat( breakdownContainer.data( 'decimal-places' ) ) + 1, 371 ratingSum = parseFloat( breakdownContainer.data( 'rating-sum' ) ), 372 userVotes = parseFloat( breakdownContainer.data( 'user-votes' ) ), 373 userVotesSingularLabel = breakdownContainer.data( 'user-votes-singular-label' ), 374 userVotesPluralLabel = breakdownContainer.data( 'user-votes-plural-label' ), 375 breakdownAverageRating = breakdownContainer.find( '.gp-breakdown-average-rating' ); 376 377 if ( commentElement.find( '.gp-comment-list > li:last-child .rating' ).length ) { 378 var submittedAverageRating = parseFloat( commentElement.find( '.gp-comment-list > li:last-child .rating' ).val() ); 379 } else if ( commentElement.find( '.gp-comment-list > li:last-child .gp-actual-rating' ).length ) { 380 var submittedAverageRating = parseFloat( commentElement.find( '.gp-comment-list > li:last-child .gp-actual-rating' ).text() ); 381 } 382 // Add submitted user rating to current rating sum 383 var newRatingSum = ratingSum + submittedAverageRating; 384 385 // Add 1 to user votes and update user votes text 386 var newUserVotes = userVotes + 1; 387 388 // Get new average rating for post 389 var newPostAverageRatingRaw = newRatingSum / newUserVotes, 390 newPostAverageRating = parseFloat( newPostAverageRatingRaw ).toPrecision( decimalPlaces ); 391 392 // Dynamically update average rating values and user votes 393 breakdownAverageRating.find( '.gp-actual-rating' ).text( newPostAverageRating ); 394 if ( newUserVotes == 1 ) { 395 var userVotesText = ' ' + userVotesSingularLabel; 396 } else { 397 userVotesText = ' ' + userVotesPluralLabel; 398 } 399 breakdownAverageRating.find( '.gp-user-votes-text' ).text( newUserVotes + userVotesText ); 400 breakdownAverageRating.data( 'user-votes', newUserVotes ); 401 402 // Update average rating 403 if ( breakdownAverageRating.find( '.rating' ).length ) { 404 breakdownAverageRating.find( '.rating' ).rating( 'rate', newPostAverageRating ); 405 } 406 407 // Update each breakdown bar 408 $( '.gp-breakdown-entry' ).each( function( index ) { 409 410 var breakdownEntry = $( this ), 411 breakdownRating = parseFloat( breakdownEntry.find( '.gp-breakdown-rating' ).text() ); 412 413 // Dynamically update breakdown rating count 414 if ( submittedAverageRating === breakdownRating ) { 415 var currentRatingCount = parseFloat( breakdownEntry.attr( 'data-current-rating-count' ) ); 416 currentRatingCount = currentRatingCount + 1; 417 breakdownEntry.attr( 'data-current-rating-count', currentRatingCount ); 418 } else { 419 currentRatingCount = parseFloat( breakdownEntry.attr( 'data-current-rating-count' ) ); 420 } 421 422 // Dynamically update breakdown bar 423 var breakdownBarValue = ( currentRatingCount > 0 && newUserVotes > 0 ) ? ( currentRatingCount / newUserVotes ) * maxRating : 0; 424 if ( breakdownEntry.find( '.rating' ).length ) { 425 breakdownEntry.find( '.rating' ).rating( 'rate', breakdownBarValue ); 426 } 427 428 // Dynamically update breakdown percentage 429 if ( currentRatingCount > 0 && newUserVotes > 0 ) { 430 var percentage = Math.round( ( currentRatingCount / newUserVotes ) * 100 ); 431 } else { 432 percentage = 0; 433 } 434 breakdownEntry.find( '.gp-breakdown-percentage' ).text( percentage + '%' ); 435 436 }); 437 438 } 439 440 // Reload comments 441 setTimeout( function() { 442 443 // Hide comment form components 444 if ( 'yes' != commentElement.data( 'multiple-comments' ) ) { 445 commentElement.find( '#respond' ).hide(); 446 } else if ( 'yes' != commentElement.data( 'multiple-ratings' ) ) { 447 commentElement.find( '.gp-comment-form-review-title' ).hide(); 448 commentElement.find( '.gp-form-rating' ).hide(); 449 } 450 451 // Remove loading class from comment form 452 commentElement.find( '#respond' ).removeClass( 'gp-loading' ); 453 454 // Show success message 455 commentElement.find( '.gp-comment-success-message' ).css({ opacity: 0, display: 'block' }).animate({ opacity:1 }, 300 ); 456 457 }, 800 ); 458 459 } 460 461 }, 462 error: function( xhr, textStatus, errorThrown ) { 463 464 //console.log( xhr, textStatus, errorThrown ); 465 466 // Show error messages 467 setTimeout( function() { 468 commentForm.removeClass( 'gp-loading' ); 469 commentElement.find( '.gp-comment-success-message' ).hide(); 470 commentElement.find( '.gp-comment-error-message' ).text( commentElement.data( 'duplicate-comments-message' ) ).css({ opacity: 0, display: 'block' }).animate({ opacity: 1 }, 600 ); 471 }, 800 ); 472 473 } 474 }); 475 476 } 477 478 return false;
479 480 }); 481 482});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.