MediaWiki:Common.js

From BZPB Wiki
Jump to navigationJump to search

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/* Any JavaScript here will be loaded for all users on every page load. */

/**
 * Dynamic Navigation Bars. See [[Wikipedia:NavFrame]]
 * 
 * Based on script from en.wikipedia.org, 2008-09-15.
 *
 * @source www.mediawiki.org/wiki/MediaWiki:Gadget-NavFrame.js
 * @maintainer Helder.wiki, 2012–2013
 * @maintainer Krinkle, 2013
 */
( function () {

// Set up the words in your language
var collapseCaption = 'hide';
var expandCaption = 'show';

var navigationBarHide = '[' + collapseCaption + ']';
var navigationBarShow = '[' + expandCaption + ']';

/**
 * Shows and hides content and picture (if available) of navigation bars.
 *
 * @param {number} indexNavigationBar The index of navigation bar to be toggled
 * @param {jQuery.Event} e Event object
 */
function toggleNavigationBar( indexNavigationBar, e ) {
	var navChild,
		navToggle = document.getElementById( 'NavToggle' + indexNavigationBar ),
		navFrame = document.getElementById( 'NavFrame' + indexNavigationBar );

	// Prevent browser from jumping to href "#"
	e.preventDefault();

	if ( !navFrame || !navToggle ) {
		return false;
	}

	// If shown now
	if ( navToggle.firstChild.data == navigationBarHide ) {
		for ( navChild = navFrame.firstChild; navChild != null; navChild = navChild.nextSibling ) {
			if ( hasClass( navChild, 'NavPic' ) ) {
				navChild.style.display = 'none';
			}
			if ( hasClass( navChild, 'NavContent' ) ) {
				navChild.style.display = 'none';
			}
		}
		navToggle.firstChild.data = navigationBarShow;

	// If hidden now
	} else if ( navToggle.firstChild.data == navigationBarShow ) {
		for ( navChild = navFrame.firstChild; navChild != null; navChild = navChild.nextSibling ) {
			if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
				navChild.style.display = 'block';
			}
		}
		navToggle.firstChild.data = navigationBarHide;
	}
}

/**
 * Adds show/hide-button to navigation bars.
 *
 * @param {jQuery} $content
 */
function createNavigationBarToggleButton( $content ) {
	var i, j, navFrame, navToggle, navToggleText, navChild,
		indexNavigationBar = 0,
		navFrames = $content.find( 'div.NavFrame' ).toArray();

	// Iterate over all (new) nav frames
	for ( i = 0; i < navFrames.length; i++ ) {
		navFrame = navFrames[i];
		// If found a navigation bar
		indexNavigationBar++;
		navToggle = document.createElement( 'a' );
		navToggle.className = 'NavToggle';
		navToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
		navToggle.setAttribute( 'href', '#' );
		$( navToggle ).on( 'click', $.proxy( toggleNavigationBar, null, indexNavigationBar ) );

		navToggleText = document.createTextNode( navigationBarHide );
		for ( navChild = navFrame.firstChild; navChild != null; navChild = navChild.nextSibling ) {
			if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
				if ( navChild.style.display == 'none' ) {
					navToggleText = document.createTextNode( navigationBarShow );
					break;
				}
			}
		}

		navToggle.appendChild( navToggleText );
		// Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
		for ( j = 0; j < navFrame.childNodes.length; j++ ) {
			if ( $( navFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
				navFrame.childNodes[j].appendChild( navToggle );
			}
		}
		navFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
	}
}

mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );

}());

/**
 * Collapsible tables
 *
 * Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].
 *
 * @version 2.0.3 (2014-03-14)
 * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
 * @author [[User:R. Koot]]
 * @author [[User:Krinkle]]
 * @deprecated Since MediaWiki 1.20: Use class="mw-collapsible" instead which
 * is supported in MediaWiki core.
 */

var autoCollapse = 2;
var collapseCaption = 'hide';
var expandCaption = 'show';
var tableIndex = 0;

function collapseTable( tableIndex ) {
    var Button = document.getElementById( 'collapseButton' + tableIndex );
    var Table = document.getElementById( 'collapsibleTable' + tableIndex );

    if ( !Table || !Button ) {
        return false;
    }

    var Rows = Table.rows;
    var i;
    var $row0 = $(Rows[0]);

    if ( Button.firstChild.data === collapseCaption ) {
        for ( i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = 'none';
        }
        Button.firstChild.data = expandCaption;
    } else {
        for ( i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = $row0.css( 'display' );
        }
        Button.firstChild.data = collapseCaption;
    }
}

function createClickHandler( tableIndex ) {
    return function ( e ) {
        e.preventDefault();
        collapseTable( tableIndex );
    };
}

function createCollapseButtons( $content ) {
    var NavigationBoxes = {};
    var $Tables = $content.find( 'table' );
    var i;

    $Tables.each( function( i, table ) {
        if ( $(table).hasClass( 'collapsible' ) ) {

            /* only add button and increment count if there is a header row to work with */
            var HeaderRow = table.getElementsByTagName( 'tr' )[0];
            if ( !HeaderRow ) {
                return;
            }
            var Header = table.getElementsByTagName( 'th' )[0];
            if ( !Header ) {
                return;
            }

            NavigationBoxes[ tableIndex ] = table;
            table.setAttribute( 'id', 'collapsibleTable' + tableIndex );

            var Button     = document.createElement( 'span' );
            var ButtonLink = document.createElement( 'a' );
            var ButtonText = document.createTextNode( collapseCaption );
            // Styles are declared in [[MediaWiki:Common.css]]
            Button.className = 'collapseButton';

            ButtonLink.style.color = Header.style.color;
            ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
            ButtonLink.setAttribute( 'href', '#' );
            $( ButtonLink ).on( 'click', createClickHandler( tableIndex ) );
            ButtonLink.appendChild( ButtonText );

            Button.appendChild( document.createTextNode( '[' ) );
            Button.appendChild( ButtonLink );
            Button.appendChild( document.createTextNode( ']' ) );

            Header.insertBefore( Button, Header.firstChild );
            tableIndex++;
        }
    } );

    for ( i = 0;  i < tableIndex; i++ ) {
        if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) ||
            ( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) )
        ) {
            collapseTable( i );
        }
        else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) {
            var element = NavigationBoxes[i];
            while ((element = element.parentNode)) {
                if ( $( element ).hasClass( 'outercollapse' ) ) {
                    collapseTable ( i );
                    break;
                }
            }
        }
    }
}

mw.hook( 'wikipage.content' ).add( createCollapseButtons );

/**
 * Add support to mw-collapsible for autocollapse, innercollapse and outercollapse
 *
 * Maintainers: TheDJ
 */
function mwCollapsibleSetup( $collapsibleContent ) {
	var $element,
	    $toggle,
		autoCollapseThreshold = 2;
	$.each( $collapsibleContent, function (index, element) {
		$element = $( element );
		if ( $collapsibleContent.length > autoCollapseThreshold && $element.hasClass( 'autocollapse' ) ) {
			$element.data( 'mw-collapsible' ).collapse();
		} else if ( $element.hasClass( 'innercollapse' ) ) {
			if ( $element.parents( '.outercollapse' ).length > 0 ) {
				$element.data( 'mw-collapsible' ).collapse();
			}
		}
		$toggle = $element.find( '.mw-collapsible-toggle' );
		if ( $toggle.length ) {
			// Make the toggle inherit text color
			if( $toggle.parent()[0].style.color ) {
				$toggle.find( 'a' ).css( 'color', 'inherit' );
			}
		}
	} );
}

mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );

/**
 * 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();
} );

/* Reference Pop Ups */

importScriptPage('ReferencePopups/code.js', 'dev');

importArticles({
    type: 'script',
    articles: [
        'u:dev:ReferencePopups/code.js',
    ]
});

importScriptURI("http://en.wikipedia.org/w/index.php?title=User:Blue-Haired_Lawyer/footnote_popups.js&action=raw&ctype=text/javascript");