Help:Tabs/js
ShoutWiki — express yourself and be heard!
Jump to navigation
Jump to search
/**
* 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();
} );