diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-admin/js/edit-comments.js --- a/wp/wp-admin/js/edit-comments.js Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-admin/js/edit-comments.js Tue Dec 15 13:49:49 2020 +0100 @@ -1,16 +1,31 @@ /** + * Handles updating and editing comments. + * + * @file This file contains functionality for the admin comments page. + * @since 2.1.0 * @output wp-admin/js/edit-comments.js */ -/* global adminCommentsL10n, thousandsSeparator, list_args, QTags, ajaxurl, wpAjax */ +/* global adminCommentsSettings, thousandsSeparator, list_args, QTags, ajaxurl, wpAjax */ /* global commentReply, theExtraList, theList, setCommentsList */ (function($) { var getCount, updateCount, updateCountText, updatePending, updateApproved, updateHtmlTitle, updateDashboardText, updateInModerationText, adminTitle = document.title, isDashboard = $('#dashboard_right_now').length, - titleDiv, titleRegEx; + titleDiv, titleRegEx, + __ = wp.i18n.__; + /** + * Extracts a number from the content of a jQuery element. + * + * @since 2.9.0 + * @access private + * + * @param {jQuery} el jQuery element. + * + * @return {number} The number found in the given element. + */ getCount = function(el) { var n = parseInt( el.html().replace(/[^0-9]+/g, ''), 10 ); if ( isNaN(n) ) { @@ -19,6 +34,17 @@ return n; }; + /** + * Updates an html element with a localized number string. + * + * @since 2.9.0 + * @access private + * + * @param {jQuery} el The jQuery element to update. + * @param {number} n Number to be put in the element. + * + * @return {void} + */ updateCount = function(el, n) { var n1 = ''; if ( isNaN(n) ) { @@ -35,6 +61,17 @@ el.html(n); }; + /** + * Updates the number of approved comments on a specific post and the filter bar. + * + * @since 4.4.0 + * @access private + * + * @param {number} diff The amount to lower or raise the approved count with. + * @param {number} commentPostId The ID of the post to be updated. + * + * @return {void} + */ updateApproved = function( diff, commentPostId ) { var postSelector = '.post-com-count-' + commentPostId, noClass = 'comment-count-no-comments', @@ -48,7 +85,7 @@ return; } - // cache selectors to not get dupes + // Cache selectors to not get duplicates. approved = $( 'span.' + approvedClass, postSelector ); noComments = $( 'span.' + noClass, postSelector ); @@ -76,6 +113,18 @@ }); }; + /** + * Updates a number count in all matched HTML elements + * + * @since 4.4.0 + * @access private + * + * @param {string} selector The jQuery selector for elements to update a count + * for. + * @param {number} diff The amount to lower or raise the count with. + * + * @return {void} + */ updateCountText = function( selector, diff ) { $( selector ).each(function() { var a = $(this), n = getCount(a) + diff; @@ -86,6 +135,17 @@ }); }; + /** + * Updates a text about comment count on the dashboard. + * + * @since 4.4.0 + * @access private + * + * @param {Object} response Ajax response from the server that includes a + * translated "comment count" message. + * + * @return {void} + */ updateDashboardText = function( response ) { if ( ! isDashboard || ! response || ! response.i18n_comments_text ) { return; @@ -99,7 +159,8 @@ * * @since 5.2.0 * - * @param {object} response Ajax response from the server. + * @param {Object} response Ajax response from the server that includes a + * translated "comments in moderation" message. * * @return {void} */ @@ -117,11 +178,23 @@ } }; + /** + * Updates the title of the document with the number comments to be approved. + * + * @since 4.4.0 + * @access private + * + * @param {number} diff The amount to lower or raise the number of to be + * approved comments with. + * + * @return {void} + */ updateHtmlTitle = function( diff ) { var newTitle, regExMatch, titleCount, commentFrag; - titleRegEx = titleRegEx || new RegExp( adminCommentsL10n.docTitleCommentsCount.replace( '%s', '\\([0-9' + thousandsSeparator + ']+\\)' ) + '?' ); - // count funcs operate on a $'d element + /* translators: %s: Comments count. */ + titleRegEx = titleRegEx || new RegExp( __( 'Comments (%s)' ).replace( '%s', '\\([0-9' + thousandsSeparator + ']+\\)' ) + '?' ); + // Count funcs operate on a $'d element. titleDiv = titleDiv || $( '
' ); newTitle = adminTitle; @@ -139,17 +212,29 @@ updateCount( titleDiv, titleCount ); regExMatch = titleRegEx.exec( document.title ); if ( regExMatch ) { - newTitle = document.title.replace( regExMatch[0], adminCommentsL10n.docTitleCommentsCount.replace( '%s', titleDiv.text() ) + ' ' ); + /* translators: %s: Comments count. */ + newTitle = document.title.replace( regExMatch[0], __( 'Comments (%s)' ).replace( '%s', titleDiv.text() ) + ' ' ); } } else { regExMatch = titleRegEx.exec( newTitle ); if ( regExMatch ) { - newTitle = newTitle.replace( regExMatch[0], adminCommentsL10n.docTitleComments ); + newTitle = newTitle.replace( regExMatch[0], __( 'Comments' ) ); } } document.title = newTitle; }; + /** + * Updates the number of pending comments on a specific post and the filter bar. + * + * @since 3.2.0 + * @access private + * + * @param {number} diff The amount to lower or raise the pending count with. + * @param {number} commentPostId The ID of the post to be updated. + * + * @return {void} + */ updatePending = function( diff, commentPostId ) { var postSelector = '.post-com-count-' + commentPostId, noClass = 'comment-count-no-pending', @@ -174,7 +259,7 @@ return; } - // cache selectors to not get dupes + // Cache selectors to not get dupes. pending = $( 'span.' + pendingClass, postSelector ); noPending = $( 'span.' + noClass, postSelector ); @@ -206,6 +291,15 @@ }); }; +/** + * Initializes the comments list. + * + * @since 4.4.0 + * + * @global + * + * @return {void} + */ window.setCommentsList = function() { var totalInput, perPageInput, pageInput, dimAfter, delBefore, updateTotalCount, delAfter, refillTheExtraList, diff, lastConfidentTime = 0; @@ -214,7 +308,26 @@ perPageInput = $('input[name="_per_page"]', '#comments-form'); pageInput = $('input[name="_page"]', '#comments-form'); - // Updates the current total (stored in the _total input) + /** + * Updates the total with the latest count. + * + * The time parameter makes sure that we only update the total if this value is + * a newer value than we previously received. + * + * The time and setConfidentTime parameters make sure that we only update the + * total when necessary. So a value that has been generated earlier will not + * update the total. + * + * @since 2.8.0 + * @access private + * + * @param {number} total Total number of comments. + * @param {number} time Unix timestamp of response. + * @param {boolean} setConfidentTime Whether to update the last confident time + * with the given time. + * + * @return {void} + */ updateTotalCount = function( total, time, setConfidentTime ) { if ( time < lastConfidentTime ) return; @@ -225,7 +338,17 @@ totalInput.val( total.toString() ); }; - // this fires when viewing "All" + /** + * Changes DOM that need to be changed after a list item has been dimmed. + * + * @since 2.5.0 + * @access private + * + * @param {Object} r Ajax response object. + * @param {Object} settings Settings for the wpList object. + * + * @return {void} + */ dimAfter = function( r, settings ) { var editRow, replyID, replyButton, response, c = $( '#' + settings.element ); @@ -240,14 +363,14 @@ if ( c.is('.unapproved') ) { if ( settings.data.id == replyID ) - replyButton.text(adminCommentsL10n.replyApprove); + replyButton.text( __( 'Approve and Reply' ) ); c.find( '.row-actions span.view' ).addClass( 'hidden' ).end() .find( 'div.comment_status' ).html( '0' ); } else { if ( settings.data.id == replyID ) - replyButton.text(adminCommentsL10n.reply); + replyButton.text( __( 'Reply' ) ); c.find( '.row-actions span.view' ).removeClass( 'hidden' ).end() .find( 'div.comment_status' ).html( '1' ); @@ -265,7 +388,19 @@ } }; - // Send current total, page, per_page and url + /** + * Handles marking a comment as spam or trashing the comment. + * + * Is executed in the list delBefore hook. + * + * @since 2.8.0 + * @access private + * + * @param {Object} settings Settings for the wpList object. + * @param {HTMLElement} list Comments table element. + * + * @return {Object} The settings object. + */ delBefore = function( settings, list ) { var note, id, el, n, h, a, author, action = false, @@ -312,7 +447,7 @@ a.click(function( e ){ e.preventDefault(); - e.stopPropagation(); // ticket #35904 + e.stopPropagation(); // Ticket #35904. list.wpList.del(this); $('#undo-' + id).css( {backgroundColor:'#ceb'} ).fadeOut(350, function(){ $(this).remove(); @@ -324,7 +459,21 @@ return settings; }; - // In admin-ajax.php, we send back the unix time stamp instead of 1 on success + /** + * Handles actions that need to be done after marking as spam or thrashing a + * comment. + * + * The ajax requests return the unix time stamp a comment was marked as spam or + * trashed. We use this to have a correct total amount of comments. + * + * @since 2.5.0 + * @access private + * + * @param {Object} r Ajax response object. + * @param {Object} settings Settings for the wpList object. + * + * @return {void} + */ delAfter = function( r, settings ) { var total_items_i18n, total, animated, animatedCallback, response = true === settings.parsed ? {} : settings.parsed.responses[0], @@ -345,17 +494,19 @@ unapproved = commentRow.hasClass( 'unapproved' ), spammed = commentRow.hasClass( 'spam' ), trashed = commentRow.hasClass( 'trash' ), - undoing = false; // ticket #35904 + undoing = false; // Ticket #35904. updateDashboardText( newTotal ); updateInModerationText( newTotal ); - // the order of these checks is important - // .unspam can also have .approve or .unapprove - // .untrash can also have .approve or .unapprove + /* + * The order of these checks is important. + * .unspam can also have .approve or .unapprove. + * .untrash can also have .approve or .unapprove. + */ if ( targetParent.is( 'span.undo' ) ) { - // the comment was spammed + // The comment was spammed. if ( targetParent.hasClass( 'unspam' ) ) { spamDiff = -1; @@ -367,7 +518,7 @@ pendingDiff = 1; } - // the comment was trashed + // The comment was trashed. } else if ( targetParent.hasClass( 'untrash' ) ) { trashDiff = -1; @@ -382,32 +533,32 @@ undoing = true; - // user clicked "Spam" + // User clicked "Spam". } else if ( targetParent.is( 'span.spam' ) ) { - // the comment is currently approved + // The comment is currently approved. if ( approved ) { approvedDiff = -1; - // the comment is currently pending + // The comment is currently pending. } else if ( unapproved ) { pendingDiff = -1; - // the comment was in the trash + // The comment was in the Trash. } else if ( trashed ) { trashDiff = -1; } - // you can't spam an item on the spam screen + // You can't spam an item on the Spam screen. spamDiff = 1; - // user clicked "Unspam" + // User clicked "Unspam". } else if ( targetParent.is( 'span.unspam' ) ) { if ( approved ) { pendingDiff = 1; } else if ( unapproved ) { approvedDiff = 1; } else if ( trashed ) { - // the comment was previously approved + // The comment was previously approved. if ( targetParent.hasClass( 'approve' ) ) { approvedDiff = 1; - // the comment was previously pending + // The comment was previously pending. } else if ( targetParent.hasClass( 'unapprove' ) ) { pendingDiff = 1; } @@ -419,23 +570,23 @@ pendingDiff = 1; } } - // you can Unspam an item on the spam screen + // You can unspam an item on the Spam screen. spamDiff = -1; - // user clicked "Trash" + // User clicked "Trash". } else if ( targetParent.is( 'span.trash' ) ) { if ( approved ) { approvedDiff = -1; } else if ( unapproved ) { pendingDiff = -1; - // the comment was in the spam queue + // The comment was in the spam queue. } else if ( spammed ) { spamDiff = -1; } - // you can't trash an item on the trash screen + // You can't trash an item on the Trash screen. trashDiff = 1; - // user clicked "Restore" + // User clicked "Restore". } else if ( targetParent.is( 'span.untrash' ) ) { if ( approved ) { pendingDiff = 1; @@ -448,21 +599,21 @@ pendingDiff = 1; } } - // you can't go from trash to spam - // you can untrash on the trash screen + // You can't go from Trash to Spam. + // You can untrash on the Trash screen. trashDiff = -1; - // User clicked "Approve" + // User clicked "Approve". } else if ( targetParent.is( 'span.approve:not(.unspam):not(.untrash)' ) ) { approvedDiff = 1; pendingDiff = -1; - // User clicked "Unapprove" + // User clicked "Unapprove". } else if ( targetParent.is( 'span.unapprove:not(.unspam):not(.untrash)' ) ) { approvedDiff = -1; pendingDiff = 1; - // User clicked "Delete Permanently" + // User clicked "Delete Permanently". } else if ( targetParent.is( 'span.delete' ) ) { if ( spammed ) { spamDiff = -1; @@ -510,8 +661,8 @@ if ( response.supplemental.total_items_i18n && lastConfidentTime < response.supplemental.time ) { total_items_i18n = response.supplemental.total_items_i18n || ''; if ( total_items_i18n ) { - $('.displaying-num').text( total_items_i18n ); - $('.total-pages').text( response.supplemental.total_pages_i18n ); + $('.displaying-num').text( total_items_i18n.replace( ' ', String.fromCharCode( 160 ) ) ); + $('.total-pages').text( response.supplemental.total_pages_i18n.replace( ' ', String.fromCharCode( 160 ) ) ); $('.tablenav-pages').find('.next-page, .last-page').toggleClass('disabled', response.supplemental.total_pages == $('.current-page').val()); } updateTotalCount( total, response.supplemental.time, true ); @@ -545,6 +696,16 @@ } }; + /** + * Retrieves additional comments to populate the extra list. + * + * @since 3.1.0 + * @access private + * + * @param {boolean} [ev] Repopulate the extra comments list if true. + * + * @return {void} + */ refillTheExtraList = function(ev) { var args = $.query.get(), total_pages = $('.total-pages').text(), per_page = $('input[name="_per_page"]', '#comments-form').val(); @@ -557,17 +718,17 @@ if (ev) { theExtraList.empty(); - args.number = Math.min(8, per_page); // see WP_Comments_List_Table::prepare_items() @ class-wp-comments-list-table.php + args.number = Math.min(8, per_page); // See WP_Comments_List_Table::prepare_items() in class-wp-comments-list-table.php. } else { args.number = 1; - args.offset = Math.min(8, per_page) - 1; // fetch only the next item on the extra list + args.offset = Math.min(8, per_page) - 1; // Fetch only the next item on the extra list. } args.no_placeholder = true; args.paged ++; - // $.query.get() needs some correction to be sent into an ajax request + // $.query.get() needs some correction to be sent into an Ajax request. if ( true === args.comment_type ) args.comment_type = ''; @@ -588,7 +749,18 @@ }); }; + /** + * Globally available jQuery object referring to the extra comments list. + * + * @global + */ window.theExtraList = $('#the-extra-comment-list').wpList( { alt: '', delColor: 'none', addColor: 'none' } ); + + /** + * Globally available jQuery object referring to the comments list. + * + * @global + */ window.theList = $('#the-comment-list').wpList( { alt: '', delBefore: delBefore, dimAfter: dimAfter, delAfter: delAfter, addColor: 'none' } ) .bind('wpListDelEnd', function(e, s){ var wpListsData = $(s.target).attr('data-wp-lists'), id = s.element.replace(/[^0-9]+/g, ''); @@ -598,11 +770,26 @@ }); }; +/** + * Object containing functionality regarding the comment quick editor and reply + * editor. + * + * @since 2.7.0 + * + * @global + */ window.commentReply = { cid : '', act : '', originalContent : '', + /** + * Initializes the comment reply functionality. + * + * @since 2.7.0 + * + * @memberof commentReply + */ init : function() { var row = $('#replyrow'); @@ -616,7 +803,7 @@ } }); - // add events + // Add events. $('#the-comment-list .column-comment > p').dblclick(function(){ commentReply.toggle($(this).parent()); }); @@ -629,6 +816,19 @@ this.comments_listing = $('#comments-form > input[name="comment_status"]').val() || ''; }, + /** + * Adds doubleclick event handler to the given comment list row. + * + * The double-click event will toggle the comment edit or reply form. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @param {Object} r The row to add double click handlers to. + * + * @return {void} + */ addEvents : function(r) { r.each(function() { $(this).find('.column-comment > p').dblclick(function(){ @@ -637,12 +837,32 @@ }); }, + /** + * Opens the quick edit for the given element. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @param {HTMLElement} el The element you want to open the quick editor for. + * + * @return {void} + */ toggle : function(el) { - if ( 'none' !== $( el ).css( 'display' ) && ( $( '#replyrow' ).parent().is('#com-reply') || window.confirm( adminCommentsL10n.warnQuickEdit ) ) ) { - $( el ).find( 'a.vim-q' ).click(); + if ( 'none' !== $( el ).css( 'display' ) && ( $( '#replyrow' ).parent().is('#com-reply') || window.confirm( __( 'Are you sure you want to edit this comment?\nThe changes you made will be lost.' ) ) ) ) { + $( el ).find( 'button.vim-q' ).click(); } }, + /** + * Closes the comment quick edit or reply form and undoes any changes. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @return {void} + */ revert : function() { if ( $('#the-comment-list #replyrow').length < 1 ) @@ -653,11 +873,20 @@ }); }, + /** + * Closes the comment quick edit or reply form and undoes any changes. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @return {void} + */ close : function() { var commentRow = $(), replyRow = $( '#replyrow' ); - // replyrow is not showing? + // Return if the replyrow is not showing. if ( replyRow.parent().is( '#com-reply' ) ) { return; } @@ -687,8 +916,8 @@ .focus(); } - // reset the Quicktags buttons - if ( typeof QTags != 'undefined' ) + // Reset the Quicktags buttons. + if ( typeof QTags != 'undefined' ) QTags.closeAllTags('replycontent'); $('#add-new-comment').css('display', ''); @@ -706,6 +935,19 @@ this.originalContent = ''; }, + /** + * Opens the comment quick edit or reply form. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @param {number} comment_id The comment ID to open an editor for. + * @param {number} post_id The post ID to open an editor for. + * @param {string} action The action to perform. Either 'edit' or 'replyto'. + * + * @return {boolean} Always false. + */ open : function(comment_id, post_id, action) { var editRow, rowData, act, replyButton, editHeight, t = this, @@ -768,9 +1010,9 @@ c.after(editRow); if ( c.hasClass('unapproved') ) { - replyButton.text(adminCommentsL10n.replyApprove); + replyButton.text( __( 'Approve and Reply' ) ); } else { - replyButton.text(adminCommentsL10n.reply); + replyButton.text( __( 'Reply' ) ); } $('#replyrow').fadeIn(300, function(){ $(this).show(); }); @@ -792,13 +1034,22 @@ $('#replycontent').focus().keyup(function(e){ if ( e.which == 27 ) - commentReply.revert(); // close on Escape + commentReply.revert(); // Close on Escape. }); }, 600); return false; }, + /** + * Submits the comment quick edit or reply form. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @return {void} + */ send : function() { var post = {}, $errorNotice = $( '#replysubmit .error-notice' ); @@ -828,6 +1079,21 @@ }); }, + /** + * Shows the new or updated comment or reply. + * + * This function needs to be passed the ajax result as received from the server. + * It will handle the response and show the comment that has just been saved to + * the server. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @param {Object} xml Ajax response object. + * + * @return {void} + */ show : function(xml) { var t = this, r, c, id, bg, pid; @@ -869,7 +1135,7 @@ updateCountText( 'span.all-count', 1 ); } - c = $.trim(r.data); // Trim leading whitespaces + c = $.trim(r.data); // Trim leading whitespaces. $(c).hide(); $('#replyrow').after(c); @@ -889,6 +1155,17 @@ }, + /** + * Shows an error for the failed comment update or reply. + * + * @since 2.7.0 + * + * @memberof commentReply + * + * @param {string} r The Ajax response. + * + * @return {void} + */ error : function(r) { var er = r.statusText, $errorNotice = $( '#replysubmit .notice-error' ), @@ -905,6 +1182,17 @@ } }, + /** + * Opens the add comments form in the comments metabox on the post edit page. + * + * @since 3.4.0 + * + * @memberof commentReply + * + * @param {number} post_id The post ID. + * + * @return {void} + */ addcomment: function(post_id) { var t = this; @@ -916,10 +1204,14 @@ }, /** - * Alert the user if they have unsaved changes on a comment that will be - * lost if they proceed. + * Alert the user if they have unsaved changes on a comment that will be lost if + * they proceed with the intended action. * - * @returns {boolean} + * @since 4.6.0 + * + * @memberof commentReply + * + * @return {boolean} Whether it is safe the continue with the intended action. */ discardCommentChanges: function() { var editRow = $( '#replyrow' ); @@ -928,7 +1220,7 @@ return true; } - return window.confirm( adminCommentsL10n.warnCommentChanges ); + return window.confirm( __( 'Are you sure you want to do this?\nThe comment changes you made will be lost.' ) ); } }; @@ -943,6 +1235,16 @@ }); if ( typeof $.table_hotkeys != 'undefined' ) { + /** + * Creates a function that navigates to a previous or next page. + * + * @since 2.7.0 + * @access private + * + * @param {string} which What page to navigate to: either next or prev. + * + * @return {Function} The function that executes the navigation. + */ make_hotkeys_redirect = function(which) { return function() { var first_last, l; @@ -954,14 +1256,43 @@ }; }; + /** + * Navigates to the edit page for the selected comment. + * + * @since 2.7.0 + * @access private + * + * @param {Object} event The event that triggered this action. + * @param {Object} current_row A jQuery object of the selected row. + * + * @return {void} + */ edit_comment = function(event, current_row) { window.location = $('span.edit a', current_row).attr('href'); }; + /** + * Toggles all comments on the screen, for bulk actions. + * + * @since 2.7.0 + * @access private + * + * @return {void} + */ toggle_all = function() { $('#cb-select-all-1').data( 'wp-toggle', 1 ).trigger( 'click' ).removeData( 'wp-toggle' ); }; + /** + * Creates a bulk action function that is executed on all selected comments. + * + * @since 2.7.0 + * @access private + * + * @param {string} value The name of the action to execute. + * + * @return {Function} The function that executes the bulk action. + */ make_bulk = function(value) { return function() { var scope = $('select[name="action"]'); @@ -984,8 +1315,8 @@ ['shift+u', make_bulk('unapprove')] ], { - highlight_first: adminCommentsL10n.hotkeys_highlight_first, - highlight_last: adminCommentsL10n.hotkeys_highlight_last, + highlight_first: adminCommentsSettings.hotkeys_highlight_first, + highlight_last: adminCommentsSettings.hotkeys_highlight_last, prev_page_link_cb: make_hotkeys_redirect('prev'), next_page_link_cb: make_hotkeys_redirect('next'), hotkeys_opts: {