annotate core/modules/comment/js/node-new-comments-link.es6.js @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
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@17 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@17 20 return (
Chris@17 21 $placeholder
Chris@17 22 // Find the parent <li>.
Chris@17 23 .closest('.comment-new-comments')
Chris@17 24 // Find the preceding <li>, if any, and give it the 'last' class.
Chris@17 25 .prev()
Chris@17 26 .addClass('last')
Chris@17 27 // Go back to the parent <li> and hide it.
Chris@17 28 .end()
Chris@17 29 .hide()
Chris@17 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@17 53 return (
Chris@17 54 $placeholder
Chris@17 55 // Find the parent <li>.
Chris@17 56 .closest('.comment-new-comments')
Chris@17 57 // Find the preceding <li>, if any, and remove its 'last' class, if any.
Chris@17 58 .prev()
Chris@17 59 .removeClass('last')
Chris@17 60 // Go back to the parent <li> and show it.
Chris@17 61 .end()
Chris@17 62 .show()
Chris@17 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@17 79 const timestamp = parseInt(
Chris@17 80 $placeholder.attr('data-history-node-last-comment-timestamp'),
Chris@17 81 10,
Chris@17 82 );
Chris@0 83 fieldName = $placeholder.attr('data-history-node-field-name');
Chris@17 84 const nodeID = $placeholder
Chris@17 85 .closest('[data-history-node-id]')
Chris@17 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@17 116 Object.keys(results || {}).forEach(nodeID => {
Chris@14 117 if ($placeholdersToUpdate.hasOwnProperty(nodeID)) {
Chris@0 118 $placeholdersToUpdate[nodeID]
Chris@0 119 .attr('href', results[nodeID].first_new_comment_link)
Chris@17 120 .text(
Chris@17 121 Drupal.formatPlural(
Chris@17 122 results[nodeID].new_comment_count,
Chris@17 123 '1 new comment',
Chris@17 124 '@count new comments',
Chris@17 125 ),
Chris@17 126 )
Chris@0 127 .removeClass('hidden');
Chris@0 128 show($placeholdersToUpdate[nodeID]);
Chris@0 129 }
Chris@14 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@17 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@17 145
Chris@17 146 /**
Chris@17 147 * Render "X new comments" links wherever necessary.
Chris@17 148 *
Chris@17 149 * @type {Drupal~behavior}
Chris@17 150 *
Chris@17 151 * @prop {Drupal~behaviorAttach} attach
Chris@17 152 * Attaches new comment links behavior.
Chris@17 153 */
Chris@17 154 Drupal.behaviors.nodeNewCommentsLink = {
Chris@17 155 attach(context) {
Chris@17 156 // Collect all "X new comments" node link placeholders (and their
Chris@17 157 // corresponding node IDs) newer than 30 days ago that have not already
Chris@17 158 // been read after their last comment timestamp.
Chris@17 159 const nodeIDs = [];
Chris@17 160 const $placeholders = $(context)
Chris@17 161 .find('[data-history-node-last-comment-timestamp]')
Chris@17 162 .once('history')
Chris@17 163 .filter(function() {
Chris@17 164 const $placeholder = $(this);
Chris@17 165 const lastCommentTimestamp = parseInt(
Chris@17 166 $placeholder.attr('data-history-node-last-comment-timestamp'),
Chris@17 167 10,
Chris@17 168 );
Chris@17 169 const nodeID = $placeholder
Chris@17 170 .closest('[data-history-node-id]')
Chris@17 171 .attr('data-history-node-id');
Chris@17 172 if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
Chris@17 173 nodeIDs.push(nodeID);
Chris@17 174 // Hide this placeholder link until it is certain we'll need it.
Chris@17 175 hide($placeholder);
Chris@17 176 return true;
Chris@17 177 }
Chris@17 178
Chris@17 179 // Remove this placeholder link from the DOM because we won't need
Chris@17 180 // it.
Chris@17 181 remove($placeholder);
Chris@17 182 return false;
Chris@17 183 });
Chris@17 184
Chris@17 185 if ($placeholders.length === 0) {
Chris@17 186 return;
Chris@17 187 }
Chris@17 188
Chris@17 189 // Perform an AJAX request to retrieve node read timestamps.
Chris@17 190 Drupal.history.fetchTimestamps(nodeIDs, () => {
Chris@17 191 processNodeNewCommentLinks($placeholders);
Chris@17 192 });
Chris@17 193 },
Chris@17 194 };
Chris@17 195 })(jQuery, Drupal, drupalSettings);