123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /**
- * @file
- * Attaches behaviors for the Comment module's "X new comments" link.
- *
- * May only be loaded for authenticated users, with the History module
- * installed.
- */
- (function($, Drupal, drupalSettings) {
- /**
- * Hides a "new comment" element.
- *
- * @param {jQuery} $placeholder
- * The placeholder element of the new comment link.
- *
- * @return {jQuery}
- * The placeholder element passed in as a parameter.
- */
- function hide($placeholder) {
- return (
- $placeholder
- // Find the parent <li>.
- .closest('.comment-new-comments')
- // Find the preceding <li>, if any, and give it the 'last' class.
- .prev()
- .addClass('last')
- // Go back to the parent <li> and hide it.
- .end()
- .hide()
- );
- }
- /**
- * Removes a "new comment" element.
- *
- * @param {jQuery} $placeholder
- * The placeholder element of the new comment link.
- */
- function remove($placeholder) {
- hide($placeholder).remove();
- }
- /**
- * Shows a "new comment" element.
- *
- * @param {jQuery} $placeholder
- * The placeholder element of the new comment link.
- *
- * @return {jQuery}
- * The placeholder element passed in as a parameter.
- */
- function show($placeholder) {
- return (
- $placeholder
- // Find the parent <li>.
- .closest('.comment-new-comments')
- // Find the preceding <li>, if any, and remove its 'last' class, if any.
- .prev()
- .removeClass('last')
- // Go back to the parent <li> and show it.
- .end()
- .show()
- );
- }
- /**
- * Processes new comment links and adds appropriate text in relevant cases.
- *
- * @param {jQuery} $placeholders
- * The placeholder elements of the current page.
- */
- function processNodeNewCommentLinks($placeholders) {
- // Figure out which placeholders need the "x new comments" links.
- const $placeholdersToUpdate = {};
- let fieldName = 'comment';
- let $placeholder;
- $placeholders.each((index, placeholder) => {
- $placeholder = $(placeholder);
- const timestamp = parseInt(
- $placeholder.attr('data-history-node-last-comment-timestamp'),
- 10,
- );
- fieldName = $placeholder.attr('data-history-node-field-name');
- const nodeID = $placeholder
- .closest('[data-history-node-id]')
- .attr('data-history-node-id');
- const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
- // Queue this placeholder's "X new comments" link to be downloaded from
- // the server.
- if (timestamp > lastViewTimestamp) {
- $placeholdersToUpdate[nodeID] = $placeholder;
- }
- // No "X new comments" link necessary; remove it from the DOM.
- else {
- remove($placeholder);
- }
- });
- // Perform an AJAX request to retrieve node view timestamps.
- const nodeIDs = Object.keys($placeholdersToUpdate);
- if (nodeIDs.length === 0) {
- return;
- }
- /**
- * Renders the "X new comments" links.
- *
- * Either use the data embedded in the page or perform an AJAX request to
- * retrieve the same data.
- *
- * @param {object} results
- * Data about new comment links indexed by nodeID.
- */
- function render(results) {
- Object.keys(results || {}).forEach(nodeID => {
- if ($placeholdersToUpdate.hasOwnProperty(nodeID)) {
- $placeholdersToUpdate[nodeID]
- .attr('href', results[nodeID].first_new_comment_link)
- .text(
- Drupal.formatPlural(
- results[nodeID].new_comment_count,
- '1 new comment',
- '@count new comments',
- ),
- )
- .removeClass('hidden');
- show($placeholdersToUpdate[nodeID]);
- }
- });
- }
- if (drupalSettings.comment && drupalSettings.comment.newCommentsLinks) {
- render(drupalSettings.comment.newCommentsLinks.node[fieldName]);
- } else {
- $.ajax({
- url: Drupal.url('comments/render_new_comments_node_links'),
- type: 'POST',
- data: { 'node_ids[]': nodeIDs, field_name: fieldName },
- dataType: 'json',
- success: render,
- });
- }
- }
- /**
- * Render "X new comments" links wherever necessary.
- *
- * @type {Drupal~behavior}
- *
- * @prop {Drupal~behaviorAttach} attach
- * Attaches new comment links behavior.
- */
- Drupal.behaviors.nodeNewCommentsLink = {
- attach(context) {
- // Collect all "X new comments" node link placeholders (and their
- // corresponding node IDs) newer than 30 days ago that have not already
- // been read after their last comment timestamp.
- const nodeIDs = [];
- const $placeholders = $(context)
- .find('[data-history-node-last-comment-timestamp]')
- .once('history')
- .filter(function() {
- const $placeholder = $(this);
- const lastCommentTimestamp = parseInt(
- $placeholder.attr('data-history-node-last-comment-timestamp'),
- 10,
- );
- const nodeID = $placeholder
- .closest('[data-history-node-id]')
- .attr('data-history-node-id');
- if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
- nodeIDs.push(nodeID);
- // Hide this placeholder link until it is certain we'll need it.
- hide($placeholder);
- return true;
- }
- // Remove this placeholder link from the DOM because we won't need
- // it.
- remove($placeholder);
- return false;
- });
- if ($placeholders.length === 0) {
- return;
- }
- // Perform an AJAX request to retrieve node read timestamps.
- Drupal.history.fetchTimestamps(nodeIDs, () => {
- processNodeNewCommentLinks($placeholders);
- });
- },
- };
- })(jQuery, Drupal, drupalSettings);
|