Tip of the day
Long pressing an item opens multi-selection options in the inventory.

MediaWiki:Gadget-WSWBLanguageSelector.js

From Walkscape Walkthrough

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// Move and control the custom WSWB language selector.
$( function () {
    'use strict';

    var selector = document.querySelector( '.wswb-language-selector' );

    if ( !selector ) {
        return;
    }

    function markSelectorReady() {
        selector.classList.add( 'is-ready' );
    }

    var subpages = document.querySelector( '.subpages' );

    if ( subpages ) {
        subpages.replaceWith( selector );
    }

    var inlineLanguages = selector.querySelector( '.wswb-language-selector__inline' );
    var toggle = selector.querySelector( '.wswb-language-selector__toggle' );
    var menu = selector.querySelector( '.wswb-language-selector__menu' );
    var toggleSeparator = selector.querySelector( '.wswb-language-selector__toggle-separator' );

    if ( !inlineLanguages || !toggle || !toggleSeparator || !menu ) {
        markSelectorReady();
        return;
    }

    // Preserve the original language order when options move between regions.
    var languageOptions = Array.from(
        inlineLanguages.querySelectorAll( '.wswb-language-selector__option' )
    );
    var currentOption = languageOptions.find( function ( option ) {
        return option.classList.contains( 'wswb-language-selector__current' );
    } );
    var englishOption = languageOptions.find( function ( option ) {
        return option.getAttribute( 'lang' ) === 'en';
    } );
    var movableOptions = languageOptions.filter( function ( option ) {
        return !option.classList.contains( 'wswb-language-selector__pinned' );
    } );

    function selectorOverflows() {
        return selector.scrollWidth > selector.clientWidth + 1;
    }

    function setOpen( open ) {
        if ( open && menu.children.length === 0 ) {
            open = false;
        }

        toggle.setAttribute( 'aria-expanded', String( open ) );
        menu.setAttribute( 'aria-hidden', String( !open ) );
        menu.classList.toggle( 'is-open', open );
    }

    function setToggleVisible( visible ) {
        toggle.classList.toggle( 'is-hidden', !visible );
        toggle.setAttribute( 'aria-hidden', String( !visible ) );
        toggleSeparator.classList.toggle( 'is-hidden', !visible );

        if ( !visible ) {
            setOpen( false );
        }
    }

    function arrangeLanguages() {
        try {
            setOpen( false );

            languageOptions.forEach( function ( option ) {
                inlineLanguages.appendChild( option );
            } );

            setToggleVisible( false );

            if ( !selectorOverflows() ) {
                return;
            }

            setToggleVisible( true );

            for (
                var index = movableOptions.length - 1;
                index >= 0 && selectorOverflows();
                index -= 1
            ) {
                menu.insertBefore( movableOptions[ index ], menu.firstChild );
            }

            // Keep the selected language visible even when English must move.
            if ( selectorOverflows() && englishOption && englishOption !== currentOption ) {
                menu.insertBefore( englishOption, menu.firstChild );
            }

            setToggleVisible( menu.children.length > 0 );
        } finally {
            markSelectorReady();
        }
    }

    toggle.addEventListener( 'click', function () {
        setOpen( toggle.getAttribute( 'aria-expanded' ) !== 'true' );
    } );

    toggle.addEventListener( 'keydown', function ( event ) {
        if ( event.key === 'Enter' || event.key === ' ' ) {
            event.preventDefault();
            setOpen( toggle.getAttribute( 'aria-expanded' ) !== 'true' );
        }
    } );

    document.addEventListener( 'keydown', function ( event ) {
        if ( event.key !== 'Escape' && event.key !== 'Esc' ) {
            return;
        }

        if ( toggle.getAttribute( 'aria-expanded' ) === 'true' ) {
            setOpen( false );
            toggle.focus();
        }
    }, true );

    document.addEventListener( 'pointerdown', function ( event ) {
        if ( !selector.contains( event.target ) ) {
            setOpen( false );
        }
    }, true );

    var resizeFrame = null;
    var lastArrangementWidth = null;

    function getArrangementWidth() {
        var container = selector.parentElement || selector;
        return Math.round( container.getBoundingClientRect().width );
    }

    function scheduleArrangement( force ) {
        var width = getArrangementWidth();

        if ( !force && width === lastArrangementWidth ) {
            return;
        }

        if ( resizeFrame !== null ) {
            window.cancelAnimationFrame( resizeFrame );
        }

        resizeFrame = window.requestAnimationFrame( function () {
            var currentWidth;

            resizeFrame = null;
            currentWidth = getArrangementWidth();

            if ( !force && currentWidth === lastArrangementWidth ) {
                return;
            }

            lastArrangementWidth = currentWidth;
            arrangeLanguages();
        } );
    }

    window.addEventListener( 'resize', function () {
        scheduleArrangement( false );
    } );

    if ( window.ResizeObserver && selector.parentElement ) {
        var resizeObserver = new ResizeObserver( function () {
            scheduleArrangement( false );
        } );

        resizeObserver.observe( selector.parentElement );
    }

    setOpen( false );
    scheduleArrangement( true );

    if ( document.fonts ) {
        document.fonts.ready.then( function () {
            scheduleArrangement( true );
        } );
    }
} );