comment-new-indicator.es6.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * @file
  3. * Attaches behaviors for the Comment module's "new" indicator.
  4. *
  5. * May only be loaded for authenticated users, with the History module
  6. * installed.
  7. */
  8. (function($, Drupal, window) {
  9. /**
  10. * Processes the markup for "new comment" indicators.
  11. *
  12. * @param {jQuery} $placeholders
  13. * The elements that should be processed.
  14. */
  15. function processCommentNewIndicators($placeholders) {
  16. let isFirstNewComment = true;
  17. const newCommentString = Drupal.t('new');
  18. let $placeholder;
  19. $placeholders.each((index, placeholder) => {
  20. $placeholder = $(placeholder);
  21. const timestamp = parseInt(
  22. $placeholder.attr('data-comment-timestamp'),
  23. 10,
  24. );
  25. const $node = $placeholder.closest('[data-history-node-id]');
  26. const nodeID = $node.attr('data-history-node-id');
  27. const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
  28. if (timestamp > lastViewTimestamp) {
  29. // Turn the placeholder into an actual "new" indicator.
  30. const $comment = $(placeholder)
  31. .removeClass('hidden')
  32. .text(newCommentString)
  33. .closest('.js-comment')
  34. // Add 'new' class to the comment, so it can be styled.
  35. .addClass('new');
  36. // Insert "new" anchor just before the "comment-<cid>" anchor if
  37. // this is the first new comment in the DOM.
  38. if (isFirstNewComment) {
  39. isFirstNewComment = false;
  40. $comment.prev().before('<a id="new"></a>');
  41. // If the URL points to the first new comment, then scroll to that
  42. // comment.
  43. if (window.location.hash === '#new') {
  44. window.scrollTo(
  45. 0,
  46. $comment.offset().top - Drupal.displace.offsets.top,
  47. );
  48. }
  49. }
  50. }
  51. });
  52. }
  53. /**
  54. * Renders "new" comment indicators wherever necessary.
  55. *
  56. * @type {Drupal~behavior}
  57. *
  58. * @prop {Drupal~behaviorAttach} attach
  59. * Attaches "new" comment indicators behavior.
  60. */
  61. Drupal.behaviors.commentNewIndicator = {
  62. attach(context) {
  63. // Collect all "new" comment indicator placeholders (and their
  64. // corresponding node IDs) newer than 30 days ago that have not already
  65. // been read after their last comment timestamp.
  66. const nodeIDs = [];
  67. const $placeholders = $(context)
  68. .find('[data-comment-timestamp]')
  69. .once('history')
  70. .filter(function() {
  71. const $placeholder = $(this);
  72. const commentTimestamp = parseInt(
  73. $placeholder.attr('data-comment-timestamp'),
  74. 10,
  75. );
  76. const nodeID = $placeholder
  77. .closest('[data-history-node-id]')
  78. .attr('data-history-node-id');
  79. if (Drupal.history.needsServerCheck(nodeID, commentTimestamp)) {
  80. nodeIDs.push(nodeID);
  81. return true;
  82. }
  83. return false;
  84. });
  85. if ($placeholders.length === 0) {
  86. return;
  87. }
  88. // Fetch the node read timestamps from the server.
  89. Drupal.history.fetchTimestamps(nodeIDs, () => {
  90. processCommentNewIndicators($placeholders);
  91. });
  92. },
  93. };
  94. })(jQuery, Drupal, window);