Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MediaWiki:Common.js

MediaWiki interface page
Revision as of 23:56, 21 February 2026 by QuadraticFour (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.
(function () {
    const theme = localStorage.getItem('lt-theme') || 'lt-theme-default';
    document.documentElement.classList.add(theme);
})();
mw.loader.using(['mediawiki.util']).then(function () {

    function injectThemeOption(container) {
    	
    	function createRadio(id, label) {
		    const radioWrapper = document.createElement('div');
		    radioWrapper.className = 'citizen-client-prefs-radio';
		
		    const input = document.createElement('input');
		    input.type = 'radio';
		    input.name = 'lt-theme-group';
		    input.id = id;
		    input.className = 'citizen-client-prefs-radio__input';
		
		    const icon = document.createElement('span');
		    icon.className = 'citizen-client-prefs-radio__icon';
		
		    const labelEl = document.createElement('label');
		    labelEl.className = 'citizen-client-prefs-radio__label';
		    labelEl.htmlFor = id;
		    labelEl.textContent = label;
		
		    radioWrapper.appendChild(input);
		    radioWrapper.appendChild(icon);
		    radioWrapper.appendChild(labelEl);
		
		    return radioWrapper;
		}

        if (document.getElementById('lt-theme-test')) return;

        const wrapper = document.createElement('div');
        wrapper.id = 'lt-theme-test';
        wrapper.className = 'mw-portlet citizen-menu';

        const heading = document.createElement('div');
        heading.className = 'citizen-menu__heading';
        heading.textContent = 'Theme';

        const content = document.createElement('div');
        content.className = 'citizen-menu__content';

        const list = document.createElement('ul');
        list.className = 'citizen-menu__content-list';

        const item = document.createElement('li');
        item.className = 'mw-list-item mw-list-item-js';

        const innerDiv = document.createElement('div');
        const form = document.createElement('form');

        form.appendChild(createRadio('lt-theme-default', '🎭 Velvet'));
		form.appendChild(createRadio('lt-theme-red', '🚇 Meta'));
		form.appendChild(createRadio('lt-theme-blue', '⚖️ Justice'));

		let savedTheme = localStorage.getItem('lt-theme');
		if (!savedTheme) {
		    savedTheme = 'lt-theme-default';
		    localStorage.setItem('lt-theme', savedTheme);
		}

		const savedInput = form.querySelector('#' + savedTheme);
		if (savedInput) savedInput.checked = true;

		form.addEventListener('change', function (e) {
		    if (e.target && e.target.matches('.citizen-client-prefs-radio__input')) {

		        const newTheme = e.target.id;

		        document.documentElement.classList.remove(
		            'lt-theme-default',
		            'lt-theme-red',
		            'lt-theme-blue'
		        );

		        document.documentElement.classList.add(newTheme);
		        localStorage.setItem('lt-theme', newTheme);

		        applyRansomEffect('.lt-infobox-title');
		        applyRansomEffect('.mw-page-title-main');
		        applyRansomEffect('h2');
		        applyRansomEffect('h3');

		        /* ===== WORDMARK UPDATE TRIGGER ===== */
		        updateWordmarkTheme();
		        /* ===== END WORDMARK UPDATE TRIGGER ===== */
		    }
		});

        innerDiv.appendChild(form);
        item.appendChild(innerDiv);
        list.appendChild(item);
        content.appendChild(list);
        wrapper.appendChild(heading);
        wrapper.appendChild(content);
        container.appendChild(wrapper);
    }

    const observer = new MutationObserver(function () {
        const container = document.querySelector('.citizen-preferences-content');
        if (container) injectThemeOption(container);
    });

    observer.observe(document.body, { childList: true, subtree: true });

    /* ========================================= */
    /* ===== WORDMARK ENGINE START ============ */
    /* ========================================= */

    function initializeWordmark() {
        const wordmarks = document.querySelectorAll('.mw-logo-wordmark');

        wordmarks.forEach(function (el) {

            if (el.dataset.wordmarkInitialized === "true") return;

            const text = el.textContent;
            el.textContent = '';

            // Original layer
            const originalLayer = document.createElement('span');
            originalLayer.className = 'wm-original';
            originalLayer.textContent = text;

            // Velvet layer
            const velvetLayer = document.createElement('span');
            velvetLayer.className = 'wm-velvet';

            text.split('').forEach(function (char, index) {
                const span = document.createElement('span');
                span.textContent = char === ' ' ? '\u00A0' : char;
                span.style.animationDelay = (index * 0.08) + 's';
                span.className = 'velvet-letter';
                velvetLayer.appendChild(span);
            });

            // Scrapbook layer
            const scrapbookLayer = document.createElement('span');
            scrapbookLayer.className = 'wm-scrap';

            const fonts = [
                "'Anton', sans-serif",
                "'Playfair Display', serif",
                "'Bitter', serif",
                "'IBM Plex Mono', monospace",
                "'Black Ops One', sans-serif"
            ];

            text.split('').forEach(function (char) {

                const span = document.createElement('span');

                if (char === ' ') {
                    span.textContent = '\u00A0';
                    scrapbookLayer.appendChild(span);
                    return;
                }

                if (!/[a-zA-Z0-9]/.test(char)) {
                    span.textContent = char;
                    scrapbookLayer.appendChild(span);
                    return;
                }

                span.textContent = char;
                span.className = 'scrapbook-letter box-black';

                const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
                const randomRotate = (Math.random() * 6 - 3);
                const randomSize = 1 + (Math.random() * 0.15 - 0.075);
                const randomY = (Math.random() * 6 - 3);

                span.style.fontFamily = randomFont;
                span.style.transform =
                    `rotate(${randomRotate}deg) translateY(${randomY}px) scale(${randomSize})`;

                if (Math.random() < 0.15) {
                    span.className = 'scrapbook-letter box-white';
                }

                scrapbookLayer.appendChild(span);
            });

            el.appendChild(originalLayer);
            el.appendChild(velvetLayer);
            el.appendChild(scrapbookLayer);

            el.dataset.wordmarkInitialized = "true";
        });
    }

    function updateWordmarkTheme() {
        const isVelvet = document.documentElement.classList.contains('lt-theme-default');
        const isRed = document.documentElement.classList.contains('lt-theme-red');

        document.querySelectorAll('.mw-logo-wordmark').forEach(function (el) {

            const original = el.querySelector('.wm-original');
            const velvet = el.querySelector('.wm-velvet');
            const scrap = el.querySelector('.wm-scrap');

            if (!original || !velvet || !scrap) return;

            if (isVelvet) {
                original.style.display = 'none';
                velvet.style.display = 'inline';
                scrap.style.display = 'none';
            }
            else if (isRed) {
                original.style.display = 'none';
                velvet.style.display = 'none';
                scrap.style.display = 'inline';
            }
            else {
                original.style.display = 'inline';
                velvet.style.display = 'none';
                scrap.style.display = 'none';
            }
        });
    }

    initializeWordmark();
    updateWordmarkTheme();

    /* ========================================= */
    /* ===== WORDMARK ENGINE END ============== */
    /* ========================================= */


    function toggleScrapbook(el) {
        const isRed = document.documentElement.classList.contains('lt-theme-red');

        const original = el.querySelector('.scrap-original');
        const scrapbook = el.querySelector('.scrap-layer');

        if (!original || !scrapbook) return;

        if (isRed) {
            original.style.display = 'none';
            scrapbook.style.display = 'inline';
        } else {
            original.style.display = 'inline';
            scrapbook.style.display = 'none';
        }
    }

    function applyRansomEffect(selector) {
        const elements = document.querySelectorAll(selector);

        elements.forEach(function (el) {

            const isRed = document.documentElement.classList.contains('lt-theme-red');

            if (el.dataset.scrapbookInitialized === "true") {
                if (isRed) {
                    const scrapbookLayer = el.querySelector('.scrap-layer');
                    if (scrapbookLayer) scrapbookLayer.remove();
                    el.dataset.scrapbookInitialized = "";
                } else {
                    toggleScrapbook(el);
                    return;
                }
            }
            const originalText = el.textContent;
            el.textContent = '';

            const originalLayer = document.createElement('span');
            originalLayer.className = 'scrap-original';
            originalLayer.textContent = originalText;

            const scrapbookLayer = document.createElement('span');
            scrapbookLayer.className = 'scrap-layer';

            const fonts = [
                "'Anton', sans-serif",
                "'Bebas Neue', sans-serif",
                "'Archivo Black', sans-serif",
                "'Oswald', sans-serif",
                "'Playfair Display', serif",
                "'Libre Baskerville', serif",
                "'Bitter', serif",
                "'Cinzel', serif",
                "'Courier New', monospace",
                "'IBM Plex Mono', monospace",
                "'Black Ops One', sans-serif"
            ];

            originalText.split('').forEach(function (char) {

                const span = document.createElement('span');

                if (char === ' ') {
                    span.textContent = '\u00A0';
                    scrapbookLayer.appendChild(span);
                    return;
                }

                if (!/[a-zA-Z0-9]/.test(char)) {
                    span.textContent = char;
                    scrapbookLayer.appendChild(span);
                    return;
                }

                span.textContent = char;
                span.className = 'scrapbook-letter box-black';

                const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
                const randomRotate = (Math.random() * 6 - 3);
                const randomSize = 1 + (Math.random() * 0.15 - 0.075);
                const randomY = (Math.random() * 6 - 3);

                span.style.fontFamily = randomFont;
                span.style.transform =
                    `rotate(${randomRotate}deg) translateY(${randomY}px) scale(${randomSize})`;

                if (Math.random() < 0.15) {
                    span.className = 'scrapbook-letter box-white';
                }

                scrapbookLayer.appendChild(span);
            });

            el.appendChild(originalLayer);
            el.appendChild(scrapbookLayer);
            el.dataset.scrapbookInitialized = "true";

            toggleScrapbook(el);
        });
    }

    applyRansomEffect('.lt-infobox-title');
    applyRansomEffect('.mw-page-title-main');
    applyRansomEffect('h2');
    applyRansomEffect('h3');

});