Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 44 additions & 33 deletions lib/rdoc/generator/template/aliki/js/aliki.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,54 +209,65 @@ function generateToc() {

function hookTocActiveHighlighting() {
var tocLinks = document.querySelectorAll('.toc-link');
if (tocLinks.length === 0) return;
var targetHeadings = [];
tocLinks.forEach(function(link) {
var targetId = link.getAttribute('data-target');
var heading = document.getElementById(targetId);
if (heading) {
targetHeadings.push(heading);
}
});

if (targetHeadings.length === 0) return;

var observerOptions = {
root: null,
rootMargin: '-20% 0px -35% 0px',
rootMargin: '0% 0px -35% 0px',
threshold: 0
};

var activeLink = null;
var intersectingHeadings = new Set();
function update() {
var firstIntersectingHeading = targetHeadings.find(function(heading) {
return intersectingHeadings.has(heading);
});
if (!firstIntersectingHeading) return;
var correspondingLink = document.querySelector('.toc-link[data-target="' + firstIntersectingHeading.id + '"]');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be simpler:

Suggested change
var correspondingLink = document.querySelector('.toc-link[data-target="' + firstIntersectingHeading.id + '"]');
var correspondingLink = document.querySelector(`.toc-link[data-target="${firstIntersectingHeading.id}"]`);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to keep it for now.
Currently this file doesn't use ES6 feature: const let ()=>{} and `${}`
I think we can use newer syntaxes, but I think it's better to do it in a separate pull request.

if (!correspondingLink) return;

// Remove active class from all links
tocLinks.forEach(function(link) {
link.classList.remove('active');
});

// Add active class to current link
correspondingLink.classList.add('active');

// Scroll link into view if needed
var tocNav = document.querySelector('#toc-nav');
if (tocNav) {
var linkRect = correspondingLink.getBoundingClientRect();
var navRect = tocNav.getBoundingClientRect();

if (linkRect.top < navRect.top || linkRect.bottom > navRect.bottom) {
correspondingLink.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}
}
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var id = entry.target.id;
var correspondingLink = document.querySelector('.toc-link[data-target="' + id + '"]');

if (correspondingLink) {
// Remove active class from all links
tocLinks.forEach(function(link) {
link.classList.remove('active');
});

// Add active class to current link
correspondingLink.classList.add('active');
activeLink = correspondingLink;

// Scroll link into view if needed
var tocNav = document.querySelector('#toc-nav');
if (tocNav) {
var linkRect = correspondingLink.getBoundingClientRect();
var navRect = tocNav.getBoundingClientRect();

if (linkRect.top < navRect.top || linkRect.bottom > navRect.bottom) {
correspondingLink.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}
}
intersectingHeadings.add(entry.target);
} else {
intersectingHeadings.delete(entry.target);
}
});
update();
}, observerOptions);

// Observe all headings that have corresponding TOC links
tocLinks.forEach(function(link) {
var targetId = link.getAttribute('data-target');
var targetHeading = document.getElementById(targetId);
if (targetHeading) {
observer.observe(targetHeading);
}
targetHeadings.forEach(function(heading) {
observer.observe(heading);
});

// Smooth scroll when clicking TOC links
Expand Down