knowledge-8.x-1.x-dev/js/knowledge-new-indicator.es6.js
js/knowledge-new-indicator.es6.js
/**
* @file
* Attaches behaviors for the Knowledge module's "new" indicator.
*
* May only be loaded for authenticated users, with the History module
* installed.
*/
(function ($, Drupal, window) {
/**
* Processes the markup for "new knowledge" indicators.
*
* @param {Array.<Element>} placeholders
* The elements that should be processed.
*/
function processKnowledgeNewIndicators(placeholders) {
let isFirstNewKnowledge = true;
const newKnowledgeString = Drupal.t('new');
let $placeholder;
placeholders.forEach((placeholder) => {
$placeholder = $(placeholder);
const timestamp = parseInt(
$placeholder.attr('data-knowledge-timestamp'),
10,
);
const $node = $placeholder.closest('[data-history-node-id]');
const nodeID = $node.attr('data-history-node-id');
const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
if (timestamp > lastViewTimestamp) {
// Turn the placeholder into an actual "new" indicator.
placeholder.textContent = newKnowledgeString;
$placeholder
.removeClass('hidden')
.closest('.js-knowledge')
// Add 'new' class to the knowledge, so it can be styled.
.addClass('new');
// Insert "new" anchor just before the "knowledge-<kid>" anchor if
// this is the first new knowledge in the DOM.
if (isFirstNewKnowledge) {
isFirstNewKnowledge = false;
$placeholder.prev().before('<a id="new"></a>');
// If the URL points to the first new knowledge, then scroll to that
// knowledge.
if (window.location.hash === '#new') {
window.scrollTo(
0,
$placeholder.offset().top - Drupal.displace.offsets.top,
);
}
}
}
});
}
/**
* Renders "new" knowledge indicators wherever necessary.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches "new" knowledge indicators behavior.
*/
Drupal.behaviors.knowledgeNewIndicator = {
attach(context) {
// Collect all "new" knowledge indicator placeholders (and their
// corresponding node IDs) newer than 30 days ago that have not already
// been read after their last knowledge timestamp.
const nodeIDs = [];
const placeholders = once(
'history',
'[data-knowledge-timestamp]',
context,
).filter((placeholder) => {
const $placeholder = $(placeholder);
const knowledgeTimestamp = parseInt(
$placeholder.attr('data-knowledge-timestamp'),
10,
);
const nodeID = $placeholder
.closest('[data-history-node-id]')
.attr('data-history-node-id');
if (Drupal.history.needsServerCheck(nodeID, knowledgeTimestamp)) {
nodeIDs.push(nodeID);
return true;
}
return false;
});
if (placeholders.length === 0) {
return;
}
// Fetch the node read timestamps from the server.
Drupal.history.fetchTimestamps(nodeIDs, () => {
processKnowledgeNewIndicators(placeholders);
});
},
};
})(jQuery, Drupal, window);
