Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / tracker / js / tracker-history.es6.js
diff --git a/web/core/modules/tracker/js/tracker-history.es6.js b/web/core/modules/tracker/js/tracker-history.es6.js
new file mode 100644 (file)
index 0000000..5df3494
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * Attaches behaviors for the Tracker module's History module integration.
+ *
+ * May only be loaded for authenticated users, with the History module enabled.
+ */
+(function ($, Drupal, window) {
+  /**
+   * Render "new" and "updated" node indicators, as well as "X new" replies links.
+   */
+  Drupal.behaviors.trackerHistory = {
+    attach(context) {
+      // Find all "new" comment indicator placeholders newer than 30 days ago that
+      // have not already been read after their last comment timestamp.
+      const nodeIDs = [];
+      const $nodeNewPlaceholders = $(context)
+        .find('[data-history-node-timestamp]')
+        .once('history')
+        .filter(function () {
+          const nodeTimestamp = parseInt(this.getAttribute('data-history-node-timestamp'), 10);
+          const nodeID = this.getAttribute('data-history-node-id');
+          if (Drupal.history.needsServerCheck(nodeID, nodeTimestamp)) {
+            nodeIDs.push(nodeID);
+            return true;
+          }
+
+          return false;
+        });
+
+      // Find all "new" comment indicator placeholders newer than 30 days ago that
+      // have not already been read after their last comment timestamp.
+      const $newRepliesPlaceholders = $(context)
+        .find('[data-history-node-last-comment-timestamp]')
+        .once('history')
+        .filter(function () {
+          const lastCommentTimestamp = parseInt(this.getAttribute('data-history-node-last-comment-timestamp'), 10);
+          const nodeTimestamp = parseInt(this.previousSibling.previousSibling.getAttribute('data-history-node-timestamp'), 10);
+          // Discard placeholders that have zero comments.
+          if (lastCommentTimestamp === nodeTimestamp) {
+            return false;
+          }
+          const nodeID = this.previousSibling.previousSibling.getAttribute('data-history-node-id');
+          if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
+            if (nodeIDs.indexOf(nodeID) === -1) {
+              nodeIDs.push(nodeID);
+            }
+            return true;
+          }
+
+          return false;
+        });
+
+      if ($nodeNewPlaceholders.length === 0 && $newRepliesPlaceholders.length === 0) {
+        return;
+      }
+
+      // Fetch the node read timestamps from the server.
+      Drupal.history.fetchTimestamps(nodeIDs, () => {
+        processNodeNewIndicators($nodeNewPlaceholders);
+        processNewRepliesIndicators($newRepliesPlaceholders);
+      });
+    },
+  };
+
+  function processNodeNewIndicators($placeholders) {
+    const newNodeString = Drupal.t('new');
+    const updatedNodeString = Drupal.t('updated');
+
+    $placeholders.each((index, placeholder) => {
+      const timestamp = parseInt(placeholder.getAttribute('data-history-node-timestamp'), 10);
+      const nodeID = placeholder.getAttribute('data-history-node-id');
+      const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
+
+      if (timestamp > lastViewTimestamp) {
+        const message = (lastViewTimestamp === 0) ? newNodeString : updatedNodeString;
+        $(placeholder).append(`<span class="marker">${message}</span>`);
+      }
+    });
+  }
+
+  function processNewRepliesIndicators($placeholders) {
+    // Figure out which placeholders need the "x new" replies links.
+    const placeholdersToUpdate = {};
+    $placeholders.each((index, placeholder) => {
+      const timestamp = parseInt(placeholder.getAttribute('data-history-node-last-comment-timestamp'), 10);
+      const nodeID = placeholder.previousSibling.previousSibling.getAttribute('data-history-node-id');
+      const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
+
+      // Queue this placeholder's "X new" replies link to be downloaded from the
+      // server.
+      if (timestamp > lastViewTimestamp) {
+        placeholdersToUpdate[nodeID] = placeholder;
+      }
+    });
+
+    // Perform an AJAX request to retrieve node view timestamps.
+    const nodeIDs = Object.keys(placeholdersToUpdate);
+    if (nodeIDs.length === 0) {
+      return;
+    }
+    $.ajax({
+      url: Drupal.url('comments/render_new_comments_node_links'),
+      type: 'POST',
+      data: { 'node_ids[]': nodeIDs },
+      dataType: 'json',
+      success(results) {
+        for (const nodeID in results) {
+          if (results.hasOwnProperty(nodeID) && placeholdersToUpdate.hasOwnProperty(nodeID)) {
+            const url = results[nodeID].first_new_comment_link;
+            const text = Drupal.formatPlural(results[nodeID].new_comment_count, '1 new', '@count new');
+            $(placeholdersToUpdate[nodeID]).append(`<br /><a href="${url}">${text}</a>`);
+          }
+        }
+      },
+    });
+  }
+}(jQuery, Drupal, window));