Jump to content

MediaWiki:Common.js

From Erindal Wiki
Revision as of 22:52, 29 August 2026 by Miyokari (talk | contribs)

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.
/* ========================================================================
   ERINDAL WIKI - VECTOR 2022.JS v1.0
   Skin-specific enhancements. Common.js continues to own article behaviour.
   ======================================================================== */

( function () {
    'use strict';

    var themeKey = 'erindal-theme';
    var sidebarKey = 'erindal-sidebar';
    var themes = [ 'system', 'light', 'dark' ];

    function onReady( callback ) {
        if ( document.readyState === 'loading' ) {
            document.addEventListener( 'DOMContentLoaded', callback, { once: true } );
        } else {
            callback();
        }
    }

    function readTheme() {
        var value = 'system';

        try {
            value = window.localStorage.getItem( themeKey ) || 'system';
        } catch ( error ) {
            value = 'system';
        }

        return themes.indexOf( value ) === -1 ? 'system' : value;
    }

    function applyTheme( value ) {
        document.documentElement.setAttribute( 'data-ew-theme', value );

        try {
            window.localStorage.setItem( themeKey, value );
        } catch ( error ) {
            /* The selected mode still applies to the current page. */
        }
    }

    function installThemeToggle() {
        var topbar = document.getElementById( 'ew-server-topbar' );
        if ( !topbar || document.getElementById( 'ew-theme-toggle' ) ) {
            return;
        }

        var tools = topbar.querySelector( '.ew-topbar-tools' );
        if ( !tools ) {
            tools = document.createElement( 'div' );
            tools.className = 'ew-topbar-tools';
            topbar.appendChild( tools );
        }

        var button = document.createElement( 'button' );
        button.id = 'ew-theme-toggle';
        button.type = 'button';

        function updateButton() {
            var value = readTheme();
            var labels = {
                system: '\u25d0 Auto',
                light: '\u2600 Light',
                dark: '\u263e Dark'
            };

            button.textContent = labels[ value ];
            button.dataset.ewTheme = value;
            button.setAttribute( 'aria-label', 'Colour mode: ' + value + '. Activate to change mode.' );
            button.title = 'Colour mode: ' + value;
        }

        button.addEventListener( 'click', function () {
            var current = readTheme();
            var next = themes[ ( themes.indexOf( current ) + 1 ) % themes.length ];
            applyTheme( next );
            updateButton();
        } );

        tools.appendChild( button );
        applyTheme( readTheme() );
        updateButton();
    }

    function installSidebarToggleFallback() {
        var button = document.getElementById( 'ew-sidebar-toggle' );
        if ( !button || button.dataset.ewVectorBound === '1' || button.getAttribute( 'data-ew-bound' ) === '1' ) {
            return;
        }

        button.dataset.ewVectorBound = '1';

        function updateButton() {
            var collapsed = document.documentElement.classList.contains( 'ew-sidebar-collapsed' );
            button.textContent = collapsed ? '\u203a' : '\u2039';
            button.setAttribute( 'aria-expanded', collapsed ? 'false' : 'true' );
            button.setAttribute( 'aria-label', collapsed ? 'Open sidebar' : 'Close sidebar' );
            button.title = collapsed ? 'Open sidebar' : 'Close sidebar';
        }

        button.addEventListener( 'click', function () {
            var collapsed = document.documentElement.classList.toggle( 'ew-sidebar-collapsed' );

            try {
                window.localStorage.setItem( sidebarKey, collapsed ? 'collapsed' : 'open' );
            } catch ( error ) {
                /* The button still works for the current page. */
            }

            updateButton();
        } );

        updateButton();
    }

    function installTopbarDetails() {
        var topbar = document.getElementById( 'ew-server-topbar' );
        if ( !topbar || topbar.dataset.ewDetailsBound === '1' ) {
            return;
        }

        topbar.dataset.ewDetailsBound = '1';

        Array.prototype.forEach.call( topbar.querySelectorAll( 'details.ew-global-section' ), function ( section ) {
            section.addEventListener( 'toggle', function () {
                if ( !section.open ) {
                    return;
                }

                Array.prototype.forEach.call( topbar.querySelectorAll( 'details.ew-global-section[open]' ), function ( other ) {
                    if ( other !== section ) {
                        other.open = false;
                    }
                } );
            } );
        } );

        document.addEventListener( 'click', function ( event ) {
            if ( topbar.contains( event.target ) ) {
                return;
            }

            Array.prototype.forEach.call( topbar.querySelectorAll( 'details.ew-global-section[open]' ), function ( section ) {
                section.open = false;
            } );
        } );

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

            Array.prototype.forEach.call( topbar.querySelectorAll( 'details.ew-global-section[open]' ), function ( section ) {
                section.open = false;
            } );
        } );
    }

    onReady( function () {
        installThemeToggle();
        installSidebarToggleFallback();
        installTopbarDetails();
    } );
}() );