MediaWiki:Gadget-SidebarTOC.js: Difference between revisions

Jump to navigation Jump to search
mNo edit summary
No edit summary
Line 1: Line 1:
mw.loader.using( 'mediawiki.toc', function () {
mw.loader.using( 'mediawiki.toc', function () {
$( function () {
$( function () {
var $window, $article, $tocContainer, $toc;
var $window, $floatTOC, scrollHandler,
 
tocLimit, headingOffsets, headingThreshold,
$window = $( window );
$toc = $( '.toc' );
$article = $( '.vector-body' );
$tocContainer = $( '<div class="mw-table-of-contents-container"></div>' ).insertBefore( $article );
$toc = $( '.toc' ).addClass( 'vector-sticky-toc-container' ).appendTo( $tocContainer );


if ( !$toc.length ) {
if ( !$toc.length ) {
Line 12: Line 9:
}
}


$tocContainer.css({
$window = $( window );
position: 'fixed',
headingThreshold = $window.height() / 5.0;
top: 0,
$floatTOC = $toc
bottom: 0,
.clone()
width: '15%', /* Adjust as needed */
.removeAttr( 'id' )
overflow: 'auto',
.addClass( 'floatTOC' )
left: 0
.appendTo( '.vector-body' )
});
.css( {
visibility: 'hidden',
opacity: 0
} );
 
// Show the ToC ul even if its hidden
$floatTOC.find( 'ul' ).show();
 
// Hijack links so that we can scroll to the content
$floatTOC.find( 'a' ).click( function ( e ) {
$( 'html, body' ).animate( {
scrollTop: $( this.hash.replace( /\./g, '\\.' ) ).offset().top - headingThreshold
} );
return false;
} );
 
tocLimit = $toc.offset().top + $toc.height();
headingOffsets = [];
 
// Get all heading positions
        $toc.find('a').each(function () {
            var href = $(this).attr('href');
            if (href && href.charAt(0) === '#') {
                var id = href.substring(1);
                var $heading = $('#' + id);
                if ($heading.length) {
                    headingOffsets.push([$heading, $heading.offset().top]);
                }
            }
        });
 
        // For the window scroll event
        scrollHandler = function () {
            var $current,
                scrollTop = $window.scrollTop();
 
            if (scrollTop > tocLimit) {
                $floatTOC.css({
                    visibility: 'visible',
                    opacity: 1
                });
 
                // Highlight current
                var highlight = false;
                // Current section is above the first heading below the top of the screen
                $.each(headingOffsets, function (i, v) {
                    if (i !== 0 && (scrollTop + headingThreshold) < v[1]) {
                        highlight = headingOffsets[i - 1][0].attr('id');
                        return false;
                    }
                });
 
                if (highlight) {
                    $current = $floatTOC.find('a[href="#' + highlight + '"]');
                    $floatTOC.find('a').not($current).css('font-weight', '');
                    $current.css('font-weight', 'bold');
                }
 
            } else {
                $floatTOC.css({
                    visibility: 'hidden',
                    opacity: 0
                });
            }
        };


        $window.on('scroll', $.throttle(250, scrollHandler));
     });
     });
});
});

Revision as of 07:12, 22 February 2024

mw.loader.using( 'mediawiki.toc', function () {
	$( function () {
		var $window, $floatTOC, scrollHandler,
			tocLimit, headingOffsets, headingThreshold,
			$toc = $( '.toc' );

		if ( !$toc.length ) {
			return;
		}

		$window = $( window );
		headingThreshold = $window.height() / 5.0;
		$floatTOC = $toc
			.clone()
			.removeAttr( 'id' )
			.addClass( 'floatTOC' )
			.appendTo( '.vector-body' )
			.css( {
				visibility: 'hidden',
				opacity: 0
			} );

		// Show the ToC ul even if its hidden
		$floatTOC.find( 'ul' ).show();

		// Hijack links so that we can scroll to the content
		$floatTOC.find( 'a' ).click( function ( e ) {
			$( 'html, body' ).animate( {
				scrollTop: $( this.hash.replace( /\./g, '\\.' ) ).offset().top - headingThreshold
			} );
			return false;
		} );

		tocLimit = $toc.offset().top + $toc.height();
		headingOffsets = [];

		// Get all heading positions
        $toc.find('a').each(function () {
            var href = $(this).attr('href');
            if (href && href.charAt(0) === '#') {
                var id = href.substring(1);
                var $heading = $('#' + id);
                if ($heading.length) {
                    headingOffsets.push([$heading, $heading.offset().top]);
                }
            }
        });

        // For the window scroll event
        scrollHandler = function () {
            var $current,
                scrollTop = $window.scrollTop();

            if (scrollTop > tocLimit) {
                $floatTOC.css({
                    visibility: 'visible',
                    opacity: 1
                });

                // Highlight current
                var highlight = false;
                // Current section is above the first heading below the top of the screen
                $.each(headingOffsets, function (i, v) {
                    if (i !== 0 && (scrollTop + headingThreshold) < v[1]) {
                        highlight = headingOffsets[i - 1][0].attr('id');
                        return false;
                    }
                });

                if (highlight) {
                    $current = $floatTOC.find('a[href="#' + highlight + '"]');
                    $floatTOC.find('a').not($current).css('font-weight', '');
                    $current.css('font-weight', 'bold');
                }

            } else {
                $floatTOC.css({
                    visibility: 'hidden',
                    opacity: 0
                });
            }
        };

        $window.on('scroll', $.throttle(250, scrollHandler));
    });
});