Difference between revisions of "MediaWiki:Common.js"

From Jadusable Wiki
Jump to navigation Jump to search
 
 
Line 1: Line 1:
 
/* Any JavaScript here will be loaded for all users on every page load. */
 
/* Any JavaScript here will be loaded for all users on every page load. */
{{:Help:Tabs/js}}
+
 
 +
/**
 +
* JS Tab System, jacked and hacked from the jsprefs in wikibits.js
 +
*
 +
* Original code by Dantman
 +
* Refactored a bit by Jack Phoenix on 11 April 2014
 +
* Support for linking to a particular tab by MatmaRex on 30 December 2016.
 +
* @note Should be rewritten to properly use jQuery like how mediawiki.special.preferences.js does.
 +
*/
 +
var TabSystem = {
 +
/**
 +
* @property {boolean}
 +
* Is the user's browser a KHTML-based one (usually, but not always, Konqueror)?
 +
*/
 +
isKHTML: ( navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ) ),
 +
 +
/**
 +
* @property {boolean}
 +
* Is the user's browser Opera?
 +
*/
 +
isOpera: navigator.userAgent.toLowerCase().indexOf( 'opera' ) != -1,
 +
 +
/*
 +
Written by Jonathan Snook, http://www.snook.ca/jonathan
 +
Add-ons by Robert Nyman, http://www.robertnyman.com
 +
Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
 +
From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
 +
*/
 +
getElementsByClassName: function( oElm, strTagName, oClassNames ) {
 +
var arrReturnElements = [];
 +
if ( typeof oElm.getElementsByClassName == 'function' ) {
 +
/* Use a native implementation where possible FF3, Saf3.2, Opera 9.5 */
 +
var arrNativeReturn = oElm.getElementsByClassName( oClassNames );
 +
if ( strTagName == '*' ) {
 +
return arrNativeReturn;
 +
}
 +
for ( var h = 0; h < arrNativeReturn.length; h++ ) {
 +
if ( arrNativeReturn[h].tagName.toLowerCase() == strTagName.toLowerCase() ) {
 +
arrReturnElements[arrReturnElements.length] = arrNativeReturn[h];
 +
}
 +
}
 +
return arrReturnElements;
 +
}
 +
 +
var arrElements = ( strTagName == '*' && oElm.all ) ? oElm.all : oElm.getElementsByTagName( strTagName );
 +
var arrRegExpClassNames = [];
 +
if ( typeof oClassNames == 'object' ) {
 +
for ( var i = 0; i < oClassNames.length; i++ ) {
 +
arrRegExpClassNames[arrRegExpClassNames.length] =
 +
new RegExp( "(^|\\s)" + oClassNames[i].replace( /\-/g, "\\-" ) + "(\\s|$)" );
 +
}
 +
} else {
 +
arrRegExpClassNames[arrRegExpClassNames.length] =
 +
new RegExp( "(^|\\s)" + oClassNames.replace( /\-/g, "\\-" ) + "(\\s|$)" );
 +
}
 +
 +
var oElement;
 +
var bMatchesAll;
 +
for ( var j = 0; j < arrElements.length; j++ ) {
 +
oElement = arrElements[j];
 +
bMatchesAll = true;
 +
for ( var k = 0; k < arrRegExpClassNames.length; k++ ) {
 +
if ( !arrRegExpClassNames[k].test( oElement.className ) ) {
 +
bMatchesAll = false;
 +
break;
 +
}
 +
}
 +
if ( bMatchesAll ) {
 +
arrReturnElements[arrReturnElements.length] = oElement;
 +
}
 +
}
 +
 +
return arrReturnElements;
 +
},
 +
 +
/**
 +
* Main function that performs all the magic on all div elements that have
 +
* class="tab" and are inside a div that has class="tabcontainer".
 +
*/
 +
main: function() {
 +
var tabcontainers = TabSystem.getElementsByClassName( document, 'div', 'tabcontainer' );
 +
for ( var tc = 0; tc < tabcontainers.length; tc++ ) {
 +
if ( !tabcontainers[tc] || !document.createElement ) {
 +
return;
 +
}
 +
if ( tabcontainers[tc].nodeName.toLowerCase() == 'a' ) {
 +
return; // Occasional IE problem
 +
}
 +
 +
tabcontainers[tc].className += ' jstabs';
 +
 +
var sections = [];
 +
var children = tabcontainers[tc].childNodes;
 +
var seci = 0;
 +
 +
for ( var i = 0; i < children.length; i++ ) {
 +
if ( children[i].className && children[i].className.match( /tab/i ) ) {
 +
children[i].id = 'tabsection-' + seci + '-' + tc;
 +
children[i].className += ' tabsection';
 +
// Opera and KHTML-based browsers get a special class
 +
if ( TabSystem.isOpera || TabSystem.isKHTML ) {
 +
children[i].className += ' tabsection operatabsection';
 +
}
 +
var legends = TabSystem.getElementsByClassName( children[i], 'div', 'tab' );
 +
sections[seci] = {};
 +
legends[0].className = 'mainTab';
 +
if ( legends[0] && legends[0].firstChild.nodeValue ) {
 +
sections[seci].text = legends[0].firstChild.nodeValue;
 +
} else {
 +
sections[seci].text = '# ' + seci;
 +
}
 +
sections[seci].secid = children[i].id;
 +
seci++;
 +
if ( sections.length != 1 ) {
 +
children[i].style.display = 'none';
 +
} else {
 +
var selectedid = children[i].id;
 +
}
 +
}
 +
}
 +
 +
var toc = document.createElement( 'ul' );
 +
toc.className = 'tabtoc';
 +
toc.id = 'tabtoc-' + tc;
 +
toc.selectedid = selectedid;
 +
 +
for ( i = 0; i < sections.length; i++ ) {
 +
var li = document.createElement( 'li' );
 +
if ( i === 0 ) {
 +
li.className = 'selected';
 +
}
 +
var a = document.createElement( 'a' );
 +
a.href = '#' + sections[i].secid;
 +
a.appendChild( document.createTextNode( sections[i].text ) );
 +
a.secid = sections[i].secid;
 +
li.appendChild( a );
 +
toc.appendChild( li );
 +
// Capture current value of variables in the closure
 +
( function ( i, a ) {
 +
$( window ).on( 'hashchange', function () {
 +
if ( location.hash === '#' + sections[i].secid ) {
 +
TabSystem.uncoverTabSection( toc, a );
 +
}
 +
} )
 +
if ( location.hash === '#' + sections[i].secid ) {
 +
TabSystem.uncoverTabSection( toc, a );
 +
}
 +
} )( i, a );
 +
}
 +
 +
tabcontainers[tc].parentNode.insertBefore( toc, tabcontainers[tc] );
 +
}
 +
},
 +
 +
/**
 +
* Show the contents of a tab section when the user clicks on the tab.
 +
*
 +
* @return {boolean} Always false
 +
*/
 +
uncoverTabSection: function( ul, a ) {
 +
var oldsecid = ul.selectedid;
 +
var newsec = document.getElementById( a.secid );
 +
if ( oldsecid != a.secid ) {
 +
document.getElementById( oldsecid ).style.display = 'none';
 +
newsec.style.display = 'block';
 +
ul.selectedid = a.secid;
 +
var lis = ul.getElementsByTagName( 'li' );
 +
for ( var i = 0; i < lis.length; i++ ) {
 +
lis[i].className = '';
 +
}
 +
a.parentNode.className = 'selected';
 +
}
 +
return false;
 +
}
 +
};
 +
 +
// Attach the onload handler using jQuery.
 +
$( function() {
 +
TabSystem.main();
 +
} );

Latest revision as of 16:12, 23 July 2020

/* Any JavaScript here will be loaded for all users on every page load. */

/**
 * JS Tab System, jacked and hacked from the jsprefs in wikibits.js
 *
 * Original code by Dantman
 * Refactored a bit by Jack Phoenix on 11 April 2014
 * Support for linking to a particular tab by MatmaRex on 30 December 2016.
 * @note Should be rewritten to properly use jQuery like how mediawiki.special.preferences.js does.
 */
var TabSystem = {
	/**
	 * @property {boolean}
	 * Is the user's browser a KHTML-based one (usually, but not always, Konqueror)?
	 */
	isKHTML: ( navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ) ),
 
	/**
	 * @property {boolean}
	 * Is the user's browser Opera?
	 */
	isOpera: navigator.userAgent.toLowerCase().indexOf( 'opera' ) != -1,
 
	/*
		Written by Jonathan Snook, http://www.snook.ca/jonathan
		Add-ons by Robert Nyman, http://www.robertnyman.com
		Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
		From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
	*/
	getElementsByClassName: function( oElm, strTagName, oClassNames ) {
		var arrReturnElements = [];
		if ( typeof oElm.getElementsByClassName == 'function' ) {
			/* Use a native implementation where possible FF3, Saf3.2, Opera 9.5 */
			var arrNativeReturn = oElm.getElementsByClassName( oClassNames );
			if ( strTagName == '*' ) {
				return arrNativeReturn;
			}
			for ( var h = 0; h < arrNativeReturn.length; h++ ) {
				if ( arrNativeReturn[h].tagName.toLowerCase() == strTagName.toLowerCase() ) {
					arrReturnElements[arrReturnElements.length] = arrNativeReturn[h];
				}
			}
			return arrReturnElements;
		}
 
		var arrElements = ( strTagName == '*' && oElm.all ) ? oElm.all : oElm.getElementsByTagName( strTagName );
		var arrRegExpClassNames = [];
		if ( typeof oClassNames == 'object' ) {
			for ( var i = 0; i < oClassNames.length; i++ ) {
				arrRegExpClassNames[arrRegExpClassNames.length] =
					new RegExp( "(^|\\s)" + oClassNames[i].replace( /\-/g, "\\-" ) + "(\\s|$)" );
			}
		} else {
			arrRegExpClassNames[arrRegExpClassNames.length] =
				new RegExp( "(^|\\s)" + oClassNames.replace( /\-/g, "\\-" ) + "(\\s|$)" );
		}
 
		var oElement;
		var bMatchesAll;
		for ( var j = 0; j < arrElements.length; j++ ) {
			oElement = arrElements[j];
			bMatchesAll = true;
			for ( var k = 0; k < arrRegExpClassNames.length; k++ ) {
				if ( !arrRegExpClassNames[k].test( oElement.className ) ) {
					bMatchesAll = false;
					break;
				}
			}
			if ( bMatchesAll ) {
				arrReturnElements[arrReturnElements.length] = oElement;
			}
		}
 
		return arrReturnElements;
	},
 
	/**
	 * Main function that performs all the magic on all div elements that have
	 * class="tab" and are inside a div that has class="tabcontainer".
	 */
	main: function() {
		var tabcontainers = TabSystem.getElementsByClassName( document, 'div', 'tabcontainer' );
		for ( var tc = 0; tc < tabcontainers.length; tc++ ) {
			if ( !tabcontainers[tc] || !document.createElement ) {
				return;
			}
			if ( tabcontainers[tc].nodeName.toLowerCase() == 'a' ) {
				return; // Occasional IE problem
			}
 
			tabcontainers[tc].className += ' jstabs';
 
			var sections = [];
			var children = tabcontainers[tc].childNodes;
			var seci = 0;
 
			for ( var i = 0; i < children.length; i++ ) {
				if ( children[i].className && children[i].className.match( /tab/i ) ) {
					children[i].id = 'tabsection-' + seci + '-' + tc;
					children[i].className += ' tabsection';
					// Opera and KHTML-based browsers get a special class
					if ( TabSystem.isOpera || TabSystem.isKHTML ) {
						children[i].className += ' tabsection operatabsection';
					}
					var legends = TabSystem.getElementsByClassName( children[i], 'div', 'tab' );
					sections[seci] = {};
					legends[0].className = 'mainTab';
					if ( legends[0] && legends[0].firstChild.nodeValue ) {
						sections[seci].text = legends[0].firstChild.nodeValue;
					} else {
						sections[seci].text = '# ' + seci;
					}
					sections[seci].secid = children[i].id;
					seci++;
					if ( sections.length != 1 ) {
						children[i].style.display = 'none';
					} else {
						var selectedid = children[i].id;
					}
				}
			}
 
			var toc = document.createElement( 'ul' );
			toc.className = 'tabtoc';
			toc.id = 'tabtoc-' + tc;
			toc.selectedid = selectedid;
 
			for ( i = 0; i < sections.length; i++ ) {
				var li = document.createElement( 'li' );
				if ( i === 0 ) {
					li.className = 'selected';
				}
				var a = document.createElement( 'a' );
				a.href = '#' + sections[i].secid;
				a.appendChild( document.createTextNode( sections[i].text ) );
				a.secid = sections[i].secid;
				li.appendChild( a );
				toc.appendChild( li );
				// Capture current value of variables in the closure
				( function ( i, a ) {
					$( window ).on( 'hashchange', function () {
						if ( location.hash === '#' + sections[i].secid ) {
							TabSystem.uncoverTabSection( toc, a );
						}
					} )
					if ( location.hash === '#' + sections[i].secid ) {
						TabSystem.uncoverTabSection( toc, a );
					}
				} )( i, a );
			}
 
			tabcontainers[tc].parentNode.insertBefore( toc, tabcontainers[tc] );
		}
	},
 
	/**
	 * Show the contents of a tab section when the user clicks on the tab.
	 *
	 * @return {boolean} Always false
	 */
	uncoverTabSection: function( ul, a ) {
		var oldsecid = ul.selectedid;
		var newsec = document.getElementById( a.secid );
		if ( oldsecid != a.secid ) {
			document.getElementById( oldsecid ).style.display = 'none';
			newsec.style.display = 'block';
			ul.selectedid = a.secid;
			var lis = ul.getElementsByTagName( 'li' );
			for ( var i = 0; i < lis.length; i++ ) {
				lis[i].className = '';
			}
			a.parentNode.className = 'selected';
		}
		return false;
	}
};
 
// Attach the onload handler using jQuery.
$( function() {
	TabSystem.main();
} );