MediaWiki:Common.js

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

/** Infobox collapsing script **/ $(".infoboxBlockImage img").each(function{	width = parseInt($(this).attr("width"), 10);	if(width > 240){		$(this).attr("height","");		$(this).attr("width","240");	} });

$(".infobox:not(.infoboxNoCollapse) td").each(function{	if($(this).html.match(/}/)) $(this).parent("tr").hide });

$(".infobox:not(.infoboxNoCollapse) .infoboxSubsectionBreak, .infobox:not(.infoboxNoCollapse) tr.infoboxSectionHeader").each(function{	flag = true;	next = $(this).next;	while(next && next != undefined && next.html != undefined && !next.hasClass("infoboxSubsectionBreak") && !next.hasClass("infoboxSectionHeader")){		if(next.css("display") != "none") flag = false;		//console.info(next.html);		next = next.next;	}	//console.info(flag);	if(flag) $(this).hide; });

/** Ore dict testing script **/ if($(".OreDictTestingScriptsOutput").length){ notices = 0; errs = 0; warns = 0; $(".gridContainer .gridImage").each(function{		tgt = "";		if($(this).children("span").children("a.new").length){			warns++;			tgt = $(this).children("span").children("a.new").attr("href").match(/\/index.php\?title=([^&]+)&action=edit&redlink=1/);			if(tgt != null) {				tgt = tgt[1];				tgt = tgt.replace(/_/g," ");				$(".OreDictTestingScriptsOutput").append("WARNING: Link to a non-existent article: "+tgt+"\n");			} else {				$(".OreDictTestingScriptsOutput").append("WARNING: Link to a non-existent article: "+$(this).children("span").children("a.new").attr("href")+"\n");				errs++;				$(".OreDictTestingScriptsOutput").append("ERROR: Unexpected error.\n");			}		} else {			if($(this).children("a:not(.new)").length)				tgt = $(this).children("a:not(.new)").attr("href").match(/\/(.+)/); else { errs++; $(".OreDictTestingScriptsOutput").append("ERROR: Unexpected error.\n"); }			if(tgt != null) tgt = tgt[1]; else { notices++; $(".OreDictTestingScriptsOutput").append("NOTICE: Link overriden to none.\n"); }		}		itemName = $(this).find(".gridTooltipInner").html.match(/Variable 1: ([^<]+)/); itemMod = $(this).find(".gridTooltipInner").html.match(/Variable 3: ([^<]+)/); if(itemName != null) itemName = itemName[1]; if(itemMod != null) itemMod = itemMod[1]; if(itemName == null){ warns++; $(".OreDictTestingScriptsOutput").append("WARNING: Tooltip text overridden!\n"); }		if(itemMod == null) expected = itemName; else expected = itemName+" ("+itemMod+")"; if(tgt != null) tgt = tgt.replace(/_/g," "); if(expected != tgt) { notices++; $(".OreDictTestingScriptsOutput").append("NOTICE: Link overridden from "+expected+" to "+tgt+"!\n"); }		if($(this).children("a.new").length){ errs++; filename = $(this).children("a.new").attr("href").match(/\/index\.php\?title=Special:Upload&wpDestFile=(.+)/); $(".OreDictTestingScriptsOutput").append("ERROR: Missing file: File:"+filename[1]+"\n"); }		if(!$(this).hasClass("testingClass")){ warns++; $(".OreDictTestingScriptsOutput").append("WARNING: Image class overridden not appended!\n"); }		if(!$(this).find(".tooltip").hasClass("testingClass")){ warns++; $(".OreDictTestingScriptsOutput").append("WARNING: Image class overridden not appended!\n"); }		if($(this).find(".gridNumber a, .gridNumber span").html != "8"){ errs++; $(".OreDictTestingScriptsOutput").append("ERROR: Item count overridden!\n"); }	});	if(errs + warns == 0) $(".OreDictTestingScriptsOutput").append("Done. "+notices+" notices, no warnings, no errors .");	else $(".OreDictTestingScriptsOutput").append("Done. "+notices+" notices , "+errs+" errors , "+warns+" <span style=\"color:orange; font-weight:bold;\">warnings ."); }

// Remove title from grid links $(".gridImage .gridNumber a").removeAttr("title");

/** Langbar **/ $(".langbarLink").children("a.new").parent(".langbarLink").hide;

/** Tanks **/ /** Resize clip parent **/ $(".tankClip").each(function(e){	$(this).parent("div").height($(this).children("img").height).width($(this).children("img").width); }); /** Clip tank image **/ $(".gridTankContainer").each(function{	// Tile liquid image	$(this).find(".tankLiquidImage").each(function{ var imglink = $(this).find("img").attr("src"); $(this).find("img").hide; $(this).css({			backgroundImage: 'url(' + imglink + ')',			backgroundRepeat: 'repeat'		}); });	$(this).find(".tankLiquidImage").height($(this).height);	$(this).find(".tankLiquidImage").width($(this).width);	$(this).find(".tankLiquidImageContainer").height($(this).height);	$(this).find(".tankLiquidImageContainer").width($(this).width);	// Get tank info	var max = parseInt($(this).find(".tankMax").html, 10);	$(this).find(".tankLiquidImage").each(function{ var usage = parseInt($(this).find(".tankUsage").html, 10); // Calculate stuff if(max == 0) max = 10000; var height = $(this).height; var width = $(this).width; var cliptop = Math.ceil(height/2*(1-usage/max))*2; $(this).css("clip","rect("+String(cliptop)+"px auto auto auto)"); // Replace vars var tooltip = $(this).parent.find(".gridTooltipInner"); if ( tooltip.length ) { var text = tooltip.html; text = text.replace("$2", usage); text = text.replace("$3", max); tooltip.html(text); }	}); });

/* $(".CraftingGrid").each(function{	maxFrames = 0;	$(this).find(".CraftingGridCell").each(function{ frames = $(this).children("span:not(.ignore), div.GridTank:not(.ignore)").length; if(frames > maxFrames){ maxFrames = frames; }		// Initialize cell states $(this).children("span:first-child:not(.ignore), div.GridTank:first-child:not(.ignore)").addClass("ActiveSlide"); });	if(maxFrames <= 1) return;	// Create crafting grid controls	$(this).append(' <input type="button" value="<" class="prevPage"> 1 / '+String(maxFrames)+' <input type="button" value=">" class="nextPage"> ');	$(this).height($(this).height + $(this).children(".CraftingGridControls").height);	// Implement controls	$(this).find(".nextPage").click(function{ container = $(this).parents(".CraftingGrid"); container.find(".CraftingGridCell").each(function{			if($(this).children(":not(.ignore)").length == 1){				$(this).removeClass(".CraftingGridCell");				return 0;			}			cur = $(this).find(".ActiveSlide");			next = cur.next("span:not(.ignore), div.GridTank:not(.ignore)");			if(next.length == 0){				next = cur.siblings("span:not(.ignore), div.GridTank:not(.ignore)").first;			}			cur.removeClass("ActiveSlide");			next.addClass("ActiveSlide");		}); pageNum = parseInt($(this).siblings("span.pageNum").html,10) + 1; if(pageNum > parseInt($(this).siblings("span.pageCount").html,10)) pageNum = 1; $(this).siblings("span.pageNum").html(pageNum); });	$(this).find(".prevPage").click(function{ container = $(this).parents(".CraftingGrid"); container.find(".CraftingGridCell").each(function{			if($(this).children(":not(.ignore)").length == 1){				$(this).removeClass(".CraftingGridCell");				return 0;			}			cur = $(this).find(".ActiveSlide");			next = cur.prev("span:not(.ignore), div.GridTank:not(.ignore)");			if(next.length == 0){				next = cur.siblings("span:not(.ignore), div.GridTank:not(.ignore)").last;			}			cur.removeClass("ActiveSlide");			next.addClass("ActiveSlide");		}); pageNum = parseInt($(this).siblings("span.pageNum").html,10) - 1; if(pageNum == 0) pageNum = parseInt($(this).siblings("span.pageCount").html,10); $(this).siblings("span.pageNum").html(pageNum); }); });
 * Automatic slide creation in crafting grids.

/*
 * Script for flipping through galleries, intended to be used with crafting grids.

$(".gallery > div, .gallery > span").addClass("page"); $(".gallery").append(' <input type="button" value="<" class="prevPage"> / <input type="button" value=">" class="nextPage"> '); $(".gallery > .page:first-child").addClass("active"); $(".gallery span.controls span.pagenum").html(1); $(".gallery").each(function{	$(this).find("span.pagecount").html($(this).children(".page").length); }); $(".gallery span.controls input.prevPage").click(function{	cur = $(this).parents(".gallery").children(".page.active");	next = cur.prev(".page");	if(next.length == 0){		next = cur.siblings(".page").last;	} 	cur.removeClass("active");	next.addClass("active");	pageNum = parseInt($(this).siblings("span.pagenum").html,10) - 1;	if(pageNum == 0) pageNum = parseInt($(this).siblings("span.pagecount").html,10);	$(this).siblings("span.pagenum").html(pageNum); }); $(".gallery span.controls input.nextPage").click(function{	cur = $(this).parents(".gallery").children(".page.active");	next = cur.next(".page");	if(next.length == 0){		next = cur.siblings(".page").first;	} 	cur.removeClass("active");	next.addClass("active");	pageNum = parseInt($(this).siblings("span.pagenum").html,10) + 1;	if(pageNum > parseInt($(this).siblings("span.pagecount").html,10)) pageNum = 1;	$(this).siblings("span.pagenum").html(pageNum); });

/*
 * Following tooltips

$(".tooltip").hide; $(".tooltip").parent.addClass("tooltipParent"); $(".tooltip").parent.mousemove(function(e){	$(this).children(".tooltip").show;	var x = Math.min(e.pageX - $(this).offset.left + 5, $(window).width - $(this).offset.left - $(this).children(".tooltip").width - 15 + $(window).scrollLeft );	$(this).children(".tooltip").css({ position: "absolute", marginLeft: 0, marginTop: 0, top: e.pageY - $(this).offset.top - 5 - $(this).children(".tooltip").outerHeight(true), left: x}); }); $(".tooltip").parent.mouseout(function{	$(this).children(".tooltip").hide; });

// Remove titles of links inside of siblings of tooltips $(".tooltipParent").children("a").attr('title','');

/** * Element animator (generic animation) * * Will cycle the active class on any child elements within an element with the animated class. */ // Remove from animated class if only one child $('.animated').each(function{   if($(this).children("span, div").length == 1){        $(this).removeClass("animated");    } }); // Add the active class to all of the first child of .animated $('.animated > span:first-child, .animated > div:first-child').addClass('active'); if ( $( '.animated' ).length ) { setInterval( function(e) {       $( '.animated' ).each( function { var current = $( this ).find( '.active' ).removeClass( 'active' ), next = current.next; if ( !current.next.length ) { next = $( this ).children.eq( 0 ); }           next.addClass( 'active' ); } );   }, 2000 ); }

/** * Pause grid templates with lots of cells in them (e.g. Template:Grid/Crafting Table) on mouseover * * This is so people have a chance to look at each image on the cell * and click on pages they want to view. */ function pauseGrid( grid ) { $( grid ).hover( function {        $( this ).find( '.grid .animated' ).removeClass( 'animated' ).addClass( 'paused' );    }, function {        $( this ).find( '.grid .paused' ).removeClass( 'paused' ).addClass( 'animated' );    } ); } pauseGrid( '.grid-Crafting_Table' ); pauseGrid( '.grid-Furnace' ); pauseGrid( '.grid-Brewing_Stand' );

/* Any JavaScript here will be loaded for all users on every page load. */ $(document).ready( function {    var pops = function( elems ) {         for (var i=0; i<elems.length; i++) {             if ( !(' '+elems[i].className+' ').match( / pops / ) ) continue;             var anchs = elems[i].getElementsByTagName('a');             for (var j=0; j<anchs.length; j++) anchs[j].target = '_blank';         }     };     var bc = document.getElementById('bodyContent');     var tags = ['span', 'div', 'table', 'td', 'th'];     for (var i=0; i<tags.length; i++) pops( bc.getElementsByTagName( tags[i] ) ); } );

function ModifySidebar(action, section, name, link) { try { switch (section) { case "languages": var target = "p-lang"; break; case "toolbox": var target = "p-tb"; break; case "navigation": var target = "p-navigation"; break; default: var target = "p-" + section; break; }       if (action == "add") { var node = document.getElementById(target) .getElementsByTagName('div')[0] .getElementsByTagName('ul')[0]; var aNode = document.createElement('a'); var liNode = document.createElement('li'); aNode.appendChild(document.createTextNode(name)); aNode.setAttribute('href', link); liNode.appendChild(aNode); liNode.className='plainlinks'; node.appendChild(liNode); }       if (action == "remove") { var list = document.getElementById(target) .getElementsByTagName('div')[0] .getElementsByTagName('ul')[0]; var listelements = list.getElementsByTagName('li'); for (var i = 0; i < listelements.length; i++) { if (listelements[i].getElementsByTagName('a')[0].innerHTML == name ||                   listelements[i].getElementsByTagName('a')[0].href == link) { list.removeChild(listelements[i]); }           }        }    } catch(e) { // lets just ignore what's happened return; } } /** Collapsible tables ********************************************************* * * Description: Allows tables to be collapsed, showing only the header. See *                        http://www.mediawiki.org/wiki/Manual:Collapsible_tables. * Maintainers: en:User:R. Koot */ var autoCollapse = 2; var collapseCaption = 'hide'; var expandCaption = 'show'; function collapseTable( tableIndex ) { var Button = document.getElementById( 'collapseButton' + tableIndex ); var Table = document.getElementById( 'collapsibleTable' + tableIndex ); if ( !Table || !Button ) { return false; }       var Rows = Table.rows; if ( Button.firstChild.data == collapseCaption ) { for ( var i = 1; i < Rows.length; i++ ) { Rows[i].style.display = 'none'; }               Button.firstChild.data = expandCaption; } else { for ( var i = 1; i < Rows.length; i++ ) { Rows[i].style.display = Rows[0].style.display; }               Button.firstChild.data = collapseCaption; } } function createCollapseButtons($content) { var tableIndex = 0; var NavigationBoxes = new Object; var Tables = $content[0].getElementsByTagName( 'table' ); for ( var i = 0; i < Tables.length; i++ ) { if ( hasClass( Tables[i], 'collapsible' ) ) { /* only add button and increment count if there is a header row to work with */ var HeaderRow = Tables[i].getElementsByTagName( 'tr' )[0]; if ( !HeaderRow ) { continue; }                       var Header = HeaderRow.getElementsByTagName( 'th' )[0]; if ( !Header ) { continue; }                       NavigationBoxes[tableIndex] = Tables[i]; Tables[i].setAttribute( 'id', 'collapsibleTable' + tableIndex ); var Button = document.createElement( 'span' ); var ButtonLink = document.createElement( 'a' ); var ButtonText = document.createTextNode( collapseCaption ); Button.className = 'collapseButton'; // Styles are declared in MediaWiki:Common.css ButtonLink.style.color = Header.style.color; ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex ); ButtonLink.setAttribute( 'href', "javascript:collapseTable(" + tableIndex + ");" ); Button.setAttribute( 'onClick', "collapseTable(" + tableIndex + ");" ); ButtonLink.appendChild( ButtonText ); Button.appendChild( document.createTextNode( '[' ) ); Button.appendChild( ButtonLink ); Button.appendChild( document.createTextNode( ']' ) ); Header.insertBefore( Button, Header.childNodes[0] ); Header.setAttribute( 'onClick', "collapseTable(" + tableIndex + ");" ); tableIndex++; }       }        for ( var i = 0;  i < tableIndex; i++ ) { if ( hasClass( NavigationBoxes[i], 'collapsed' ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], 'autocollapse' ) ) ) { collapseTable( i ); } else if ( hasClass( NavigationBoxes[i], 'innercollapse' ) ) { var element = NavigationBoxes[i]; while ( element = element.parentNode ) { if ( hasClass( element, 'outercollapse' ) ) { collapseTable( i ); break; }                       }                }        } }

mw.hook('wikipage.content').add(function ($content) { (function  { if (!$content.find('.load-page').length) { console.log('Nothing to add hooks for!'); return; }   console.log('Adding hooks!'); $content.on('click', '.load-page-button > a', function (e) {     e.preventDefault;      var $button = $(this).parent;      var $body = $button.closest('.load-page');      new mw.Api.get({ action: 'parse', prop: 'text', page: $body.data('page') }).done(function (data) { console.log('Loaded data!'); $body.html(data.parse.text['*']); mw.hook('wikipage.content').fire($body); }).fail(function (_, error) { console.log('Failed to load data!'); });     console.log('Firing request to load data!');    }); }); createCollapseButtons($content); }); /** Test if an element has a certain class ************************************** * * Description: Uses regular expressions and caching for better performance. * Maintainers: User:Mike Dillon, User:R. Koot, User:SG */ function hasClass(element, className) { return new RegExp( "(?:\\s|^)" + className + "(?:\\s|$)" ).test(element.className); }

/** * Creates minecraft style tooltips * * Replaces normal tooltips. Supports mcw:formatting codes (except k), * a description with line breaks ("/"), and character escaping with "\". */ ( function {	var $tooltip,		escapeChars = { '\\&': '&#38;', '<': '&#60;', '>': '&#62;' },		escape = function( text ) {			// "\" must be escaped first			return text.replace( /\\\\/g, '&#92;' )				.replace( /\\&|[<>]/g, function( char ) { return escapeChars[char]; } );		},		$win = $( window ), winWidth, winHeight, width, height;	$( '#mw-content-text' ).on( { 'mouseenter.minetip': function( e ) { var $elem = $( this ), title = $elem.attr( 'data-minetip-title' ); // No title or title only contains formatting codes if ( title === undefined || title && title.replace( /&([0-9a-fl-or])|\s+/g,  ) ===  ) { // Find deepest child title var childElem = $elem[0], childTitle; do { if ( childElem.hasAttribute( 'title' ) ) { childTitle = childElem.title; }					childElem = childElem.firstChild; } while( childElem && childElem.nodeType === 1 ); if ( childTitle === undefined ) { return; }				// Append child title as title may contain formatting codes if ( !title ) { title = ''; }				title += childTitle; // Set the retrieved title as data for future use $elem.attr( 'data-minetip-title', title ); }			if ( !$elem.data( 'minetip-ready' ) ) { // Remove title attributes so the native tooltip doesn't get in the way $elem.find( '[title]' ).addBack.removeAttr( 'title' ); $elem.data( 'minetip-ready', true ); }			if ( title === '' ) { return; }			// Apply normal escaping title = escape( title ); var text = ' ' + title + '&r '; var description = $elem.attr( 'data-minetip-text' ); if ( description ) { // Apply normal escaping plus "/" description = escape( description ).replace( /\\\//g, '&#47;' ); text += ' ' + description.replace( /\//g, ' ' ) + '&r '; }			// Add classes for minecraft formatting codes while ( /&[0-9a-fl-o]/.test( text ) ) { text = text.replace( /&([0-9a-fl-o])(.*?)(&r|$)/g, '<span class="format-$1">$2 &r' ); }			// Remove reset formatting text = text.replace( /&r/g, '' ); // Unescape "&" so HTML entities work text = text.replace( /&#38;/g, '&' ); $tooltip = $( '#minetip-tooltip' ); if ( !$tooltip.length ) { $tooltip = $( ' ' ).appendTo( 'body' ); }			$tooltip.html( text ); // Cache current window and tooltip size winWidth = $win.width; winHeight = $win.height; width = $tooltip.outerWidth( true ); height = $tooltip.outerHeight( true ); // Trigger a mouse movement to position the tooltip $elem.trigger( 'mousemove', e ); },		'mousemove.minetip': function( e, trigger ) { if ( !$( '#minetip-tooltip' ).length ) { $( this ).trigger( 'mouseenter' ); return; }			// Get event data from remote trigger e = trigger || e;			// Get mouse position and add default offsets var top = e.clientY - 34, left = e.clientX + 14; // If going off the right of the screen, go to the left of the cursor if ( left + width > winWidth ) { left -= width + 36; }			// If now going off to the left of the screen, resort to going above the cursor if ( left < 0 ) { left = 0; top -= height - 22; // Go below the cursor if too high if ( top < 0 ) { top += height + 47; }			// Don't go off the top of the screen } else if ( top < 0 ) { top = 0; // Don't go off the bottom of the screen } else if ( top + height > winHeight ) { top = winHeight - height; }			// Apply the positions $tooltip.css( { top: top, left: left } ); },		'mouseleave.minetip': function { if ( !$tooltip ) { return; }			$tooltip.remove; }	}, '.minetip, .grid' ); } ); $(".gridTankContainer").each(function{	// Get tank info	var max = $( this ).data( 'tank-max' ) || 10000;	// Tile liquid image	$(this).find(".tankLiquidImageContainer.minetip .tankLiquidImage").each(function{ var usage = $( this ).data( 'tank-usage' ) || 5000; var imglink = $(this).find("img").hide.attr("src"); $(this).css({			backgroundImage: 'url(' + imglink + ')',			backgroundRepeat: 'repeat',			backgroundPosition: 'bottom',			height: usage / max * 100 + '%'		}); }); });