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) {
14 * Render "X new comments" links wherever necessary.
16 * @type {Drupal~behavior}
18 * @prop {Drupal~behaviorAttach} attach
19 * Attaches new comment links behavior.
21 Drupal.behaviors.nodeNewCommentsLink = {
22 attach: function (context) {
23 // Collect all "X new comments" node link placeholders (and their
24 // corresponding node IDs) newer than 30 days ago that have not already
25 // been read after their last comment timestamp.
27 var $placeholders = $(context)
28 .find('[data-history-node-last-comment-timestamp]')
31 var $placeholder = $(this);
32 var lastCommentTimestamp = parseInt($placeholder.attr('data-history-node-last-comment-timestamp'), 10);
33 var nodeID = $placeholder.closest('[data-history-node-id]').attr('data-history-node-id');
34 if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
36 // Hide this placeholder link until it is certain we'll need it.
41 // Remove this placeholder link from the DOM because we won't need
48 if ($placeholders.length === 0) {
52 // Perform an AJAX request to retrieve node read timestamps.
53 Drupal.history.fetchTimestamps(nodeIDs, function () {
54 processNodeNewCommentLinks($placeholders);
60 * Hides a "new comment" element.
62 * @param {jQuery} $placeholder
63 * The placeholder element of the new comment link.
66 * The placeholder element passed in as a parameter.
68 function hide($placeholder) {
70 // Find the parent <li>.
71 .closest('.comment-new-comments')
72 // Find the preceding <li>, if any, and give it the 'last' class.
73 .prev().addClass('last')
74 // Go back to the parent <li> and hide it.
79 * Removes a "new comment" element.
81 * @param {jQuery} $placeholder
82 * The placeholder element of the new comment link.
84 function remove($placeholder) {
85 hide($placeholder).remove();
89 * Shows a "new comment" element.
91 * @param {jQuery} $placeholder
92 * The placeholder element of the new comment link.
95 * The placeholder element passed in as a parameter.
97 function show($placeholder) {
99 // Find the parent <li>.
100 .closest('.comment-new-comments')
101 // Find the preceding <li>, if any, and remove its 'last' class, if any.
102 .prev().removeClass('last')
103 // 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 var $placeholdersToUpdate = {};
116 var fieldName = 'comment';
118 $placeholders.each(function (index, placeholder) {
119 $placeholder = $(placeholder);
120 var timestamp = parseInt($placeholder.attr('data-history-node-last-comment-timestamp'), 10);
121 fieldName = $placeholder.attr('data-history-node-field-name');
122 var nodeID = $placeholder.closest('[data-history-node-id]').attr('data-history-node-id');
123 var 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 var 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 for (var nodeID in results) {
153 if (results.hasOwnProperty(nodeID) && $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},
177 })(jQuery, Drupal, drupalSettings);