MediaWiki:Gadget-SidebarTOC.js: Difference between revisions

Jump to navigation Jump to search
mNo edit summary
mNo edit summary
Line 10: Line 10:
     // Remove the existing TOC
     // Remove the existing TOC
     $('#toc').remove();
     $('#toc').remove();
 
   
     // Create a new TOC
     new ResizeObserver(function(entries) {
    var $tocList = $('<ul class="vector-menu-content-list">').append(
if (window.innerWidth <= 720) {
        $('<li class="toclevel-1 tocsection-0">').append($('<a href="#">').append(
$('#mw-panel').css('height', '');
            $('<span class="toctext">').text(i18n.top)
}
        )),
else {
        $('#content > h2, #content > h3, #content > h4, #content > h5, #content > h6').map(function() {
$('#mw-panel').css('height', document.body.scrollHeight - 10);
            var $this = $(this);
}
            return $('<li class="toclevel-' + this.tagName.slice(1) + '">').append(
}).observe($('#content')[0]);
                $('<a href="#' + this.id + '">').text($this.text())
var tocCollapsed = (localStorage.getItem("sidebar_vector_c_p-toc") !== "n");
            );
$('<nav id="p-toc" class="vector-menu mw-portlet mw-portlet-toc vector-menu-portal portal" aria-labelledby="p-toc-label" role="navigation">').append(
        })
    $('<h3 id="p-toc-label" class="vector-menu-heading" tabindex="0">').append(
    );
        $('<span class="vector-menu-heading-label">').text(i18n.header)
 
    ).on("keypress", function(event) {
    // Append the new TOC to the page
if (event.which == 13) {
    $('<nav id="p-toc" class="vector-menu mw-portlet mw-portlet-toc vector-menu-portal portal" aria-labelledby="p-toc-label" role="navigation">').append(
$(this).trigger("click");
        $('<h3 id="p-toc-label" class="vector-menu-heading" tabindex="0">').append(
event.stopImmediatePropagation()
            $('<span class="vector-menu-heading-label">').text(i18n.header)
}
        ),
}).on("click", function(event) {
        $('<div class="vector-menu-content">').append($tocList)
        var $el = $(this).parent();
    ).appendTo('#mw-panel');
event.stopPropagation();
 
        $el.toggleClass("collapsed");
    // Ensure that the "Contents" header still follows the user when scrolling
        if($el.hasClass("collapsed")){
    var $pToc = $('#p-toc');
localStorage.setItem("sidebar_vector_c_p-toc", "y");
    $(window).on('scroll', function() {
            $el.find(".vector-menu-content").slideUp("fast");
        var scrollTop = $(this).scrollTop();
            $el.css({'margin-right': '', 'margin-left': ''});
        if (scrollTop > 100) {
        }
            $pToc.css('top', scrollTop - 100);
        else{
        } else {
localStorage.setItem("sidebar_vector_c_p-toc", "n");
            $pToc.css('top', 0);
            $el.find(".vector-menu-content").slideDown("fast");
        }
            var $toc = $el.find(".vector-menu-content-list")[0];
    });
            if ($toc.clientWidth < $toc.scrollWidth) {
 
        $el.css({'margin-right': '0', 'margin-left': '0'});
    // Prevent the TOC from collapsing immediately after opening it
            }
    $pToc.on('click', function(event) {
if (window.innerWidth >= 982 && $toc.clientWidth < $toc.scrollWidth) {
        event.stopPropagation();
        $el.css({'margin-right': '-0.5em', 'margin-left': '-0.5em'});
        $pToc.toggleClass('collapsed');
}
    });
        }
}),
    $('<div class="vector-menu-content">').append(
        $('<ul class="vector-menu-content-list">').append(
        $('<li class="toclevel-1 tocsection-0">').append($('<a href="#">').append(
        $('<span class="toctext">').text(i18n.top)
        )),
            $('#toc > ul').children().clone()
        )
    ).addClass($('#toc').parent().prop('class').split(/\s+/).filter(function(classname) {
    return classname.startsWith('toc-');
    }).join(' ')).css('display', tocCollapsed ? 'none' : '')
).addClass(tocCollapsed ? 'collapsed' : '').appendTo('#mw-panel');
mw.loader.using( ['ext.gadget.sectionObserver'], function(require) {
var initSectionObserver = require('ext.gadget.sectionObserver');
var allSections = document.querySelectorAll('#firstHeading, .mw-headline');
var sectionObserver = initSectionObserver({topMargin: 20, onIntersection: onIntersection})
sectionObserver.setElements(allSections);
sectionObserver.calcIntersection();
allSections = Array.from(allSections);
var tocList = $('#p-toc .vector-menu-content-list')[0];
var tocSections = $('#p-toc .vector-menu-content-list li');
var baseOffset = $('#p-toc .tocsection-0 .toctext')[0].offsetTop;
function onIntersection(section) {
    var index = allSections.indexOf(section);
    $('#p-toc .tocsection-current').removeClass('tocsection-current');
    var tocSection = tocSections.eq(index).addClass('tocsection-current');
    if ( tocSection.is(':hidden') && index > 0 ) return onIntersection(allSections[index - 1]);
    var tocSectionPos = tocSection[0].offsetTop - baseOffset;
    if ( tocSectionPos < tocList.scrollTop + (tocList.clientHeight * 0.15) ) {
        tocList.scrollTo({top: tocSectionPos - (tocList.clientHeight * 0.3)});
    }
    else if ( tocSectionPos > tocList.scrollTop + (tocList.clientHeight * 0.85) ) {
        tocList.scrollTo({top: tocSectionPos - (tocList.clientHeight * 0.7)});
    }
}
} );
});
});

Revision as of 17:48, 22 February 2024

$(function(){
    if (!$('#toc').length) {
        return;
    }
    var i18n = {
        header: 'Contents',
        top: '(Top)'
    };

    // Remove the existing TOC
    $('#toc').remove();
    
    new ResizeObserver(function(entries) {
		if (window.innerWidth <= 720) {
			$('#mw-panel').css('height', '');
		}
		else {
			$('#mw-panel').css('height', document.body.scrollHeight - 10);
		}
	}).observe($('#content')[0]);
	var tocCollapsed = (localStorage.getItem("sidebar_vector_c_p-toc") !== "n");
	$('<nav id="p-toc" class="vector-menu mw-portlet mw-portlet-toc vector-menu-portal portal" aria-labelledby="p-toc-label" role="navigation">').append(
	    $('<h3 id="p-toc-label" class="vector-menu-heading" tabindex="0">').append(
	        $('<span class="vector-menu-heading-label">').text(i18n.header)
	    ).on("keypress", function(event) {
			if (event.which == 13) {
				$(this).trigger("click");
				event.stopImmediatePropagation()
			}
		}).on("click", function(event) {
	        var $el = $(this).parent();
			event.stopPropagation();
	        $el.toggleClass("collapsed");
	        if($el.hasClass("collapsed")){
				localStorage.setItem("sidebar_vector_c_p-toc", "y");
	            $el.find(".vector-menu-content").slideUp("fast");
	            $el.css({'margin-right': '', 'margin-left': ''});
	        }
	        else{
				localStorage.setItem("sidebar_vector_c_p-toc", "n");
	            $el.find(".vector-menu-content").slideDown("fast");
	            var $toc = $el.find(".vector-menu-content-list")[0];
	            if ($toc.clientWidth < $toc.scrollWidth) {
	        		$el.css({'margin-right': '0', 'margin-left': '0'});
	            }
				if (window.innerWidth >= 982 && $toc.clientWidth < $toc.scrollWidth) {
	        		$el.css({'margin-right': '-0.5em', 'margin-left': '-0.5em'});
				}
	        }
		}),
	    $('<div class="vector-menu-content">').append(
	        $('<ul class="vector-menu-content-list">').append(
	        	$('<li class="toclevel-1 tocsection-0">').append($('<a href="#">').append(
	        		$('<span class="toctext">').text(i18n.top)
	        	)),
	            $('#toc > ul').children().clone()
	        )
	    ).addClass($('#toc').parent().prop('class').split(/\s+/).filter(function(classname) {
	    	return classname.startsWith('toc-');
	    }).join(' ')).css('display', tocCollapsed ? 'none' : '')
	).addClass(tocCollapsed ? 'collapsed' : '').appendTo('#mw-panel');
	
	mw.loader.using( ['ext.gadget.sectionObserver'], function(require) {
		var initSectionObserver = require('ext.gadget.sectionObserver');
		var allSections = document.querySelectorAll('#firstHeading, .mw-headline');
		var sectionObserver = initSectionObserver({topMargin: 20, onIntersection: onIntersection})
		sectionObserver.setElements(allSections);
		sectionObserver.calcIntersection();
		
		allSections = Array.from(allSections);
		var tocList = $('#p-toc .vector-menu-content-list')[0];
		var tocSections = $('#p-toc .vector-menu-content-list li');
		var baseOffset = $('#p-toc .tocsection-0 .toctext')[0].offsetTop;
		
		function onIntersection(section) {
		    var index = allSections.indexOf(section);
		    $('#p-toc .tocsection-current').removeClass('tocsection-current');
		    var tocSection = tocSections.eq(index).addClass('tocsection-current');
		    if ( tocSection.is(':hidden') && index > 0 ) return onIntersection(allSections[index - 1]);
		    var tocSectionPos = tocSection[0].offsetTop - baseOffset;
		    if ( tocSectionPos < tocList.scrollTop + (tocList.clientHeight * 0.15) ) {
		        tocList.scrollTo({top: tocSectionPos - (tocList.clientHeight * 0.3)});
		    }
		    else if ( tocSectionPos > tocList.scrollTop + (tocList.clientHeight * 0.85) ) {
		        tocList.scrollTo({top: tocSectionPos - (tocList.clientHeight * 0.7)});
		    }
		}
	} );
});