2 * Attaches behaviors for the Tracker module's History module integration.
4 * May only be loaded for authenticated users, with the History module enabled.
6 (function ($, Drupal, window) {
8 * Render "new" and "updated" node indicators, as well as "X new" replies links.
10 Drupal.behaviors.trackerHistory = {
12 // Find all "new" comment indicator placeholders newer than 30 days ago that
13 // have not already been read after their last comment timestamp.
15 const $nodeNewPlaceholders = $(context)
16 .find('[data-history-node-timestamp]')
19 const nodeTimestamp = parseInt(this.getAttribute('data-history-node-timestamp'), 10);
20 const nodeID = this.getAttribute('data-history-node-id');
21 if (Drupal.history.needsServerCheck(nodeID, nodeTimestamp)) {
29 // Find all "new" comment indicator placeholders newer than 30 days ago that
30 // have not already been read after their last comment timestamp.
31 const $newRepliesPlaceholders = $(context)
32 .find('[data-history-node-last-comment-timestamp]')
35 const lastCommentTimestamp = parseInt(this.getAttribute('data-history-node-last-comment-timestamp'), 10);
36 const nodeTimestamp = parseInt(this.previousSibling.previousSibling.getAttribute('data-history-node-timestamp'), 10);
37 // Discard placeholders that have zero comments.
38 if (lastCommentTimestamp === nodeTimestamp) {
41 const nodeID = this.previousSibling.previousSibling.getAttribute('data-history-node-id');
42 if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
43 if (nodeIDs.indexOf(nodeID) === -1) {
52 if ($nodeNewPlaceholders.length === 0 && $newRepliesPlaceholders.length === 0) {
56 // Fetch the node read timestamps from the server.
57 Drupal.history.fetchTimestamps(nodeIDs, () => {
58 processNodeNewIndicators($nodeNewPlaceholders);
59 processNewRepliesIndicators($newRepliesPlaceholders);
64 function processNodeNewIndicators($placeholders) {
65 const newNodeString = Drupal.t('new');
66 const updatedNodeString = Drupal.t('updated');
68 $placeholders.each((index, placeholder) => {
69 const timestamp = parseInt(placeholder.getAttribute('data-history-node-timestamp'), 10);
70 const nodeID = placeholder.getAttribute('data-history-node-id');
71 const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
73 if (timestamp > lastViewTimestamp) {
74 const message = (lastViewTimestamp === 0) ? newNodeString : updatedNodeString;
75 $(placeholder).append(`<span class="marker">${message}</span>`);
80 function processNewRepliesIndicators($placeholders) {
81 // Figure out which placeholders need the "x new" replies links.
82 const placeholdersToUpdate = {};
83 $placeholders.each((index, placeholder) => {
84 const timestamp = parseInt(placeholder.getAttribute('data-history-node-last-comment-timestamp'), 10);
85 const nodeID = placeholder.previousSibling.previousSibling.getAttribute('data-history-node-id');
86 const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
88 // Queue this placeholder's "X new" replies link to be downloaded from the
90 if (timestamp > lastViewTimestamp) {
91 placeholdersToUpdate[nodeID] = placeholder;
95 // Perform an AJAX request to retrieve node view timestamps.
96 const nodeIDs = Object.keys(placeholdersToUpdate);
97 if (nodeIDs.length === 0) {
101 url: Drupal.url('comments/render_new_comments_node_links'),
103 data: { 'node_ids[]': nodeIDs },
106 for (const nodeID in results) {
107 if (results.hasOwnProperty(nodeID) && placeholdersToUpdate.hasOwnProperty(nodeID)) {
108 const url = results[nodeID].first_new_comment_link;
109 const text = Drupal.formatPlural(results[nodeID].new_comment_count, '1 new', '@count new');
110 $(placeholdersToUpdate[nodeID]).append(`<br /><a href="${url}">${text}</a>`);
116 }(jQuery, Drupal, window));