annotate core/modules/comment/js/node-new-comments-link.es6.js @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents a9cd425dd02b
children
rev   line source
Chris@0 1 /**
Chris@0 2 * @file
Chris@0 3 * Attaches behaviors for the Comment module's "X new comments" link.
Chris@0 4 *
Chris@0 5 * May only be loaded for authenticated users, with the History module
Chris@0 6 * installed.
Chris@0 7 */
Chris@0 8
Chris@4 9 (function($, Drupal, drupalSettings) {
Chris@0 10 /**
Chris@0 11 * Hides a "new comment" element.
Chris@0 12 *
Chris@0 13 * @param {jQuery} $placeholder
Chris@0 14 * The placeholder element of the new comment link.
Chris@0 15 *
Chris@0 16 * @return {jQuery}
Chris@0 17 * The placeholder element passed in as a parameter.
Chris@0 18 */
Chris@0 19 function hide($placeholder) {
Chris@4 20 return (
Chris@4 21 $placeholder
Chris@4 22 // Find the parent <li>.
Chris@4 23 .closest('.comment-new-comments')
Chris@4 24 // Find the preceding <li>, if any, and give it the 'last' class.
Chris@4 25 .prev()
Chris@4 26 .addClass('last')
Chris@4 27 // Go back to the parent <li> and hide it.
Chris@4 28 .end()
Chris@4 29 .hide()
Chris@4 30 );
Chris@0 31 }
Chris@0 32
Chris@0 33 /**
Chris@0 34 * Removes a "new comment" element.
Chris@0 35 *
Chris@0 36 * @param {jQuery} $placeholder
Chris@0 37 * The placeholder element of the new comment link.
Chris@0 38 */
Chris@0 39 function remove($placeholder) {
Chris@0 40 hide($placeholder).remove();
Chris@0 41 }
Chris@0 42
Chris@0 43 /**
Chris@0 44 * Shows a "new comment" element.
Chris@0 45 *
Chris@0 46 * @param {jQuery} $placeholder
Chris@0 47 * The placeholder element of the new comment link.
Chris@0 48 *
Chris@0 49 * @return {jQuery}
Chris@0 50 * The placeholder element passed in as a parameter.
Chris@0 51 */
Chris@0 52 function show($placeholder) {
Chris@4 53 return (
Chris@4 54 $placeholder
Chris@4 55 // Find the parent <li>.
Chris@4 56 .closest('.comment-new-comments')
Chris@4 57 // Find the preceding <li>, if any, and remove its 'last' class, if any.
Chris@4 58 .prev()
Chris@4 59 .removeClass('last')
Chris@4 60 // Go back to the parent <li> and show it.
Chris@4 61 .end()
Chris@4 62 .show()
Chris@4 63 );
Chris@0 64 }
Chris@0 65
Chris@0 66 /**
Chris@0 67 * Processes new comment links and adds appropriate text in relevant cases.
Chris@0 68 *
Chris@0 69 * @param {jQuery} $placeholders
Chris@0 70 * The placeholder elements of the current page.
Chris@0 71 */
Chris@0 72 function processNodeNewCommentLinks($placeholders) {
Chris@0 73 // Figure out which placeholders need the "x new comments" links.
Chris@0 74 const $placeholdersToUpdate = {};
Chris@0 75 let fieldName = 'comment';
Chris@0 76 let $placeholder;
Chris@0 77 $placeholders.each((index, placeholder) => {
Chris@0 78 $placeholder = $(placeholder);
Chris@4 79 const timestamp = parseInt(
Chris@4 80 $placeholder.attr('data-history-node-last-comment-timestamp'),
Chris@4 81 10,
Chris@4 82 );
Chris@0 83 fieldName = $placeholder.attr('data-history-node-field-name');
Chris@4 84 const nodeID = $placeholder
Chris@4 85 .closest('[data-history-node-id]')
Chris@4 86 .attr('data-history-node-id');
Chris@0 87 const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
Chris@0 88
Chris@0 89 // Queue this placeholder's "X new comments" link to be downloaded from
Chris@0 90 // the server.
Chris@0 91 if (timestamp > lastViewTimestamp) {
Chris@0 92 $placeholdersToUpdate[nodeID] = $placeholder;
Chris@0 93 }
Chris@0 94 // No "X new comments" link necessary; remove it from the DOM.
Chris@0 95 else {
Chris@0 96 remove($placeholder);
Chris@0 97 }
Chris@0 98 });
Chris@0 99
Chris@0 100 // Perform an AJAX request to retrieve node view timestamps.
Chris@0 101 const nodeIDs = Object.keys($placeholdersToUpdate);
Chris@0 102 if (nodeIDs.length === 0) {
Chris@0 103 return;
Chris@0 104 }
Chris@0 105
Chris@0 106 /**
Chris@0 107 * Renders the "X new comments" links.
Chris@0 108 *
Chris@0 109 * Either use the data embedded in the page or perform an AJAX request to
Chris@0 110 * retrieve the same data.
Chris@0 111 *
Chris@0 112 * @param {object} results
Chris@0 113 * Data about new comment links indexed by nodeID.
Chris@0 114 */
Chris@0 115 function render(results) {
Chris@4 116 Object.keys(results || {}).forEach(nodeID => {
Chris@0 117 if ($placeholdersToUpdate.hasOwnProperty(nodeID)) {
Chris@0 118 $placeholdersToUpdate[nodeID]
Chris@0 119 .attr('href', results[nodeID].first_new_comment_link)
Chris@4 120 .text(
Chris@4 121 Drupal.formatPlural(
Chris@4 122 results[nodeID].new_comment_count,
Chris@4 123 '1 new comment',
Chris@4 124 '@count new comments',
Chris@4 125 ),
Chris@4 126 )
Chris@0 127 .removeClass('hidden');
Chris@0 128 show($placeholdersToUpdate[nodeID]);
Chris@0 129 }
Chris@0 130 });
Chris@0 131 }
Chris@0 132
Chris@0 133 if (drupalSettings.comment && drupalSettings.comment.newCommentsLinks) {
Chris@0 134 render(drupalSettings.comment.newCommentsLinks.node[fieldName]);
Chris@4 135 } else {
Chris@0 136 $.ajax({
Chris@0 137 url: Drupal.url('comments/render_new_comments_node_links'),
Chris@0 138 type: 'POST',
Chris@0 139 data: { 'node_ids[]': nodeIDs, field_name: fieldName },
Chris@0 140 dataType: 'json',
Chris@0 141 success: render,
Chris@0 142 });
Chris@0 143 }
Chris@0 144 }
Chris@4 145
Chris@4 146 /**
Chris@4 147 * Render "X new comments" links wherever necessary.
Chris@4 148 *
Chris@4 149 * @type {Drupal~behavior}
Chris@4 150 *
Chris@4 151 * @prop {Drupal~behaviorAttach} attach
Chris@4 152 * Attaches new comment links behavior.
Chris@4 153 */
Chris@4 154 Drupal.behaviors.nodeNewCommentsLink = {
Chris@4 155 attach(context) {
Chris@4 156 // Collect all "X new comments" node link placeholders (and their
Chris@4 157 // corresponding node IDs) newer than 30 days ago that have not already
Chris@4 158 // been read after their last comment timestamp.
Chris@4 159 const nodeIDs = [];
Chris@4 160 const $placeholders = $(context)
Chris@4 161 .find('[data-history-node-last-comment-timestamp]')
Chris@4 162 .once('history')
Chris@4 163 .filter(function() {
Chris@4 164 const $placeholder = $(this);
Chris@4 165 const lastCommentTimestamp = parseInt(
Chris@4 166 $placeholder.attr('data-history-node-last-comment-timestamp'),
Chris@4 167 10,
Chris@4 168 );
Chris@4 169 const nodeID = $placeholder
Chris@4 170 .closest('[data-history-node-id]')
Chris@4 171 .attr('data-history-node-id');
Chris@4 172 if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
Chris@4 173 nodeIDs.push(nodeID);
Chris@4 174 // Hide this placeholder link until it is certain we'll need it.
Chris@4 175 hide($placeholder);
Chris@4 176 return true;
Chris@4 177 }
Chris@4 178
Chris@4 179 // Remove this placeholder link from the DOM because we won't need
Chris@4 180 // it.
Chris@4 181 remove($placeholder);
Chris@4 182 return false;
Chris@4 183 });
Chris@4 184
Chris@4 185 if ($placeholders.length === 0) {
Chris@4 186 return;
Chris@4 187 }
Chris@4 188
Chris@4 189 // Perform an AJAX request to retrieve node read timestamps.
Chris@4 190 Drupal.history.fetchTimestamps(nodeIDs, () => {
Chris@4 191 processNodeNewCommentLinks($placeholders);
Chris@4 192 });
Chris@4 193 },
Chris@4 194 };
Chris@4 195 })(jQuery, Drupal, drupalSettings);