User:Dlrohrer2003/portlet-toggle.js

/* 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 ) === 'false' ) { 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 ); }); });