3 * Attaches behaviors for the Comment module's "X new comments" link.
5 * May only be loaded for authenticated users, with the History module
9 (function ($, Drupal, drupalSettings) {
11 * Render "X new comments" links wherever necessary.
13 * @type {Drupal~behavior}
15 * @prop {Drupal~behaviorAttach} attach
16 * Attaches new comment links behavior.
18 Drupal.behaviors.nodeNewCommentsLink = {
20 // Collect all "X new comments" node link placeholders (and their
21 // corresponding node IDs) newer than 30 days ago that have not already
22 // been read after their last comment timestamp.
24 const $placeholders = $(context)
25 .find('[data-history-node-last-comment-timestamp]')
28 const $placeholder = $(this);
29 const lastCommentTimestamp = parseInt($placeholder.attr('data-history-node-last-comment-timestamp'), 10);
30 const nodeID = $placeholder.closest('[data-history-node-id]').attr('data-history-node-id');
31 if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
33 // Hide this placeholder link until it is certain we'll need it.
38 // Remove this placeholder link from the DOM because we won't need
44 if ($placeholders.length === 0) {
48 // Perform an AJAX request to retrieve node read timestamps.
49 Drupal.history.fetchTimestamps(nodeIDs, () => {
50 processNodeNewCommentLinks($placeholders);
56 * Hides a "new comment" element.
58 * @param {jQuery} $placeholder
59 * The placeholder element of the new comment link.
62 * The placeholder element passed in as a parameter.
64 function hide($placeholder) {
66 // Find the parent <li>.
67 .closest('.comment-new-comments')
68 // Find the preceding <li>, if any, and give it the 'last' class.
71 // Go back to the parent <li> and hide it.
77 * Removes a "new comment" element.
79 * @param {jQuery} $placeholder
80 * The placeholder element of the new comment link.
82 function remove($placeholder) {
83 hide($placeholder).remove();
87 * Shows a "new comment" element.
89 * @param {jQuery} $placeholder
90 * The placeholder element of the new comment link.
93 * The placeholder element passed in as a parameter.
95 function show($placeholder) {
97 // Find the parent <li>.
98 .closest('.comment-new-comments')
99 // Find the preceding <li>, if any, and remove its 'last' class, if any.
102 // Go back to the parent <li> and show it.
108 * Processes new comment links and adds appropriate text in relevant cases.
110 * @param {jQuery} $placeholders
111 * The placeholder elements of the current page.
113 function processNodeNewCommentLinks($placeholders) {
114 // Figure out which placeholders need the "x new comments" links.
115 const $placeholdersToUpdate = {};
116 let fieldName = 'comment';
118 $placeholders.each((index, placeholder) => {
119 $placeholder = $(placeholder);
120 const timestamp = parseInt($placeholder.attr('data-history-node-last-comment-timestamp'), 10);
121 fieldName = $placeholder.attr('data-history-node-field-name');
122 const nodeID = $placeholder.closest('[data-history-node-id]').attr('data-history-node-id');
123 const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
125 // Queue this placeholder's "X new comments" link to be downloaded from
127 if (timestamp > lastViewTimestamp) {
128 $placeholdersToUpdate[nodeID] = $placeholder;
130 // No "X new comments" link necessary; remove it from the DOM.
132 remove($placeholder);
136 // Perform an AJAX request to retrieve node view timestamps.
137 const nodeIDs = Object.keys($placeholdersToUpdate);
138 if (nodeIDs.length === 0) {
143 * Renders the "X new comments" links.
145 * Either use the data embedded in the page or perform an AJAX request to
146 * retrieve the same data.
148 * @param {object} results
149 * Data about new comment links indexed by nodeID.
151 function render(results) {
152 Object.keys(results || {}).forEach((nodeID) => {
153 if ($placeholdersToUpdate.hasOwnProperty(nodeID)) {
154 $placeholdersToUpdate[nodeID]
155 .attr('href', results[nodeID].first_new_comment_link)
156 .text(Drupal.formatPlural(results[nodeID].new_comment_count, '1 new comment', '@count new comments'))
157 .removeClass('hidden');
158 show($placeholdersToUpdate[nodeID]);
163 if (drupalSettings.comment && drupalSettings.comment.newCommentsLinks) {
164 render(drupalSettings.comment.newCommentsLinks.node[fieldName]);
168 url: Drupal.url('comments/render_new_comments_node_links'),
170 data: { 'node_ids[]': nodeIDs, field_name: fieldName },
176 }(jQuery, Drupal, drupalSettings));