/* Collapsible Portlets
* =============================================================================
* Description: Toggles the visibility of portlets by clicking on each portlet's
* header.
* Author: [[User:Dlrohrer2003]]
* License: GNU-GPL v2 or higher
*/
// The style sheet for this script
mw.loader.load( '//en.wikipedia.org/w/index.php?title=User:Dlrohrer2003/portlet-toggle.css&action=raw&ctype=text/css', 'text/css' );
mw.loader.using( [ 'mediawiki.cookie' ], function () {
'use strict';
const cookiePrefix = mw.config.get( 'skin' ) + '-nav-';
const portletHeaderSelectors = 'h3';
const portletBodySelectors = 'div, ul';
const portletCollapsedClass = 'collapsible-portlet-collapsed';
let tabIndex = Array
.from( document.querySelectorAll( '[tabindex]' ), element => +element.tabIndex )
.reduce( ( a, b ) => Math.max( a, b ), 0 ) + 1;
document
.querySelectorAll( '#searchInput, .searchButton' )
.forEach( element => element.tabIndex = tabIndex++ );
function portletToggleHandler( event ) {
// Left click (usually), Middle click, Enter, or Space
if ( event.button === 0 || event.button === 1 || event.key === 'Enter' || event.key === ' ' ) {
const portlet = event.currentTarget.parentNode;
// Toggle the portlet's visibility class.
portlet.classList.toggle( portletCollapsedClass );
// Set the cookie to the state the portlet has been set to
mw.cookie.set(
portlet.id,
portlet.classList.contains( portletCollapsedClass ),
{ prefix: cookiePrefix, sameSite: 'Strict' }
);
}
if ( event.key !== 'Tab' ) {
event.preventDefault();
}
}
function makeCollapsible( portlet ) {
const portletHeader = portlet.querySelector( portletHeaderSelectors );
const portletBody = portlet.querySelector( portletBodySelectors );
portletHeader.classList.add( 'collapsible-portlet-header' );
portletHeader.tabIndex = tabIndex++;
portletHeader.addEventListener( 'keydown', portletToggleHandler );
portletHeader.addEventListener( 'mousedown', portletToggleHandler );
portletBody.classList.add( 'collapsible-portlet-body' );
// Set the initial class of the portlet based on the cookie
if ( mw.cookie.get( portlet.id, cookiePrefix ) === 'true' ) {
portlet.classList.add( portletCollapsedClass );
}
}
document
.querySelectorAll( '#mw_portlets, #quickbar, #mw-panel, #sidebar, .sidebar-inner' )
.forEach( portletContainer => {
portletContainer.classList.add( 'collapsible-portlet-container' );
Array
.from( portletContainer.querySelectorAll( '.mw-portlet:not( #p-search )' ) )
.filter( element => element.querySelector( portletHeaderSelectors ) )
.forEach( makeCollapsible );
});
});