MediaWiki:Gadget-SidebarTOC.js: Difference between revisions

Jump to navigation Jump to search
mNo edit summary
mNo edit summary
Line 1: Line 1:
mw.loader.using( 'OO.ui.throttle/debounce', function () {
mw.loader.using( 'mediawiki.toc', function () {
$( function () {
$( function () {
var $window, $mwPanel, $floatTOC, scrollHandler,
var $window, $mwPanel, $floatTOC, scrollHandler,
tocLimit, headingOffsets, headingThreshold,
tocLimit, headingOffsets, headingThreshold,
$toc = $( '#toc' );
$toc = $( '.toc' );


if ( !$toc.length ) {
if ( !$toc.length ) {
Line 27: Line 27:
// Hijack links so that we can scroll to the content
// Hijack links so that we can scroll to the content
$floatTOC.find( 'a' ).click( function ( e ) {
$floatTOC.find( 'a' ).click( function ( e ) {
$( 'html, body' ).animate( {
var target = $( this.hash.replace( /\./g, '\\.' ));
scrollTop: $( this.hash.replace( /\./g, '\\.' ) ).offset().top - headingThreshold
if (target.length) {
} );
$( 'html, body' ).animate( {
scrollTop: target.offset().top - headingThreshold
} );
}
return false;
return false;
} );
} );
Line 38: Line 41:


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


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


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


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


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


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


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

Revision as of 06:43, 22 February 2024

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

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

		$window = $( window );
		$mwPanel = $( '#mw-panel' );
		headingThreshold = $window.height() / 5.0;
		$floatTOC = $toc
			.clone()
			.removeAttr( 'id' )
			.addClass( 'floatTOC' )
			.appendTo( '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 ) {
			var target = $( this.hash.replace( /\./g, '\\.' ));
			if (target.length) {
				$( 'html, body' ).animate( {
					scrollTop: target.offset().top - headingThreshold
				} );
			}
			return false;
		} );


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

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

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

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

                // Highlight current
                var highlight = false;
                // Current section is above the first heading below the top of the screen
                $.each(headingOffsets, function (i, v) {
                    // Skip first as there's no previous heading before the first
                    if (i !== 0 && (scrollTop + headingThreshold) < v[1]) {
                        highlight = headingOffsets[i - 1][0];
                        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
                });
                $mwPanel.show();
            }
        }

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