User:The wub/tocExpandAllSandbox.js

/* Add an expand/collapse all button to the top of the Vector 2022 table of contents See also https://phabricator.wikimedia.org/T302426

$( document ).ready(function {

if (        mw.config.get('skin') === 'vector-2022' &&        document.querySelector('.vector-toc-level-1 ul li') // any subsections?    ) { // Styles copied from .vector-pinnable-header-toggle-button const styles = ` .vector-toc-header-button { display: none; border: 0; padding: 4px 8px; background-color: #eaecf0; color: #202122; cursor: pointer; text-align: left; font-size: 0.75rem; border-radius: 2px; }

.vector-toc-header-button:hover { background-color: #f8f9fa; }       `;

mw.loader.addStyleTag( styles );

const expandButton = document.createElement('button'); expandButton.innerText = 'expand all'; expandButton.classList.add('vector-toc-header-button', 'vector-toc-expand-all'); expandButton.addEventListener( 'click', e => {           document.querySelectorAll('.vector-toc-contents .vector-toc-level-1').forEach( node => node.classList.add('vector-toc-list-item-expanded') );           document.querySelectorAll('.vector-toc-contents [aria-expanded="false"]').forEach( node => node.setAttribute('aria-expanded', 'true') );           expandButton.style.display = 'none';            collapseButton.style.display = 'inline-block';            collapseButton.focus({ preventScroll: true });        }); const collapseButton = document.createElement('button'); collapseButton.innerText = 'collapse all'; collapseButton.classList.add('vector-toc-header-button', 'vector-toc-collapse-all'); collapseButton.addEventListener( 'click', e => {           document.querySelectorAll('.vector-toc-contents .vector-toc-level-1').forEach( node => node.classList.remove('vector-toc-list-item-expanded') );           document.querySelectorAll('.vector-toc-contents [aria-expanded="true"]').forEach( node => node.setAttribute('aria-expanded', 'false') );           collapseButton.style.display = 'none';            expandButton.style.display = 'inline-block';            expandButton.focus({ preventScroll: true });        });

// Any already expanded sections? if ( document.querySelector('.vector-toc-list-item-expanded ul li') ) { expandButton.style.display = 'none'; collapseButton.style.display = 'inline-block'; } else { expandButton.style.display = 'inline-block'; collapseButton.style.display = 'none'; }

const tocHeader = document.querySelector('.vector-toc-pinnable-header'); tocHeader.appendChild( expandButton ); tocHeader.appendChild( collapseButton );

} });