From 1031c61d0c191aeec0707d6dff755fca7ab291a2 Mon Sep 17 00:00:00 2001 From: Abijeet Date: Thu, 2 Nov 2017 01:14:06 +0530 Subject: [PATCH] Fixes #466. Adds support for header highlighting using intersection observer. --- resources/assets/js/pages/page-show.js | 53 ++++++++++++++++++++++++++ resources/assets/sass/_lists.scss | 3 ++ 2 files changed, 56 insertions(+) diff --git a/resources/assets/js/pages/page-show.js b/resources/assets/js/pages/page-show.js index 14437cd68..15acddf85 100644 --- a/resources/assets/js/pages/page-show.js +++ b/resources/assets/js/pages/page-show.js @@ -150,6 +150,59 @@ let setupPageShow = window.setupPageShow = function (pageId) { unstickTree(); } }); + + + // Check if support is present for IntersectionObserver + if ('IntersectionObserver' in window && + 'IntersectionObserverEntry' in window && + 'intersectionRatio' in window.IntersectionObserverEntry.prototype) { + $(document).ready(function () { + // fetch all the headings. + let headings = document.querySelector('.page-content').querySelectorAll('h1, h2, h3, h4, h5, h6'); + // if headings are present, add observers. + if (headings.length > 0) { + addNavObserver(headings); + } + }); + } + + let $pageNav = null; + function addNavObserver(headings) { + // Setup the intersection observer. + // margin top = -25px to trigger the threshold change before the heading + // has completely left the viewport on the top. + let intersectOpts = { + rootMargin: '-25px 0px 0px 0px', + threshold: 1.0 + } + $pageNav = $('.sidebar-page-nav'); + let pageNavObserver = new IntersectionObserver(cbHeadingVisible, intersectOpts); + + // observe each heading + for (let i = 0; i !== headings.length; ++i) { + pageNavObserver.observe(headings[i]); + } + } + + function cbHeadingVisible(entries, observer) { + let element = null; + for (let i = 0; i !== entries.length; ++i) { + let currentEntry = entries[i]; + // check if its currently visible and its distance from top of viewport is less than 100 + if (currentEntry.intersectionRatio <= 1 && currentEntry.boundingClientRect.y < 100) { + element = currentEntry.target; + } else { + break; + } + } + if (!element) { + return; + } + let elementId = element.id; + $pageNav.find('a').removeClass('current-heading'); + $pageNav.find('a[href="#' + elementId + '"]').addClass('current-heading'); + } + }; module.exports = setupPageShow; \ No newline at end of file diff --git a/resources/assets/sass/_lists.scss b/resources/assets/sass/_lists.scss index d30d4d4a2..298ce32cb 100644 --- a/resources/assets/sass/_lists.scss +++ b/resources/assets/sass/_lists.scss @@ -82,6 +82,9 @@ .h6 { margin-left: $nav-indent*4; } + .current-heading { + font-weight: bold; + } } // Sidebar list