MediaWiki:Common.js

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

/** * 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 ); /** Dynamic Navigation Bars (experimental) ************************************* * * Description: See NavFrame. * Maintainers: UNMAINTAINED */ // set up the words in your language var NavigationBarHide = '[' + collapseCaption + ']'; var NavigationBarShow = '[' + expandCaption + ']'; // shows and hides content and picture (if available) of navigation bars // Parameters: //    indexNavigationBar: the index of navigation bar to be toggled function toggleNavigationBar(indexNavigationBar) {   var NavToggle = document.getElementById("NavToggle" + indexNavigationBar); var NavFrame = document.getElementById("NavFrame" + indexNavigationBar); if (!NavFrame || !NavToggle) { return false; }   // if shown now if (NavToggle.firstChild.data == NavigationBarHide) { for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) { if ($(NavChild).hasClass('NavContent') || $(NavChild).hasClass('NavPic')) { NavChild.style.display = 'none'; }       }    NavToggle.firstChild.data = NavigationBarShow; // if hidden now } else if (NavToggle.firstChild.data == NavigationBarShow) { for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) { if ($(NavChild).hasClass('NavContent') || $(NavChild).hasClass('NavPic')) { NavChild.style.display = 'block'; }       }        NavToggle.firstChild.data = NavigationBarHide; } } // adds show/hide-button to navigation bars function createNavigationBarToggleButton {   var indexNavigationBar = 0; // iterate over all -elements var divs = document.getElementsByTagName("div"); for (var i = 0; NavFrame = divs[i]; i++) { // if found a navigation bar if ($(NavFrame).hasClass("NavFrame")) { indexNavigationBar++; var NavToggle = document.createElement("a"); NavToggle.className = 'NavToggle'; NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar); NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');'); var isCollapsed = $(NavFrame).hasClass("collapsed" ); /*            * Check if any children are already hidden. This loop is here for backwards compatibility: * the old way of making NavFrames start out collapsed was to manually add style="display:none" * to all the NavPic/NavContent elements. Since this was bad for accessibility (no way to make            * the content visible without JavaScript support), the new recommended way is to add the class * "collapsed" to the NavFrame itself, just like with collapsible tables. */           for (var NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling) { if ($(NavChild).hasClass('NavPic' ) || $(NavChild).hasClass('NavContent' ) ) { if ( NavChild.style.display == 'none' ) { isCollapsed = true; }               }            }            if (isCollapsed) { for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) { if ( $(NavChild).hasClass('NavPic' ) || $(NavChild).hasClass('NavContent' ) ) { NavChild.style.display = 'none'; }               }            }            var NavToggleText = document.createTextNode(isCollapsed ? NavigationBarShow : NavigationBarHide); NavToggle.appendChild(NavToggleText); // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) for(var j=0; j < NavFrame.childNodes.length; j++) { if ($(NavFrame.childNodes[j]).hasClass("NavHead")) { NavToggle.style.color = NavFrame.childNodes[j].style.color; NavFrame.childNodes[j].appendChild(NavToggle); }           }            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar); }   } } $( createNavigationBarToggleButton );

/* displayTimer.js taken from http://bulbapedia.bulbagarden.net/wiki/MediaWiki:Monobook.js  Add the following to your vector.js file for customisation: timerDisplay = false; // de-activates the timer timerTimezone = [offset]; // set the timer offset, e.g. timerTimezone = +10; for AEST */ //hookEvent( 'load', displayTimer ); function displayTimer { if ( typeof( timerDisplay ) !== 'undefined' && timerDisplay === false ) return; var date; var timerParent = document.getElementById( 'p-personal' ).getElementsByTagName( 'ul' )[0]; var timerLink  = document.createElement( 'a' ); var timerObj   = document.createElement( 'li' ); timerLink.href              = '/index.php?title=' + wgPageName + '&action=purge'; timerLink.title             = 'Purge the server cache and update the contents of this page.' timerObj.id                 = 'pt-timer'; timerObj.style.textTransform = 'none'; timerObj.style.fontWeight   = 'bold'; timerObj.style.fontSize     = '72%'; timerObj.appendChild( timerLink ); timerParent.insertBefore( timerObj, timerParent.firstChild ); function actualizeUTC {   timerDate           = new Date; timerLink.innerHTML = ( timerDate.getUTCHours  < 10 ? '0' : '' ) + timerDate.getUTCHours   + ':' + ( timerDate.getUTCMinutes < 10 ? '0' : '' ) + timerDate.getUTCMinutes + ':' + ( timerDate.getUTCSeconds < 10 ? '0' : '' ) + timerDate.getUTCSeconds + ' (UTC)'; } function actualizeCustom {   timerDate           = new Date; timerDate.setMinutes( timerDate.getMinutes + timerDate.getTimezoneOffset + timerTimezone * 60 ); timerLink.innerHTML = ( timerDate.getHours  < 10 ? '0' : '' ) + timerDate.getHours   + ':' + ( timerDate.getMinutes < 10 ? '0' : '' ) + timerDate.getMinutes + ':' + ( timerDate.getSeconds < 10 ? '0' : '' ) + timerDate.getSeconds + ' (UTC' + ( timerTimezone < 0 ? '' : '+' ) + timerTimezone + ')'; } // start if ( typeof( timerTimezone ) !== 'number' ) {   actualizeUTC; setInterval( actualizeUTC, 1000 ); } else {   actualizeCustom; setInterval( actualizeCustom, 1000 ); } }

// Add a new section link to the bottom of discussion pages function addsectionbottom { if (!wgIsArticle) return; if ((document.URL.indexOf('?')>=0) && (document.URL.indexOf('action=delete')>=0)) return; var caplus; if (!(caplus = document.getElementById("ca-addsection"))) return; var addsection = document.createElement("span"); addsection.innerHTML = " " + (skin == "vector" ? " Add topic " : " Add section " ) + " " addsection.className = "noprint"; addsection.id = "addsectionbottom"; var content; if (!(content = document.getElementById("bodyContent"))) return; var catlinks = document.getElementById("catlinks"); if (catlinks == null) {   content.appendChild(addsection); } else { content.insertBefore(addsection, catlinks); } }

$( addsectionbottom );

// Highlight recent changes //hookEvent( 'load', recentChangesHighlights ); function recentChangesHighlights { if ( wgPageName == 'Special:RecentChanges' ) { var targetContent = document.getElementById( 'bodyContent' ); var rows = targetContent.getElementsByTagName( 'li' ); for ( var l = 0; l < rows.length; l++ ) { liHTML = rows[l].innerHTML liText = rows[l].textContent; if ( liHTML.indexOf( '/index.php?title=Special:Log/' ) != -1 ) { rows[l].style.backgroundColor = '#DDF'; }			if ( liHTML.indexOf( '/index.php?title=Special:Log/block' ) != -1 || liHTML.indexOf( '/index.php?title=Special:Log/delete' ) != -1 ) { rows[l].style.backgroundColor = '#FCC'; }			if ( liHTML.indexOf( 'class="newpage"' ) != -1 ) { rows[l].style.backgroundColor = '#DFD'; }			if ( liHTML.indexOf( 'class="minor"' ) != -1 ) { rows[l].style.backgroundColor = '#FEF'; }		}	} }

function fillBrowser { /*var matched; var browser; browser.webkit = false; browser.safari = false; browser.opera = false; browser.msie = false; browser.trident = false; browser.mozilla = false; jQuery.uaMatch = function( ua ) { ua = ua.toLowerCase;

var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || /(webkit)[ \/]([\w.]+)/.exec( ua ) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || /(msie)[\s?]([\w.]+)/.exec( ua ) || /(trident)(?:.*? rv:([\w.]+)|)/.exec( ua ) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || [];

return { browser: match[ 1 ] || "", version: match[ 2 ] || "0" }; };

matched = jQuery.uaMatch( navigator.userAgent ); //IE 11+ fix (Trident) matched.browser = matched.browser == 'trident' ? 'msie' : matched.browser; browser = {};

if ( matched.browser ) { browser[ matched.browser ] = true; browser.version = matched.version; }

// Chrome is Webkit, but Webkit is also Safari. if ( browser.chrome ) { browser.webkit = true; } else if ( browser.webkit ) { browser.safari = true; }*/ return ""; } //major stupidity ahead if(jQuery.browser !== undefined) jQuery.browser = fillBrowser; /*

https://en.wikipedia.org/wiki/MediaWiki:Gadget-switcher.js Creator: Wikipedia user Jackmcbarn CC-BY-SA

( function ( $ ) {	'use strict';	$( function { $( '.switcher-container' ).each( function ( i ) {			var activeElement, $showRadio, $showAllRadio;			var elements = [], container = this;			var radioName = 'switcher-' + i;			$( this ).children.each( function { var self = this; var $labelContainer = $( this ).find( '.switcher-label' ); var $labelText = $labelContainer.contents; if ( !$labelText.length ) { return; }				elements.push( this ); $showRadio = $( ' ' ).attr( 'name', radioName ).click( function {					$( activeElement ).hide;					$( self ).show;					activeElement = self;				} ); $( ' ' ).append( $showRadio ).append( $labelText ).appendTo( container ); if ( !activeElement ) { activeElement = this; $showRadio.prop( 'checked', true ); } else if ( $labelContainer.is( '[data-switcher-default]' ) ) { $showRadio.click; } else { $( this ).hide; }				$labelContainer.remove; } );			if ( elements.length > 1 ) {				$showAllRadio = $( ' ' ).attr( 'name', radioName ).click( function { $( elements ).show; activeElement = elements; } );				$( 'Show all ' ).prepend( $showAllRadio ).appendTo( container );			} else if ( elements.length === 1 ) {				$showRadio.remove;			}		} ); } ); } )( jQuery );