跳转到内容

MediaWiki:Gadget-ThemeSwitch.js

来自槌基百科

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
/**
 * ThemeSwitch gadget — floating theme picker for all visitors.
 */
( function () {
    'use strict';

    var STORAGE_KEY = 'mw-theme';

    var THEMES = [
        { id: '',      label: 'Classic', swatch: '#f8f9fa', text: '#333' },
        { id: 'slate', label: 'Slate',   swatch: '#4a7fa5', text: '#fff' },
        { id: 'dark',  label: 'Dark',    swatch: '#1a1d27', text: '#90cdf4' },
        { id: 'warm',  label: 'Warm',    swatch: '#c8922a', text: '#fff' }
    ];

    var current = localStorage.getItem( STORAGE_KEY ) || '';

    function applyTheme( id ) {
        THEMES.forEach( function ( t ) {
            document.documentElement.classList.remove( 'theme-' + t.id );
        } );
        if ( id ) {
            document.documentElement.classList.add( 'theme-' + id );
        }
        current = id;
        localStorage.setItem( STORAGE_KEY, id );
        updateSwatch();
    }

    // Apply stored theme immediately (before DOM ready, to avoid flash)
    applyTheme( current );

    function updateSwatch() {
        var btn = document.getElementById( 'theme-toggle-btn' );
        if ( !btn ) { return; }
        var theme = THEMES.find( function(t){ return t.id === current; } ) || THEMES[0];
        btn.style.background = theme.swatch;
        btn.style.color      = theme.text;
        btn.title = 'Theme: ' + theme.label;
    }

    $( function () {
        // Build the floating picker
        var wrapper = document.createElement( 'div' );
        wrapper.id = 'theme-picker';

        var btn = document.createElement( 'button' );
        btn.id = 'theme-toggle-btn';
        btn.innerHTML = '◐'; // half circle / palette symbol
        btn.setAttribute( 'aria-label', 'Switch theme' );
        wrapper.appendChild( btn );

        var menu = document.createElement( 'div' );
        menu.id = 'theme-picker-menu';
        menu.setAttribute( 'aria-hidden', 'true' );

        var label = document.createElement( 'div' );
        label.className = 'theme-picker-heading';
        label.textContent = 'Theme';
        menu.appendChild( label );

        THEMES.forEach( function ( theme ) {
            var opt = document.createElement( 'button' );
            opt.className  = 'theme-option';
            opt.dataset.theme = theme.id;

            var swatch = document.createElement( 'span' );
            swatch.className = 'theme-swatch';
            swatch.style.background = theme.swatch;
            swatch.style.border = theme.id === '' ? '1px solid #ccc' : 'none';

            var name = document.createElement( 'span' );
            name.textContent = theme.label;

            opt.appendChild( swatch );
            opt.appendChild( name );

            opt.addEventListener( 'click', function () {
                applyTheme( theme.id );
                menu.classList.remove( 'open' );
                menu.setAttribute( 'aria-hidden', 'true' );
            } );

            menu.appendChild( opt );
        } );

        wrapper.appendChild( menu );
        document.body.appendChild( wrapper );

        // Toggle open/close
        btn.addEventListener( 'click', function ( e ) {
            e.stopPropagation();
            var isOpen = menu.classList.toggle( 'open' );
            menu.setAttribute( 'aria-hidden', String( !isOpen ) );
        } );

        document.addEventListener( 'click', function () {
            menu.classList.remove( 'open' );
            menu.setAttribute( 'aria-hidden', 'true' );
        } );

        updateSwatch();
    } );
}() );