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: Difference between revisions

MediaWiki interface page
No edit summary
No edit summary
Tag: Reverted
Line 336: Line 336:
     applyRansomEffect('.mw-page-title-main');
     applyRansomEffect('.mw-page-title-main');
     applyRansomEffect('h2');
     applyRansomEffect('h2');
   
    /* ===============================
  Metaverse Wandering Vertices
=============================== */
function initMetaverseWobble() {
    if (!document.documentElement.classList.contains('lt-theme-red')) return;
    const card = document.querySelector('.mw-parser-output');
    if (!card) return;
    card.style.position = "relative";
    card.style.background = "transparent";
    // Create inner wobble layer
    const layer = document.createElement('div');
    layer.className = 'metaverse-wobble-layer';
    card.prepend(layer);
    // Style layer
    Object.assign(layer.style, {
        position: 'absolute',
        inset: '0',
        background: '#000',
        zIndex: '-1'
    });
    const radius = 1.5; // % movement radius
    const speed = 0.03;
    const corners = [
        { baseX: 0, baseY: 0, x: 0, y: 0, vx: Math.random(), vy: Math.random() },
        { baseX: 100, baseY: 0, x: 100, y: 0, vx: Math.random(), vy: Math.random() },
        { baseX: 100, baseY: 100, x: 100, y: 100, vx: Math.random(), vy: Math.random() },
        { baseX: 0, baseY: 100, x: 0, y: 100, vx: Math.random(), vy: Math.random() }
    ];
    function update() {
        corners.forEach(c => {
            c.x += (c.vx - 0.5) * speed;
            c.y += (c.vy - 0.5) * speed;
            if (Math.abs(c.x - c.baseX) > radius) c.vx *= -1;
            if (Math.abs(c.y - c.baseY) > radius) c.vy *= -1;
        });
        layer.style.clipPath = `polygon(
            ${corners[0].x}% ${corners[0].y}%,
            ${corners[1].x}% ${corners[1].y}%,
            ${corners[2].x}% ${corners[2].y}%,
            ${corners[3].x}% ${corners[3].y}%
        )`;
        requestAnimationFrame(update);
    }
    update();
}
initMetaverseWobble();


});
});

Revision as of 23:33, 20 February 2026

(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');

		        /* ===== 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');
    
    /* ===============================
	   Metaverse Wandering Vertices
	=============================== */
	
	function initMetaverseWobble() {
	
	    if (!document.documentElement.classList.contains('lt-theme-red')) return;
	
	    const card = document.querySelector('.mw-parser-output');
	    if (!card) return;
	
	    card.style.position = "relative";
	    card.style.background = "transparent";
	
	    // Create inner wobble layer
	    const layer = document.createElement('div');
	    layer.className = 'metaverse-wobble-layer';
	    card.prepend(layer);
	
	    // Style layer
	    Object.assign(layer.style, {
	        position: 'absolute',
	        inset: '0',
	        background: '#000',
	        zIndex: '-1'
	    });
	
	    const radius = 1.5; // % movement radius
	    const speed = 0.03;
	
	    const corners = [
	        { baseX: 0, baseY: 0, x: 0, y: 0, vx: Math.random(), vy: Math.random() },
	        { baseX: 100, baseY: 0, x: 100, y: 0, vx: Math.random(), vy: Math.random() },
	        { baseX: 100, baseY: 100, x: 100, y: 100, vx: Math.random(), vy: Math.random() },
	        { baseX: 0, baseY: 100, x: 0, y: 100, vx: Math.random(), vy: Math.random() }
	    ];
	
	    function update() {
	
	        corners.forEach(c => {
	
	            c.x += (c.vx - 0.5) * speed;
	            c.y += (c.vy - 0.5) * speed;
	
	            if (Math.abs(c.x - c.baseX) > radius) c.vx *= -1;
	            if (Math.abs(c.y - c.baseY) > radius) c.vy *= -1;
	
	        });
	
	        layer.style.clipPath = `polygon(
	            ${corners[0].x}% ${corners[0].y}%,
	            ${corners[1].x}% ${corners[1].y}%,
	            ${corners[2].x}% ${corners[2].y}%,
	            ${corners[3].x}% ${corners[3].y}%
	        )`;
	
	        requestAnimationFrame(update);
	    }
	
	    update();
	}
	
	initMetaverseWobble();

});