Common.js – MediaWiki
Categories: 
Fred Gandt (talk | contribs) m (Layout changes only at this stage - making it easier to read, edit, and understand.)  | 
				Lou Montana (talk | contribs)  m (Fix typo)  | 
				||
| (81 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
/*****************************************************************************************  | /*****************************************************************************************  | ||
  *   |   * This JavaScript file will be loaded for all users on every page load  | ||
  * Its content must be kept as minimal as possible.  | |||
  *   | |||
  *****************************************************************************************/  |   *****************************************************************************************/  | ||
mw.loader.using( ['mediawiki.util', 'jquery.client'], function() { /* BEGIN mw.loader WRAPPER */  | |||
	if ( mw.config.get( '  | 	/*****************************************************************************************  | ||
	 * Conditionally import further JavaScript for specific situations.  | |||
	 */  | |||
		if (   | 	function conditionallyImport() {  | ||
		if ( mw.config.get( 'wgAction' ) === 'edit' || mw.config.get( 'wgAction' ) === 'submit' ) {  | |||
			importScript( 'MediaWiki:Editing.js' );  | |||
			// mw.loader.load( '/wiki/index.php?title=MediaWiki:Editing.js&action=raw&ctype=text/javascript' ); // proper thing to do - for future reference  | |||
		}  | |||
		if ( mw.config.get( 'wgCanonicalNamespace' ) != 'MediaWiki' && mw.config.get( 'wgArticleId' ) === 0 ) {  | |||
			importScript( 'MediaWiki:Creation.js' );  | |||
		}  | |||
		if ( mw.config.get( 'wgPageName' ) === 'Special:Version' ) {  | |||
			importScript( 'MediaWiki:SpecialVersion.js' );  | |||
		}  | 		}  | ||
	}  | 	}  | ||
	mw.hook( 'wikipage.content' ).add( conditionallyImport );  | |||
/*****************************************************************************************/  | 	/*****************************************************************************************  | ||
	 * Add a Purge button  | |||
	 * Maintainer: [[User:Lou Montana]]  | |||
	 */  | |||
	function offerPurgeButton() {  | |||
		var protectButton = document.getElementById('ca-protect');  | |||
		if (protectButton == null) {  | |||
			protectButton = document.getElementById('ca-unprotect');  | |||
			if (protectButton == null) {  | |||
				return; // quick'n'not that dirty  | |||
			}  | |||
		}  | |||
/  | 		var newButton = protectButton.cloneNode(true),  | ||
			link = newButton.getElementsByTagName('a')[0];  | |||
		link.removeAttribute('accesskey');  | |||
		link.setAttribute('title', 'Purge the page\'s cache');  | |||
		link.setAttribute('href', document.location.href + (document.location.href.indexOf('?') === -1 ? '?action=purge' : '&action=purge'));  | |||
		link.innerHTML = 'Purge';  | |||
		protectButton.parentNode.appendChild(newButton);  | |||
	}  | 	}  | ||
	mw.hook( 'wikipage.content' ).add( offerPurgeButton );  | |||
/*****************************************************************************************/  | 	/*****************************************************************************************  | ||
	 * Add a Fix access button  | |||
	 * Maintainer: [[User:Lou Montana]]  | |||
	 */  | |||
	function offerDeleteSessionCookieButton() {  | |||
		var protectButton = document.getElementById('ca-protect');  | |||
		if (protectButton == null) {  | |||
			protectButton = document.getElementById('ca-unprotect');  | |||
			if (protectButton == null) {  | |||
				return; // quick'n'not that dirty  | |||
			}  | |||
/  | |||
			}  | |||
		}  | 		}  | ||
		var newButton = protectButton.cloneNode(true),  | |||
			link = newButton.getElementsByTagName('a')[0];  | |||
		link.removeAttribute('accesskey');  | |||
		link.setAttribute('title', 'Delete the community_session cookie to fix the DbQueryError issue');  | |||
		link.setAttribute('href', '/clearcookie.php?url=' + document.location.href);  | |||
		link.innerHTML = 'Fix access';  | |||
		protectButton.parentNode.appendChild(newButton);  | |||
	}  | 	}  | ||
	// mw.hook( 'wikipage.content' ).add( offerDeleteSessionCookieButton ); // disabled for now, -should- be fixed  | |||
/*****************************************************************************************/  | 	/*****************************************************************************************  | ||
	 * Disable Talk pages  | |||
	 * Maintainer: [[User:Lou Montana]]  | |||
	 */  | |||
	function disableTalkPages() {  | |||
		if ($.inArray('sysop', mw.config.get('wgUserGroups')) === -1) { // not admin  | |||
			if (mw.config.get('wgCanonicalNamespace').indexOf('talk') !== -1 && // talk page  | |||
				mw.config.get('wgNamespaceNumber') !== 3) { // User Talk exception  | |||
				if (document.getElementById('ca-edit') != null) {  | |||
					document.getElementById('ca-edit').remove();  | |||
				}  | |||
				if (document.getElementById('ca-addsection') != null) {  | |||
					document.getElementById('ca-addsection').remove();  | |||
				}  | 				}  | ||
			}  | 			}  | ||
			var talkTab = document.getElementById('ca-talk');  | |||
			if (  | 			if (talkTab != null && talkTab.classList.contains('new')) {  | ||
				talkTab.remove();  | |||
			}  | 			}  | ||
		}  | 		}  | ||
	}  | |||
	mw.hook( 'wikipage.content' ).add( disableTalkPages );  | |||
	/*****************************************************************************************  | 	/*****************************************************************************************  | ||
	 * Function that adds a Sandbox button  | |||
	 * Maintainer: [[User:Lou Montana]]  | |||
	 */  | |||
	function addSandboxButton() {  | |||
		var userpageLink = document.getElementById('pt-userpage');  | |||
		var talkLink = document.getElementById('pt-mytalk');  | |||
		if (talkLink == null) {  | |||
			return;  | |||
		}  | 		}  | ||
		var sandboxLink = talkLink.cloneNode(true),  | |||
			link = sandboxLink.getElementsByTagName('a')[0];  | |||
		link.removeAttribute('accesskey');  | |||
		link.setAttribute('title', 'Your Sandbox');  | |||
		link.setAttribute('href', userpageLink.getElementsByTagName('a')[0].href + '/Sandbox');  | |||
		link.innerHTML = 'Sandbox';  | |||
		talkLink.parentNode.insertBefore(sandboxLink, talkLink);  | |||
	}  | |||
	mw.hook( 'wikipage.content' ).add( addSandboxButton );  | |||
	/*****************************************************************************************/  | 	/*****************************************************************************************  | ||
	 * Functions that adds Tabs  | |||
	 * Maintainer: [[User:Lou Montana]]  | |||
	 */  | |||
	function tabSystem_selectTab(titles, contents, tabIndex) {  | |||
		var i;  | |||
		var   | 		for (i = 0; i < titles.length; i++) {  | ||
			titles[i].classList.remove('selected');  | |||
		}  | |||
		}  | 		for (i = 0; i < contents.length; i++) {  | ||
			contents[i].style.display = 'none';  | |||
		}  | |||
		if (tabIndex < 0 || tabIndex > titles.length -1 || tabIndex > contents.length -1) {  | |||
			return;  | |||
		if (   | |||
		}  | 		}  | ||
		titles[tabIndex].classList.add('selected');  | |||
		contents[tabIndex].style.display = 'block';  | |||
	}  | 	}  | ||
	function tabSystem_implementTabs() {  | |||
		var tabBlocks = document.getElementsByClassName('biki-tabs');  | |||
		var   | |||
		for (var i = 0; i < tabBlocks.length; i++) {  | |||
			var tabBlock = tabBlocks[i];  | |||
			var titles = tabBlock.getElementsByClassName('biki-tab-title');  | |||
			var contents = tabBlock.getElementsByClassName('biki-tab-content');  | |||
			if (titles.length < 1 || contents.length < 1 || titles.length != contents.length) {  | |||
				continue;  | |||
			}  | 			}  | ||
			for (var j = 0; j < titles.length; j++) {  | |||
				(function(titles, contents, index) {  | |||
					titles[j].addEventListener('click', function () { tabSystem_selectTab(titles, contents, index) })  | |||
			for (var   | 				})(titles, contents, j);  | ||
				}  | |||
			}  | 			}  | ||
			var selectedTab = 0;  | |||
			if (tabBlock.dataset && tabBlock.dataset.selectedtab) {  | |||
				var dataSelectedTab = +tabBlock.dataset.selectedtab;  | |||
				if (!isNaN(dataSelectedTab)) {  | |||
					selectedTab = Math.max(0, Math.min(dataSelectedTab, titles.length -1));  | |||
			if (  | |||
				var   | |||
				}  | 				}  | ||
			}  | 			}  | ||
			tabSystem_selectTab(titles, contents, selectedTab);  | |||
		}  | 		}  | ||
	}  | 	}  | ||
	mw.hook( 'wikipage.content' ).add( tabSystem_implementTabs );  | |||
	/*****************************************************************************************  | |||
	 * Function that adds Dark/Default Mode button for non logged-in users  | |||
	 * (logged-in users can select their skin in Parameters)  | |||
	 * Maintainer: [[User:Lou Montana]]  | |||
	 */  | |||
	const SKIN_USAGE = 'useskin=';  | |||
	function addDarkOrDefaultModeButton() {  | |||
		const DARKMODE_SKIN = 'darkvector';  | |||
		const DARKMODE_SKIN_USAGE = SKIN_USAGE + DARKMODE_SKIN;  | |||
		var leftTabHolder = document.getElementById('p-namespaces').getElementsByTagName('ul')[0]; // <ul>  | |||
		if (leftTabHolder == null)  | |||
			return;  | |||
/  | 		var firstButton = leftTabHolder .children[0]; // <li>  | ||
		if (firstButton == null)  | |||
			return; // quick'n'not that dirty  | |||
		var buttonName;  | |||
		var title;  | |||
		var href = document.documentURI;  | |||
		if (href.indexOf(DARKMODE_SKIN_USAGE) !== -1)  | |||
		{  | |||
			buttonName = 'Default Mode';  | |||
			title = 'Go back to the default skin';  | |||
			href = href.replace(/[?&]useskin=[a-zA-Z0-9_]+/, '');  | |||
		}  | |||
		else // not in URL  | |||
		{  | |||
			buttonName = 'Dark Mode';  | |||
			title = 'Use Dark Mode';  | |||
			if (href.includes('?'))  | |||
				href += '&' + DARKMODE_SKIN_USAGE;  | |||
			else  | |||
				href += '?' + DARKMODE_SKIN_USAGE;  | |||
		}  | |||
		var newButton = firstButton.cloneNode(true),  | |||
			link = newButton.getElementsByTagName('a')[0];  | |||
		newButton.removeAttribute('class');  | |||
		link.removeAttribute('accesskey');  | |||
		link.removeAttribute('rel');  | |||
		link.setAttribute('title', title);  | |||
		link.setAttribute('href', href);  | |||
		link.innerHTML = buttonName;  | |||
		leftTabHolder.appendChild(newButton);  | |||
	}  | 	}  | ||
/*****************************************************************************************/  | 	/*****************************************************************************************  | ||
	 * Function that adds the currently-used 'useskin' URL parameter to all relevant links in the page  | |||
	 * Maintainer: [[User:Lou Montana]]  | |||
	 */  | |||
	function setAllLinksToUseForcedSkin() {  | |||
		var usedSkin = mw.util.getParamValue('useskin');  | |||
		if (usedSkin == null || usedSkin == '')  | |||
			return;  | |||
		var allLinks = document.getElementsByTagName('a');  | |||
		var link;  | |||
		var href;  | |||
		for (var i = 0, count = allLinks.length - 1; i < count; i++)  | |||
		{  | |||
			link = allLinks[i];  | |||
			href = link.href;  | |||
			if (href == null || href == '')  | |||
				continue;  | |||
/  | 			// only httpS wiki links, no javascript:, no #, no enfusion:// or other protocol  | ||
			if (!(href.startsWith('https://community.bistudio.com/') || href.startsWith('https://community.bohemia.net/') || href.startsWith('/wiki/')))  | |||
				continue;  | |||
			if (href.indexOf(SKIN_USAGE) !== -1)  | |||
				continue; // already has a skin assigned  | |||
			var poundIndex = href.indexOf('#');  | |||
			if (href.indexOf('?') !== -1)  | |||
			{  | |||
				if (poundIndex !== -1)  | |||
					href = href.replace('#', '&' + SKIN_USAGE + usedSkin + '#');  | |||
				else  | |||
					href += '&' + SKIN_USAGE + usedSkin;  | |||
			}  | 			}  | ||
			else // no ?x=y parameters  | |||
			{  | |||
				if (poundIndex !== -1)  | |||
					href = href.replace('#', '?' + SKIN_USAGE + usedSkin + '#');  | |||
				else  | |||
					href += '?' + SKIN_USAGE + usedSkin;  | |||
			}  | 			}  | ||
			link.href = href;  | |||
		}  | |||
	}  | 	}  | ||
/  | 	// if 'useskin' is used, apply it to all links  | ||
	if (mw.util.getParamValue('useskin'))  | |||
		mw.hook( 'wikipage.content' ).add( setAllLinksToUseForcedSkin );  | |||
/  | 	// no ES5 promise, use jQuery  | ||
	$.getJSON('/wikidata/api.php?action=query&meta=userinfo&format=json').done(function(response) {  | |||
		if (response != null && response.query.userinfo.id === 0) {	// not logged in  | |||
			mw.hook( 'wikipage.content' ).add( addDarkOrDefaultModeButton );  | |||
			// hopefully -after- setAllLinksToUseForcedSkin so the button's URL is not changed by it  | |||
		}  | |||
			/  | |||
		}  | |||
	});  | 	});  | ||
/*  | }); /* END mw.loader WRAPPER */  | ||
Latest revision as of 23:46, 10 March 2024
/*****************************************************************************************
 * This JavaScript file will be loaded for all users on every page load
 * Its content must be kept as minimal as possible.
 *****************************************************************************************/
mw.loader.using( ['mediawiki.util', 'jquery.client'], function() { /* BEGIN mw.loader WRAPPER */
	/*****************************************************************************************
	 * Conditionally import further JavaScript for specific situations.
	 */
	function conditionallyImport() {
		if ( mw.config.get( 'wgAction' ) === 'edit' || mw.config.get( 'wgAction' ) === 'submit' ) {
			importScript( 'MediaWiki:Editing.js' );
			// mw.loader.load( '/wiki/index.php?title=MediaWiki:Editing.js&action=raw&ctype=text/javascript' ); // proper thing to do - for future reference
		}
		if ( mw.config.get( 'wgCanonicalNamespace' ) != 'MediaWiki' && mw.config.get( 'wgArticleId' ) === 0 ) {
			importScript( 'MediaWiki:Creation.js' );
		}
		if ( mw.config.get( 'wgPageName' ) === 'Special:Version' ) {
			importScript( 'MediaWiki:SpecialVersion.js' );
		}
	}
	mw.hook( 'wikipage.content' ).add( conditionallyImport );
	/*****************************************************************************************
	 * Add a Purge button
	 * Maintainer: [[User:Lou Montana]]
	 */
	function offerPurgeButton() {
		var protectButton = document.getElementById('ca-protect');
		if (protectButton == null) {
			protectButton = document.getElementById('ca-unprotect');
			if (protectButton == null) {
				return; // quick'n'not that dirty
			}
		}
		var newButton = protectButton.cloneNode(true),
			link = newButton.getElementsByTagName('a')[0];
		link.removeAttribute('accesskey');
		link.setAttribute('title', 'Purge the page\'s cache');
		link.setAttribute('href', document.location.href + (document.location.href.indexOf('?') === -1 ? '?action=purge' : '&action=purge'));
		link.innerHTML = 'Purge';
		protectButton.parentNode.appendChild(newButton);
	}
	mw.hook( 'wikipage.content' ).add( offerPurgeButton );
	/*****************************************************************************************
	 * Add a Fix access button
	 * Maintainer: [[User:Lou Montana]]
	 */
	function offerDeleteSessionCookieButton() {
		var protectButton = document.getElementById('ca-protect');
		if (protectButton == null) {
			protectButton = document.getElementById('ca-unprotect');
			if (protectButton == null) {
				return; // quick'n'not that dirty
			}
		}
		var newButton = protectButton.cloneNode(true),
			link = newButton.getElementsByTagName('a')[0];
		link.removeAttribute('accesskey');
		link.setAttribute('title', 'Delete the community_session cookie to fix the DbQueryError issue');
		link.setAttribute('href', '/clearcookie.php?url=' + document.location.href);
		link.innerHTML = 'Fix access';
		protectButton.parentNode.appendChild(newButton);
	}
	// mw.hook( 'wikipage.content' ).add( offerDeleteSessionCookieButton ); // disabled for now, -should- be fixed
	/*****************************************************************************************
	 * Disable Talk pages
	 * Maintainer: [[User:Lou Montana]]
	 */
	function disableTalkPages() {
		if ($.inArray('sysop', mw.config.get('wgUserGroups')) === -1) { // not admin
			if (mw.config.get('wgCanonicalNamespace').indexOf('talk') !== -1 && // talk page
				mw.config.get('wgNamespaceNumber') !== 3) { // User Talk exception
				if (document.getElementById('ca-edit') != null) {
					document.getElementById('ca-edit').remove();
				}
				if (document.getElementById('ca-addsection') != null) {
					document.getElementById('ca-addsection').remove();
				}
			}
			var talkTab = document.getElementById('ca-talk');
			if (talkTab != null && talkTab.classList.contains('new')) {
				talkTab.remove();
			}
		}
	}
	mw.hook( 'wikipage.content' ).add( disableTalkPages );
	/*****************************************************************************************
	 * Function that adds a Sandbox button
	 * Maintainer: [[User:Lou Montana]]
	 */
	function addSandboxButton() {
		var userpageLink = document.getElementById('pt-userpage');
		var talkLink = document.getElementById('pt-mytalk');
		if (talkLink == null) {
			return;
		}
		var sandboxLink = talkLink.cloneNode(true),
			link = sandboxLink.getElementsByTagName('a')[0];
		link.removeAttribute('accesskey');
		link.setAttribute('title', 'Your Sandbox');
		link.setAttribute('href', userpageLink.getElementsByTagName('a')[0].href + '/Sandbox');
		link.innerHTML = 'Sandbox';
		talkLink.parentNode.insertBefore(sandboxLink, talkLink);
	}
	mw.hook( 'wikipage.content' ).add( addSandboxButton );
	/*****************************************************************************************
	 * Functions that adds Tabs
	 * Maintainer: [[User:Lou Montana]]
	 */
	function tabSystem_selectTab(titles, contents, tabIndex) {
		var i;
		for (i = 0; i < titles.length; i++) {
			titles[i].classList.remove('selected');
		}
		for (i = 0; i < contents.length; i++) {
			contents[i].style.display = 'none';
		}
		if (tabIndex < 0 || tabIndex > titles.length -1 || tabIndex > contents.length -1) {
			return;
		}
		titles[tabIndex].classList.add('selected');
		contents[tabIndex].style.display = 'block';
	}
	function tabSystem_implementTabs() {
		var tabBlocks = document.getElementsByClassName('biki-tabs');
		for (var i = 0; i < tabBlocks.length; i++) {
			var tabBlock = tabBlocks[i];
			var titles = tabBlock.getElementsByClassName('biki-tab-title');
			var contents = tabBlock.getElementsByClassName('biki-tab-content');
			if (titles.length < 1 || contents.length < 1 || titles.length != contents.length) {
				continue;
			}
			for (var j = 0; j < titles.length; j++) {
				(function(titles, contents, index) {
					titles[j].addEventListener('click', function () { tabSystem_selectTab(titles, contents, index) })
				})(titles, contents, j);
			}
			var selectedTab = 0;
			if (tabBlock.dataset && tabBlock.dataset.selectedtab) {
				var dataSelectedTab = +tabBlock.dataset.selectedtab;
				if (!isNaN(dataSelectedTab)) {
					selectedTab = Math.max(0, Math.min(dataSelectedTab, titles.length -1));
				}
			}
			tabSystem_selectTab(titles, contents, selectedTab);
		}
	}
	mw.hook( 'wikipage.content' ).add( tabSystem_implementTabs );
	/*****************************************************************************************
	 * Function that adds Dark/Default Mode button for non logged-in users
	 * (logged-in users can select their skin in Parameters)
	 * Maintainer: [[User:Lou Montana]]
	 */
	const SKIN_USAGE = 'useskin=';
	function addDarkOrDefaultModeButton() {
		const DARKMODE_SKIN = 'darkvector';
		const DARKMODE_SKIN_USAGE = SKIN_USAGE + DARKMODE_SKIN;
		var leftTabHolder = document.getElementById('p-namespaces').getElementsByTagName('ul')[0]; // <ul>
		if (leftTabHolder == null)
			return;
		var firstButton = leftTabHolder .children[0]; // <li>
		if (firstButton == null)
			return; // quick'n'not that dirty
		var buttonName;
		var title;
		var href = document.documentURI;
		if (href.indexOf(DARKMODE_SKIN_USAGE) !== -1)
		{
			buttonName = 'Default Mode';
			title = 'Go back to the default skin';
			href = href.replace(/[?&]useskin=[a-zA-Z0-9_]+/, '');
		}
		else // not in URL
		{
			buttonName = 'Dark Mode';
			title = 'Use Dark Mode';
			if (href.includes('?'))
				href += '&' + DARKMODE_SKIN_USAGE;
			else
				href += '?' + DARKMODE_SKIN_USAGE;
		}
		var newButton = firstButton.cloneNode(true),
			link = newButton.getElementsByTagName('a')[0];
		newButton.removeAttribute('class');
		link.removeAttribute('accesskey');
		link.removeAttribute('rel');
		link.setAttribute('title', title);
		link.setAttribute('href', href);
		link.innerHTML = buttonName;
		leftTabHolder.appendChild(newButton);
	}
	/*****************************************************************************************
	 * Function that adds the currently-used 'useskin' URL parameter to all relevant links in the page
	 * Maintainer: [[User:Lou Montana]]
	 */
	function setAllLinksToUseForcedSkin() {
		var usedSkin = mw.util.getParamValue('useskin');
		if (usedSkin == null || usedSkin == '')
			return;
		var allLinks = document.getElementsByTagName('a');
		var link;
		var href;
		for (var i = 0, count = allLinks.length - 1; i < count; i++)
		{
			link = allLinks[i];
			href = link.href;
			if (href == null || href == '')
				continue;
			// only httpS wiki links, no javascript:, no #, no enfusion:// or other protocol
			if (!(href.startsWith('https://community.bistudio.com/') || href.startsWith('https://community.bohemia.net/') || href.startsWith('/wiki/')))
				continue;
			if (href.indexOf(SKIN_USAGE) !== -1)
				continue; // already has a skin assigned
			var poundIndex = href.indexOf('#');
			if (href.indexOf('?') !== -1)
			{
				if (poundIndex !== -1)
					href = href.replace('#', '&' + SKIN_USAGE + usedSkin + '#');
				else
					href += '&' + SKIN_USAGE + usedSkin;
			}
			else // no ?x=y parameters
			{
				if (poundIndex !== -1)
					href = href.replace('#', '?' + SKIN_USAGE + usedSkin + '#');
				else
					href += '?' + SKIN_USAGE + usedSkin;
			}
			link.href = href;
		}
	}
	// if 'useskin' is used, apply it to all links
	if (mw.util.getParamValue('useskin'))
		mw.hook( 'wikipage.content' ).add( setAllLinksToUseForcedSkin );
	// no ES5 promise, use jQuery
	$.getJSON('/wikidata/api.php?action=query&meta=userinfo&format=json').done(function(response) {
		if (response != null && response.query.userinfo.id === 0) {	// not logged in
			mw.hook( 'wikipage.content' ).add( addDarkOrDefaultModeButton );
			// hopefully -after- setAllLinksToUseForcedSkin so the button's URL is not changed by it
		}
	});
}); /* END mw.loader WRAPPER */