MediaWiki:Common.js: Difference between revisions

From Warmachine University Archive
Jump to navigation Jump to search
(Wait for DOM before injecting archived sidebar)
No edit summary
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
( function () {
( function () {
// Only run on Vector legacy and only if the normal sidebar is effectively empty.
if ( mw.config.get( 'skin' ) !== 'vector' ) {
return;
}
var sections = [
var sections = [
{
{
Line 5: Line 10:
label: 'Navigation',
label: 'Navigation',
links: [
links: [
{ title: 'Main Page', label: 'Home Page' },
{ href: '/index.php/Main_Page', label: 'Home Page' },
{ title: 'Find your local community', label: 'Find a local club' },
{ href: '/index.php?title=Find_your_local_community', label: 'Find a local club' },
{ href: 'https://www.patreon.com/user?u=35827616&fan_landing=true', label: 'Patreon', external: true }
{ href: 'https://www.patreon.com/user?u=35827616&fan_landing=true', label: 'Patreon', external: true }
]
]
Line 14: Line 19:
label: 'Core Rules',
label: 'Core Rules',
links: [
links: [
{ title: 'Useful External Links', label: 'Get the Rules Free' },
{ href: '/index.php?title=Useful_External_Links', label: 'Get the Rules Free' },
{ title: 'LPG - Theme Forces', label: 'Theme Forces' },
{ href: '/index.php?title=LPG_-_Theme_Forces', label: 'Theme Forces' },
{ title: 'Steamroller', label: 'Steamroller' },
{ href: '/index.php?title=Steamroller', label: 'Steamroller' },
{ title: 'Infernal Rulings', label: 'Rule Clarifications' }
{ href: '/index.php?title=Infernal_Rulings', label: 'Rule Clarifications' }
]
]
},
},
Line 24: Line 29:
label: 'Training',
label: 'Training',
links: [
links: [
{ title: 'Crash Course (101)', label: 'Basic Training' },
{ href: '/index.php?title=Crash_Course_(101)', label: 'Basic Training' },
{ title: 'Learning to Play the Game (LPG)', label: 'Intermediate Training' },
{ href: '/index.php?title=Learning_to_Play_the_Game_(LPG)', label: 'Intermediate Training' },
{ title: 'Learn Objectives, Tactics, & Strategy (LOTS)', label: 'Advanced Training' },
{ href: '/index.php?title=Learn_Objectives,_Tactics,_%26_Strategy_(LOTS)', label: 'Advanced Training' },
{ title: 'Glossary', label: 'Glossary' }
{ href: '/index.php?title=Glossary', label: 'Glossary' }
]
]
},
},
Line 34: Line 39:
label: 'Warmachine',
label: 'Warmachine',
links: [
links: [
{ title: 'Cryx', label: 'Cryx' },
{ href: '/index.php?title=Cryx', label: 'Cryx' },
{ title: 'Cygnar', label: 'Cygnar' },
{ href: '/index.php?title=Cygnar', label: 'Cygnar' },
{ title: 'Khador', label: 'Khador' },
{ href: '/index.php?title=Khador', label: 'Khador' },
{ title: 'Protectorate of Menoth', label: 'Protectorate' },
{ href: '/index.php?title=Protectorate_of_Menoth', label: 'Protectorate' },
{ title: 'Retribution of Scyrah', label: 'Retribution' },
{ href: '/index.php?title=Retribution_of_Scyrah', label: 'Retribution' },
{ title: 'Mercenaries', label: 'Mercenaries' }
{ href: '/index.php?title=Mercenaries', label: 'Mercenaries' }
]
]
},
},
Line 46: Line 51:
label: 'Hordes',
label: 'Hordes',
links: [
links: [
{ title: 'Circle Orboros', label: 'Circle' },
{ href: '/index.php?title=Circle_Orboros', label: 'Circle' },
{ title: 'Legion of Everblight', label: 'Legion' },
{ href: '/index.php?title=Legion_of_Everblight', label: 'Legion' },
{ title: 'Skorne', label: 'Skorne' },
{ href: '/index.php?title=Skorne', label: 'Skorne' },
{ title: 'Trollbloods', label: 'Trollbloods' },
{ href: '/index.php?title=Trollbloods', label: 'Trollbloods' },
{ title: 'Minions', label: 'Minions' }
{ href: '/index.php?title=Minions', label: 'Minions' }
]
]
},
},
Line 57: Line 62:
label: 'Mini-Factions',
label: 'Mini-Factions',
links: [
links: [
{ title: 'Convergence of Cyriss', label: 'Convergence' },
{ href: '/index.php?title=Convergence_of_Cyriss', label: 'Convergence' },
{ title: 'Crucible Guard', label: 'Crucible Guard' },
{ href: '/index.php?title=Crucible_Guard', label: 'Crucible Guard' },
{ title: 'Grymkin', label: 'Grymkin' },
{ href: '/index.php?title=Grymkin', label: 'Grymkin' },
{ title: 'Infernals', label: 'Infernals' },
{ href: '/index.php?title=Infernals', label: 'Infernals' },
{ title: 'Orgoth', label: 'Orgoth' }
{ href: '/index.php?title=Orgoth', label: 'Orgoth' }
]
]
},
},
{
{
id: 'wmu-other-pp-games',
id: 'wmu-other-games',
label: 'Other PP Games',
label: 'Other PP Games',
links: [
links: [
{ title: 'Other PP Games', label: 'Neo-Mechanika' },
{ href: '/index.php?title=Other_PP_Games', label: 'Neo-Mechanika' },
{ title: 'Other PP Games', label: 'Riot Quest' },
{ href: '/index.php?title=Other_PP_Games', label: 'Riot Quest' },
{ title: 'Other PP Games', label: '...more' }
{ href: '/index.php?title=Other_PP_Games', label: '...more' }
]
]
},
},
Line 77: Line 82:
label: 'The Vaults',
label: 'The Vaults',
links: [
links: [
{ title: 'FAQ', label: 'FAQ' },
{ href: '/index.php?title=FAQ', label: 'FAQ' },
{ title: 'League Models', label: 'League Models' },
{ href: '/index.php?title=League_Models', label: 'League Models' },
{ title: 'New Releases', label: 'New Releases' },
{ href: '/index.php?title=New_Releases', label: 'New Releases' },
{ title: 'Attack Sequence', label: 'Attack Sequence' },
{ href: '/index.php?title=Attack_Sequence', label: 'Attack Sequence' },
{ title: 'Template:Index Vaults', label: '...more' }
{ href: '/index.php?title=Template:Index_Vaults', label: '...more' }
]
]
},
},
Line 89: Line 94:
links: [
links: [
{ href: 'https://www.loswarmachine.com/', label: 'Other LOS sites', external: true },
{ href: 'https://www.loswarmachine.com/', label: 'Other LOS sites', external: true },
{ title: 'Useful External Links', label: 'Other useful websites' },
{ href: '/index.php?title=Useful_External_Links', label: 'Other useful websites' },
{ title: 'Special:Random', label: 'Random page', special: true },
{ href: '/index.php/Special:Random', label: 'Random page' },
{ title: 'Special:RecentChanges', label: 'Recent changes', special: true },
{ href: '/index.php/Special:RecentChanges', label: 'Recent changes' },
{ title: 'War Table', label: 'War Table' }
{ href: '/index.php?title=War_Table', label: 'War Table' }
]
]
}
}
];
];
function titleToHref( title, special ) {
var normalized = title.replace(/ /g, '_');
if ( special ) {
return '/index.php/' + encodeURI( normalized );
}
return '/index.php?title=' + encodeURIComponent( normalized );
}


function makePortlet( section ) {
function makePortlet( section ) {
Line 133: Line 130:


var anchor = document.createElement( 'a' );
var anchor = document.createElement( 'a' );
anchor.href = link.href || titleToHref( link.title, link.special );
anchor.href = link.href;
if ( link.external ) {
if ( link.external ) {
anchor.rel = 'nofollow';
anchor.rel = 'nofollow';
Line 151: Line 148:
}
}


function injectSidebar() {
function normalSidebarAlreadyHasMenus( panel ) {
var portlets = panel.querySelectorAll( '.portal, .mw-portlet' );
for ( var i = 0; i < portlets.length; i++ ) {
var id = portlets[ i ].id || '';
if ( id && id !== 'p-logo' && id !== 'p-tb' ) {
return true;
}
}
return false;
}
 
function injectIntoPanel() {
var panel = document.getElementById( 'mw-panel' );
var panel = document.getElementById( 'mw-panel' );
var tools = document.getElementById( 'p-tb' );
var tools = document.getElementById( 'p-tb' );
if ( !panel || document.getElementById( 'wmu-navigation' ) ) {
 
if ( !panel ) {
return;
}
 
// Prevent duplicates if our custom menu is already present.
if ( document.getElementById( 'wmu-navigation' ) ) {
return;
}
 
// If the normal MediaWiki sidebar already exists, do not inject a second one.
if ( normalSidebarAlreadyHasMenus( panel ) ) {
return;
return;
}
}
Line 163: Line 182:
}
}


mw.loader.using( 'mediawiki.util' ).then( function () {
if ( document.readyState === 'loading' ) {
if ( document.readyState === 'loading' ) {
document.addEventListener( 'DOMContentLoaded', injectIntoPanel, { once: true } );
document.addEventListener( 'DOMContentLoaded', injectSidebar, { once: true } );
} else {
return;
injectIntoPanel();
}
}
injectSidebar();
} );
}() );
}() );

Latest revision as of 09:37, 26 March 2026

( function () {
	// Only run on Vector legacy and only if the normal sidebar is effectively empty.
	if ( mw.config.get( 'skin' ) !== 'vector' ) {
		return;
	}

	var sections = [
		{
			id: 'wmu-navigation',
			label: 'Navigation',
			links: [
				{ href: '/index.php/Main_Page', label: 'Home Page' },
				{ href: '/index.php?title=Find_your_local_community', label: 'Find a local club' },
				{ href: 'https://www.patreon.com/user?u=35827616&fan_landing=true', label: 'Patreon', external: true }
			]
		},
		{
			id: 'wmu-core-rules',
			label: 'Core Rules',
			links: [
				{ href: '/index.php?title=Useful_External_Links', label: 'Get the Rules Free' },
				{ href: '/index.php?title=LPG_-_Theme_Forces', label: 'Theme Forces' },
				{ href: '/index.php?title=Steamroller', label: 'Steamroller' },
				{ href: '/index.php?title=Infernal_Rulings', label: 'Rule Clarifications' }
			]
		},
		{
			id: 'wmu-training',
			label: 'Training',
			links: [
				{ href: '/index.php?title=Crash_Course_(101)', label: 'Basic Training' },
				{ href: '/index.php?title=Learning_to_Play_the_Game_(LPG)', label: 'Intermediate Training' },
				{ href: '/index.php?title=Learn_Objectives,_Tactics,_%26_Strategy_(LOTS)', label: 'Advanced Training' },
				{ href: '/index.php?title=Glossary', label: 'Glossary' }
			]
		},
		{
			id: 'wmu-warmachine',
			label: 'Warmachine',
			links: [
				{ href: '/index.php?title=Cryx', label: 'Cryx' },
				{ href: '/index.php?title=Cygnar', label: 'Cygnar' },
				{ href: '/index.php?title=Khador', label: 'Khador' },
				{ href: '/index.php?title=Protectorate_of_Menoth', label: 'Protectorate' },
				{ href: '/index.php?title=Retribution_of_Scyrah', label: 'Retribution' },
				{ href: '/index.php?title=Mercenaries', label: 'Mercenaries' }
			]
		},
		{
			id: 'wmu-hordes',
			label: 'Hordes',
			links: [
				{ href: '/index.php?title=Circle_Orboros', label: 'Circle' },
				{ href: '/index.php?title=Legion_of_Everblight', label: 'Legion' },
				{ href: '/index.php?title=Skorne', label: 'Skorne' },
				{ href: '/index.php?title=Trollbloods', label: 'Trollbloods' },
				{ href: '/index.php?title=Minions', label: 'Minions' }
			]
		},
		{
			id: 'wmu-mini-factions',
			label: 'Mini-Factions',
			links: [
				{ href: '/index.php?title=Convergence_of_Cyriss', label: 'Convergence' },
				{ href: '/index.php?title=Crucible_Guard', label: 'Crucible Guard' },
				{ href: '/index.php?title=Grymkin', label: 'Grymkin' },
				{ href: '/index.php?title=Infernals', label: 'Infernals' },
				{ href: '/index.php?title=Orgoth', label: 'Orgoth' }
			]
		},
		{
			id: 'wmu-other-games',
			label: 'Other PP Games',
			links: [
				{ href: '/index.php?title=Other_PP_Games', label: 'Neo-Mechanika' },
				{ href: '/index.php?title=Other_PP_Games', label: 'Riot Quest' },
				{ href: '/index.php?title=Other_PP_Games', label: '...more' }
			]
		},
		{
			id: 'wmu-vaults',
			label: 'The Vaults',
			links: [
				{ href: '/index.php?title=FAQ', label: 'FAQ' },
				{ href: '/index.php?title=League_Models', label: 'League Models' },
				{ href: '/index.php?title=New_Releases', label: 'New Releases' },
				{ href: '/index.php?title=Attack_Sequence', label: 'Attack Sequence' },
				{ href: '/index.php?title=Template:Index_Vaults', label: '...more' }
			]
		},
		{
			id: 'wmu-other',
			label: 'Other',
			links: [
				{ href: 'https://www.loswarmachine.com/', label: 'Other LOS sites', external: true },
				{ href: '/index.php?title=Useful_External_Links', label: 'Other useful websites' },
				{ href: '/index.php/Special:Random', label: 'Random page' },
				{ href: '/index.php/Special:RecentChanges', label: 'Recent changes' },
				{ href: '/index.php?title=War_Table', label: 'War Table' }
			]
		}
	];

	function makePortlet( section ) {
		var nav = document.createElement( 'nav' );
		nav.id = section.id;
		nav.className = 'vector-menu mw-portlet vector-menu-portal portal';
		nav.setAttribute( 'role', 'navigation' );
		nav.setAttribute( 'aria-labelledby', section.id + '-label' );

		var heading = document.createElement( 'h3' );
		heading.id = section.id + '-label';
		heading.className = 'vector-menu-heading';

		var headingLabel = document.createElement( 'span' );
		headingLabel.className = 'vector-menu-heading-label';
		headingLabel.textContent = section.label;
		heading.appendChild( headingLabel );

		var content = document.createElement( 'div' );
		content.className = 'vector-menu-content';

		var list = document.createElement( 'ul' );
		list.className = 'vector-menu-content-list';

		section.links.forEach( function ( link, index ) {
			var item = document.createElement( 'li' );
			item.id = section.id + '-' + index;
			item.className = 'mw-list-item';

			var anchor = document.createElement( 'a' );
			anchor.href = link.href;
			if ( link.external ) {
				anchor.rel = 'nofollow';
			}

			var span = document.createElement( 'span' );
			span.textContent = link.label;
			anchor.appendChild( span );
			item.appendChild( anchor );
			list.appendChild( item );
		} );

		content.appendChild( list );
		nav.appendChild( heading );
		nav.appendChild( content );
		return nav;
	}

	function normalSidebarAlreadyHasMenus( panel ) {
		var portlets = panel.querySelectorAll( '.portal, .mw-portlet' );
		for ( var i = 0; i < portlets.length; i++ ) {
			var id = portlets[ i ].id || '';
			if ( id && id !== 'p-logo' && id !== 'p-tb' ) {
				return true;
			}
		}
		return false;
	}

	function injectIntoPanel() {
		var panel = document.getElementById( 'mw-panel' );
		var tools = document.getElementById( 'p-tb' );

		if ( !panel ) {
			return;
		}

		// Prevent duplicates if our custom menu is already present.
		if ( document.getElementById( 'wmu-navigation' ) ) {
			return;
		}

		// If the normal MediaWiki sidebar already exists, do not inject a second one.
		if ( normalSidebarAlreadyHasMenus( panel ) ) {
			return;
		}

		sections.forEach( function ( section ) {
			panel.insertBefore( makePortlet( section ), tools || null );
		} );
	}

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