Jump to content

MediaWiki:Common.js: Difference between revisions

From Grantha
No edit summary
No edit summary
Line 1: Line 1:
/* Grantha.io — chapter nav scroll-spy */
/* Grantha.io — scroll-spy for MW native TOC links */
(function () {
(function () {
     'use strict';
     'use strict';


     function initScrollSpy() {
     mw.hook('wikipage.content').add(function () {
         var nav = document.querySelector('.gr-chapter-nav');
         setTimeout(function () {
        if (!nav) return;
 
            /* Find TOC links — works with both sidebar and inline TOC */
            var tocLinks = Array.from(
                document.querySelectorAll('.vector-toc a, #toc a, .toc a')
            ).filter(function (a) {
                return a.href && a.href.indexOf('#') !== -1;
            });


        var links = Array.from(nav.querySelectorAll('a')).filter(function (a) {
             if (!tocLinks.length) return;
             return a.href && a.href.indexOf('#') !== -1;
        });
        if (!links.length) return;


        var targets = links.map(function (a) {
            var targets = tocLinks.map(function (a) {
            var id = a.href.split('#')[1];
                return document.getElementById(a.href.split('#')[1]);
             return id ? document.getElementById(id) : null;
             });
        });


        function update() {
            function update() {
            /* Try all possible scroll containers — window, html, body,
                var threshold = window.scrollY + 130;
              and MW-specific wrappers */
                var active = 0;
            var scrollY = window.scrollY
                for (var i = 0; i < targets.length; i++) {
                || document.documentElement.scrollTop
                    if (targets[i]) {
                || document.body.scrollTop
                        var el = targets[i], top = 0;
                || 0;
                        while (el) { top += el.offsetTop; el = el.offsetParent; }
            var threshold = scrollY + 130;
                        if (top <= threshold) active = i;
            var active = 0;
                    }
            for (var i = 0; i < targets.length; i++) {
                if (targets[i]) {
                    /* offsetTop walks up to get absolute position */
                    var el = targets[i];
                    var top = 0;
                    while (el) { top += el.offsetTop; el = el.offsetParent; }
                    if (top <= threshold) active = i;
                 }
                 }
                tocLinks.forEach(function (a, i) {
                    a.style.color = (i === active) ? '#f57c00' : '';
                    a.style.fontWeight = (i === active) ? '600' : '';
                });
             }
             }
            links.forEach(function (a, i) {
                a.style.color = (i === active) ? '#f57c00' : '';
                a.style.fontWeight = (i === active) ? '600' : '';
            });
        }


        /* Attach to every possible scroll source */
            window.addEventListener('scroll', update, { passive: true });
        window.addEventListener('scroll', update, { passive: true });
            update();
        document.addEventListener('scroll', update, { passive: true });
        var mwContent = document.getElementById('mw-content-text')
            || document.getElementById('content')
            || document.getElementById('bodyContent');
        if (mwContent) {
            mwContent.addEventListener('scroll', update, { passive: true });
        }


         update();
         }, 400);
    }
 
    mw.hook('wikipage.content').add(function () {
        /* Small delay to let MW finish rendering large pages */
        setTimeout(initScrollSpy, 300);
     });
     });
}());
}());

Revision as of 11:55, 13 April 2026

/* Grantha.io — scroll-spy for MW native TOC links */
(function () {
    'use strict';

    mw.hook('wikipage.content').add(function () {
        setTimeout(function () {

            /* Find TOC links — works with both sidebar and inline TOC */
            var tocLinks = Array.from(
                document.querySelectorAll('.vector-toc a, #toc a, .toc a')
            ).filter(function (a) {
                return a.href && a.href.indexOf('#') !== -1;
            });

            if (!tocLinks.length) return;

            var targets = tocLinks.map(function (a) {
                return document.getElementById(a.href.split('#')[1]);
            });

            function update() {
                var threshold = window.scrollY + 130;
                var active = 0;
                for (var i = 0; i < targets.length; i++) {
                    if (targets[i]) {
                        var el = targets[i], top = 0;
                        while (el) { top += el.offsetTop; el = el.offsetParent; }
                        if (top <= threshold) active = i;
                    }
                }
                tocLinks.forEach(function (a, i) {
                    a.style.color = (i === active) ? '#f57c00' : '';
                    a.style.fontWeight = (i === active) ? '600' : '';
                });
            }

            window.addEventListener('scroll', update, { passive: true });
            update();

        }, 400);
    });
}());