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 * Hides a "new comment" element.
13 * @param {jQuery} $placeholder
14 * The placeholder element of the new comment link.
17 * The placeholder element passed in as a parameter.
19 function hide($placeholder) {
22 // Find the parent <li>.
23 .closest('.comment-new-comments')
24 // Find the preceding <li>, if any, and give it the 'last' class.
27 // Go back to the parent <li> and hide it.
34 * Removes a "new comment" element.
36 * @param {jQuery} $placeholder
37 * The placeholder element of the new comment link.
39 function remove($placeholder) {
40 hide($placeholder).remove();
44 * Shows a "new comment" element.
46 * @param {jQuery} $placeholder
47 * The placeholder element of the new comment link.
50 * The placeholder element passed in as a parameter.
52 function show($placeholder) {
55 // Find the parent <li>.
56 .closest('.comment-new-comments')
57 // Find the preceding <li>, if any, and remove its 'last' class, if any.
60 // Go back to the parent <li> and show it.
67 * Processes new comment links and adds appropriate text in relevant cases.
69 * @param {jQuery} $placeholders
70 * The placeholder elements of the current page.
72 function processNodeNewCommentLinks($placeholders) {
73 // Figure out which placeholders need the "x new comments" links.
74 const $placeholdersToUpdate = {};
75 let fieldName = 'comment';
77 $placeholders.each((index, placeholder) => {
78 $placeholder = $(placeholder);
79 const timestamp = parseInt(
80 $placeholder.attr('data-history-node-last-comment-timestamp'),
83 fieldName = $placeholder.attr('data-history-node-field-name');
84 const nodeID = $placeholder
85 .closest('[data-history-node-id]')
86 .attr('data-history-node-id');
87 const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
89 // Queue this placeholder's "X new comments" link to be downloaded from
91 if (timestamp > lastViewTimestamp) {
92 $placeholdersToUpdate[nodeID] = $placeholder;
94 // No "X new comments" link necessary; remove it from the DOM.
100 // Perform an AJAX request to retrieve node view timestamps.
101 const nodeIDs = Object.keys($placeholdersToUpdate);
102 if (nodeIDs.length === 0) {
107 * Renders the "X new comments" links.
109 * Either use the data embedded in the page or perform an AJAX request to
110 * retrieve the same data.
112 * @param {object} results
113 * Data about new comment links indexed by nodeID.
115 function render(results) {
116 Object.keys(results || {}).forEach(nodeID => {
117 if ($placeholdersToUpdate.hasOwnProperty(nodeID)) {
118 $placeholdersToUpdate[nodeID]
119 .attr('href', results[nodeID].first_new_comment_link)
122 results[nodeID].new_comment_count,
124 '@count new comments',
127 .removeClass('hidden');
128 show($placeholdersToUpdate[nodeID]);
133 if (drupalSettings.comment && drupalSettings.comment.newCommentsLinks) {
134 render(drupalSettings.comment.newCommentsLinks.node[fieldName]);
137 url: Drupal.url('comments/render_new_comments_node_links'),
139 data: { 'node_ids[]': nodeIDs, field_name: fieldName },
147 * Render "X new comments" links wherever necessary.
149 * @type {Drupal~behavior}
151 * @prop {Drupal~behaviorAttach} attach
152 * Attaches new comment links behavior.
154 Drupal.behaviors.nodeNewCommentsLink = {
156 // Collect all "X new comments" node link placeholders (and their
157 // corresponding node IDs) newer than 30 days ago that have not already
158 // been read after their last comment timestamp.
160 const $placeholders = $(context)
161 .find('[data-history-node-last-comment-timestamp]')
164 const $placeholder = $(this);
165 const lastCommentTimestamp = parseInt(
166 $placeholder.attr('data-history-node-last-comment-timestamp'),
169 const nodeID = $placeholder
170 .closest('[data-history-node-id]')
171 .attr('data-history-node-id');
172 if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
173 nodeIDs.push(nodeID);
174 // Hide this placeholder link until it is certain we'll need it.
179 // Remove this placeholder link from the DOM because we won't need
181 remove($placeholder);
185 if ($placeholders.length === 0) {
189 // Perform an AJAX request to retrieve node read timestamps.
190 Drupal.history.fetchTimestamps(nodeIDs, () => {
191 processNodeNewCommentLinks($placeholders);
195 })(jQuery, Drupal, drupalSettings);