MediaWiki:Common.js: Difference between revisions

From CoraTO Wiki - Official Wiki
Jump to navigation Jump to search
Blanked the page
Tags: Blanking Reverted
No edit summary
Tag: Reverted
Line 1: Line 1:
( function () {
'use strict';


function ensureThemeStylesLoaded() {
try {
if ( !window.mw || !mw.loader || !mw.config ) {
return;
}
const skin = mw.config.get( 'skin' ) || 'vector';
const moduleName = 'themeloader.skins.' + skin + '.default';
if ( typeof mw.loader.getState === 'function' ) {
const state = mw.loader.getState( moduleName );
if ( state === null ) {
return;
}
if ( state === 'ready' || state === 'loading' ) {
return;
}
}
mw.loader.load( moduleName );
} catch ( e ) {
// Ignore error
}
}
function getSavedTheme() {
try {
return localStorage.getItem( 'mw-theme' ) || 'default';
} catch ( e ) {
return 'default';
}
}
// Define available themes matching christmas.css roots
const themes = [
{ name: 'Pink', id: 'default' },
{ name: 'Dark', id: 'dark-neutral' },
{ name: 'Christmas', id: 'christmas' },
{ name: 'Power Light', id: 'power-light' },
{ name: 'Magic Light', id: 'magic-light' },
{ name: 'Sense Light', id: 'sense-light' },
{ name: 'Charm Light', id: 'charm-light' },
{ name: 'Power Dark', id: 'power-dark' },
{ name: 'Charm Dark', id: 'charm-dark' },
{ name: 'Magic Dark', id: 'dark-lightBlue' },
{ name: 'Sense Dark', id: 'dark-purple' },
];
// Function to apply theme
function applyTheme( themeId ) {
ensureThemeStylesLoaded();
try {
localStorage.setItem( 'mw-theme', themeId );
} catch ( e ) {
// Ignore error
}
if ( themeId === 'default' ) {
document.documentElement.removeAttribute( 'data-theme' );
} else {
document.documentElement.setAttribute( 'data-theme', themeId );
}
}
// Initialize theme immediately
ensureThemeStylesLoaded();
applyTheme( getSavedTheme() );
// Wait for DOM
const domReady = function ( callback ) {
if ( document.readyState === 'loading' ) {
document.addEventListener( 'DOMContentLoaded', callback );
} else {
setTimeout( callback, 0 );
}
};
domReady( function () {
// Prevent duplicate injection
if ( document.getElementById( 'mw-theme-floating' ) ) {
return;
}
// Create Floating Container
// ID matches CSS: #mw-theme-floating
const container = document.createElement( 'div' );
container.id = 'mw-theme-floating';
// Create Inner Wrapper
// Class matches CSS: .themeMenu
const themeMenuDiv = document.createElement( 'div' );
themeMenuDiv.className = 'themeMenu';
// Create Toggle Button
// Class matches CSS: .themeMenu-toggle
const btn = document.createElement( 'button' );
btn.className = 'themeMenu-toggle';
btn.textContent = 'Appearence';
btn.title = 'Change appearence';
btn.type = 'button';
// Create Dropdown List
// Class matches CSS: .themeMenu-dropdown
const dropdown = document.createElement( 'ul' );
dropdown.className = 'themeMenu-dropdown';
// Populate Items
themes.forEach( function ( theme ) {
// Item Wrapper
// CSS doesn't strictly require this wrapper for floating,
// but theme-menu.css might use .themeMenu-itemWrap
const itemWrap = document.createElement( 'li' );
itemWrap.className = 'themeMenu-itemWrap';
const themeLink = document.createElement( 'a' );
themeLink.className = 'themeMenu-item';
themeLink.href = '#';
themeLink.textContent = theme.name;
themeLink.dataset.themeId = theme.id;
// Highlight current
const currentTheme = getSavedTheme();
if ( theme.id === currentTheme ) {
themeLink.classList.add( 'is-current' );
}
themeLink.addEventListener( 'click', function ( e ) {
e.preventDefault();
ensureThemeStylesLoaded();
applyTheme( theme.id );
// Update highlighting
dropdown.querySelectorAll( '.themeMenu-item' ).forEach( function ( link ) {
link.classList.remove( 'is-current' );
} );
themeLink.classList.add( 'is-current' );
// Close menu
themeMenuDiv.classList.remove( 'is-open' );
} );
itemWrap.appendChild( themeLink );
dropdown.appendChild( itemWrap );
} );
// Toggle Logic
// CSS uses .themeMenu.is-open .themeMenu-dropdown { display: block }
btn.addEventListener( 'click', function ( e ) {
e.preventDefault();
e.stopPropagation();
themeMenuDiv.classList.toggle( 'is-open' );
} );
// Click Outside Logic
document.addEventListener( 'click', function ( e ) {
if ( !themeMenuDiv.contains( e.target ) ) {
themeMenuDiv.classList.remove( 'is-open' );
}
} );
// Assemble
themeMenuDiv.appendChild( btn );
themeMenuDiv.appendChild( dropdown );
container.appendChild( themeMenuDiv );
// Inject into Body
document.body.appendChild( container );
} );
}() );

Revision as of 19:42, 1 January 2026

( function () {
	'use strict';

	function ensureThemeStylesLoaded() {
		try {
			if ( !window.mw || !mw.loader || !mw.config ) {
				return;
			}

			const skin = mw.config.get( 'skin' ) || 'vector';
			const moduleName = 'themeloader.skins.' + skin + '.default';

			if ( typeof mw.loader.getState === 'function' ) {
				const state = mw.loader.getState( moduleName );
				if ( state === null ) {
					return;
				}
				if ( state === 'ready' || state === 'loading' ) {
					return;
				}
			}

			mw.loader.load( moduleName );
		} catch ( e ) {
			// Ignore error
		}
	}

	function getSavedTheme() {
		try {
			return localStorage.getItem( 'mw-theme' ) || 'default';
		} catch ( e ) {
			return 'default';
		}
	}

	// Define available themes matching christmas.css roots
	const themes = [
		{ name: 'Pink', id: 'default' },
		{ name: 'Dark', id: 'dark-neutral' },
		{ name: 'Christmas', id: 'christmas' },
		{ name: 'Power Light', id: 'power-light' },
		{ name: 'Magic Light', id: 'magic-light' },
		{ name: 'Sense Light', id: 'sense-light' },
		{ name: 'Charm Light', id: 'charm-light' },
		{ name: 'Power Dark', id: 'power-dark' },
		{ name: 'Charm Dark', id: 'charm-dark' },
		{ name: 'Magic Dark', id: 'dark-lightBlue' },
		{ name: 'Sense Dark', id: 'dark-purple' },
	];

	// Function to apply theme
	function applyTheme( themeId ) {
		ensureThemeStylesLoaded();

		try {
			localStorage.setItem( 'mw-theme', themeId );
		} catch ( e ) {
			// Ignore error
		}

		if ( themeId === 'default' ) {
			document.documentElement.removeAttribute( 'data-theme' );
		} else {
			document.documentElement.setAttribute( 'data-theme', themeId );
		}
	}

	// Initialize theme immediately
	ensureThemeStylesLoaded();
	applyTheme( getSavedTheme() );

	// Wait for DOM
	const domReady = function ( callback ) {
		if ( document.readyState === 'loading' ) {
			document.addEventListener( 'DOMContentLoaded', callback );
		} else {
			setTimeout( callback, 0 );
		}
	};

	domReady( function () {
		// Prevent duplicate injection
		if ( document.getElementById( 'mw-theme-floating' ) ) {
			return;
		}

		// Create Floating Container
		// ID matches CSS: #mw-theme-floating
		const container = document.createElement( 'div' );
		container.id = 'mw-theme-floating';

		// Create Inner Wrapper
		// Class matches CSS: .themeMenu
		const themeMenuDiv = document.createElement( 'div' );
		themeMenuDiv.className = 'themeMenu';

		// Create Toggle Button
		// Class matches CSS: .themeMenu-toggle
		const btn = document.createElement( 'button' );
		btn.className = 'themeMenu-toggle';
		btn.textContent = 'Appearence';
		btn.title = 'Change appearence';
		btn.type = 'button';
		
		// Create Dropdown List
		// Class matches CSS: .themeMenu-dropdown
		const dropdown = document.createElement( 'ul' );
		dropdown.className = 'themeMenu-dropdown';
		
		// Populate Items
		themes.forEach( function ( theme ) {
			// Item Wrapper
			// CSS doesn't strictly require this wrapper for floating, 
			// but theme-menu.css might use .themeMenu-itemWrap
			const itemWrap = document.createElement( 'li' );
			itemWrap.className = 'themeMenu-itemWrap';

			const themeLink = document.createElement( 'a' );
			themeLink.className = 'themeMenu-item';
			themeLink.href = '#';
			themeLink.textContent = theme.name;
			themeLink.dataset.themeId = theme.id;
			
			// Highlight current
			const currentTheme = getSavedTheme();
			if ( theme.id === currentTheme ) {
				themeLink.classList.add( 'is-current' );
			}
			
			themeLink.addEventListener( 'click', function ( e ) {
				e.preventDefault();
				ensureThemeStylesLoaded();
				applyTheme( theme.id );
				
				// Update highlighting
				dropdown.querySelectorAll( '.themeMenu-item' ).forEach( function ( link ) {
					link.classList.remove( 'is-current' );
				} );
				themeLink.classList.add( 'is-current' );

				// Close menu
				themeMenuDiv.classList.remove( 'is-open' );
			} );

			itemWrap.appendChild( themeLink );
			dropdown.appendChild( itemWrap );
		} );

		// Toggle Logic
		// CSS uses .themeMenu.is-open .themeMenu-dropdown { display: block }
		btn.addEventListener( 'click', function ( e ) {
			e.preventDefault();
			e.stopPropagation();
			themeMenuDiv.classList.toggle( 'is-open' );
		} );

		// Click Outside Logic
		document.addEventListener( 'click', function ( e ) {
			if ( !themeMenuDiv.contains( e.target ) ) {
				themeMenuDiv.classList.remove( 'is-open' );
			}
		} );

		// Assemble
		themeMenuDiv.appendChild( btn );
		themeMenuDiv.appendChild( dropdown );
		container.appendChild( themeMenuDiv );

		// Inject into Body
		document.body.appendChild( container );
	} );

}() );