MediaWiki:Common.js

From TerraFirmaCraft Plus Wiki
Revision as of 23:08, 16 September 2013 by Kittychanley (talk | contribs) (Added Back to Top)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Note: After publishing, 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: Press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */

/**
 * Instead of cluttering up the global scope with
 * variables, they should instead be set as an
 * object of this global variable
 *
 * E.g: Instead of
 *   window.myVar = 'blah';
 * use
 *   window.mcw.myVar = 'blah';
 */
window.mcw = {};


/**
 * Location of baseURL and wikiURL
 *
 * baseURL is where the wiki is actually installed
 * It can be seen in URLs such as index.php and api.php
 * It's usually /w/
 *
 * wikiURL is the alias for baseURL + index.php?title=
 * It can be seen when viewing any normal wiki page
 * It's usually /wiki/
 */
window.mcw.baseURL = '/';
window.mcw.wikiURL = '/wiki/';

/**
 * Collapsible tables
 *
 * Based on http://www.mediawiki.org/wiki/Manual:Collapsible_tables#Common.js_script_.28before_1.18.29
 *
 * @maintainers [[User:Ultradude25]]
 */
var collapseText = 'hide', expandText = 'show';
	
window.mcw.makeCollapsible = function() {
	var $tables = $( 'table.collapsible' );
	if ( $tables.length ) {
		var collapseButton, buttonText = ' <span class="collapsible-button">[<span class="jslink">' + collapseText + '</span>]</span> ';
		
		$tables.each( function() {
			var $table = $( this ), header;
			
			if ( $table.data( 'collapsible' ) ) {
				return true;
			}
			
			if ( $table.find( '.collapse-button' ).length ) {
				header = $table.find( 'tr:first .collapse-button' );
			} else {
				header = $table.find( 'tr:first th:first' );
			}
			
			if ( !header.length || !$table.find( 'tr' ).not( 'tr:first' ).text().replace( /\n/g, '' ).length ) {
				return true;
			}
			
			if ( $table.hasClass( 'collapse-button-none' ) ) {
				header.append( buttonText );
			} else {
				header.prepend( buttonText );
			}
			
			collapseButton = $table.find( '.collapsible-button .jslink' );
			
			if ( $table.hasClass( 'collapsed' ) ) {
				collapseButton.text( expandText );
			}
			
			$table.data( 'collapsible', true );
		} );
	}
};

$( '#content' ).delegate( 'table.collapsible .collapsible-button .jslink', 'click', function( e ) {
	var $table = $( this ).closest( 'table.collapsible' );
	
	// Stop table sorting activating when clicking the link
	e.stopPropagation();
	
	if ( $table.hasClass( 'collapsed' ) ) {
		$table.removeClass( 'collapsed' ).addClass( 'expanded' );
		$( this ).text( collapseText );
	} else {
		$table.removeClass( 'expanded' ).addClass( 'collapsed' );
		$( this ).text( expandText );
	}
} );
window.mcw.makeCollapsible();

/** 
 * Fix edit summary prompt for undo
 *
 * Fixes the fact that the undo function combined with the "no edit summary prompter"
 * causes problems if leaving the edit summary unchanged.
 * Added by [[wikipedia:User:Deskana]], code by [[wikipedia:User:Tra]].
 * See https://bugzilla.wikimedia.org/show_bug.cgi?id=8912
 */
if ( document.location.search.indexOf( "undo=" ) !== -1 && document.getElementsByName( 'wpAutoSummary' )[0] ) {
	document.getElementsByName( 'wpAutoSummary' )[0].value='1';
}


window.mcw.animation = function() {
	/**
	 * Element animator
	 *
	 * Will cycle the active class on any child elements
	 * within an element with the animated class.
	 */
	if ( window.mcw.animate === undefined && $( '.animated' ).length ) {
		window.mcw.animate = setInterval( function() {
			$( '.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 );
	}
	
	
	/**
	 * Frame loader 
	 * 
	 * Loads a semi-colon (;) separated list of images
	 * to be animated by the element animator
	 * 
	 * Has special support for [[Template:Grid]]
	 */
	var $animate = $( '.animated' ), size = {};
	if ( $animate.length ) {
		$animate.each( function() {
			var imgs = $( this ).data( 'imgs' ), imgSize = $( this ).data( 'img-size' ),
				grid = $( this ).closest( '.grid' ), mod = $( this ).data( 'mod' );
			
			if ( !imgs ) {
				return true;
			}
			if ( grid.length ) {
				grid = true;
				imgSize = '32x32';
			} else {
				grid = false;
				if ( imgSize ) {
					imgSize = imgSize.split( 'x' );
					imgSize[0] = imgSize[0].replace( /[\D ]/, '' );
					imgSize[1] = imgSize[1].replace( /[\D ]/, '' );
					
					if ( imgSize[1] ) {
						imgSize[0] += 'x' + imgSize[1];
					}
					
					imgSize = imgSize[0];
				} else {
					imgSize = '';
				}
			}
			
			if ( size[imgSize] === undefined ) {
				size[imgSize] = [];
			}
			
			imgs = imgs.split( ';' );
			imgs.shift();
			$.each( imgs, function() {
				if ( !this.trim() ) {
					return true;
				}
				
				var parts, name;
				if ( grid ) {
					if ( this.indexOf( ':' ) > -1 ) {
						parts = $.map( this.split( /[:,]+/ ), $.trim );
						if ( parts[0].toLowerCase() === 'v' || parts[0].toLowerCase() === 'vanilla' ) {
							name = 'File:Grid ' + parts[1] + '.png';
						} else {
							name = 'File:Grid ' + parts[1] + ' (' + parts[0] + ').png';
						}
					} else {
						parts = $.map( this.split( ',' ), $.trim );
						if ( !mod ) {
							name = 'File:Grid ' + parts[0] + '.png';
						} else {
							name = 'File:Grid ' + parts[0] + ' (' + mod + ').png';
						}
					}
					
					if ( size[imgSize].indexOf( name ) < 0 ) {
						size[imgSize].push( name );
					}
				} else if ( size[imgSize].indexOf( 'File:' + this.trim() ) < 0 ) {
					size[imgSize].push( 'File:' + this.trim() );
				}
			} );
		} );
		
		var redirectPromise = [], urlPromise = [], redirects = {}, urls = {};
		$.each( size, function( size ) {
			var titles = this;
			if ( !titles ) {
				return true;
			}
			
			// Split titles up into blocks of 50, which is the API's title limit for standard users
			for ( var i = 0; i < titles.length; i += 50 ) { ( function() {
				var section = titles.slice( i, i + 50 ).join( '|' );
			
				redirectPromise.push(
					// Thanks to bug 23750 (https://bugzilla.wikimedia.org/show_bug.cgi?id=23750)
					// &redirects doesn't work properly with prop=imageinfo. Some of the images
					// will return without any imageinfo, even though they are valid.
					// So the redirects have to be resolved in a separate request...
					$.ajax( {
						type: 'POST',
						url: window.mcw.baseURL + 'api.php?action=query&format=json&redirects',
						data: { titles: section },
						timeout: 20000
					} ).done( function( data ) {
						if ( data.query.redirects ) {
							$.each( data.query.redirects, function() {
								redirects[this.to] = this.from;
								section = section.replace( this.from, this.to );
							} );
						}
						
						var thumburl = '', sizes = size.split( 'x' );
						if ( sizes[0] ) {
							thumburl = '&iiurlwidth=' + sizes[0];
							
							if ( sizes[1] ) {
								thumburl += '&iiurlheight=' + sizes[1];
							}
						}
						urlPromise.push(
							$.ajax( {
								type: 'POST',
								url: window.mcw.baseURL + 'api.php?action=query&format=json&prop=imageinfo&iiprop=url' + thumburl,
								data: { titles: section },
								timeout: 20000
							} ).done( function( data ) {
								$.each( data.query.pages, function( index ) {
									if ( index < 0 ) {
										return true;
									}
									if ( !this.imageinfo ) {
										console.error( 'Imageinfo is empty' );
										return true;
									}
									
									var url = this.imageinfo[0].thumburl || this.imageinfo[0].url;
									if ( redirects.hasOwnProperty( this.title ) ) {
										urls[redirects[this.title].replace( /File:(.*)/, '$1' ) + size] = url;
									} else {
										urls[this.title.replace( /File:(.*)/, '$1' ) + size] = url;
									}
								} );
							} ).fail( function( error ) {
								console.error( error );
							} )
						);
					} ).fail( function( error ) {
						console.error( error );
					} )
				);
			} )(); }
		} );
		
		$.when.apply( $, redirectPromise ).then( function() {
			$.when.apply( $, urlPromise ).then( function() {
				$animate.each( function() {
					var imgs = $( this ).data( 'imgs' ), imgSize = $( this ).data( 'img-size' ), html = '',
						grid = $( this ).closest( '.grid' ), mod = $( this ).data( 'mod' );
					
					if ( !imgs ) {
						return true;
					}
					if ( grid.length ) {
						grid = true;
						imgSize = '32x32';
					} else {
						grid = false;
						if ( imgSize ) {
							imgSize = imgSize.split( 'x' );
							imgSize[0] = imgSize[0].replace( /[\D ]/, '' );
							imgSize[1] = imgSize[1].replace( /[\D ]/, '' );
							
							if ( imgSize[1] ) {
								imgSize[0] += 'x' + imgSize[1];
							}
							
							imgSize = imgSize[0];
						} else {
							imgSize = '';
						}
					}
					
					imgs = imgs.split( ';' );
					imgs.shift();
					$.each( imgs, function() {
						if ( !this.trim() ) {
							if ( grid ) {
								html += '<span class="image">&nbsp;</span>';
							}
							return true;
						}
						
						var parts, name, link, url, num;
						if ( grid ) {
							if ( this.indexOf( ':' ) > -1 ) {
								parts = $.map( this.split( /[:,]+/ ), $.trim );
								if ( parts[0].toLowerCase() === 'v' || parts[0].toLowerCase() === 'vanilla' ) {
									name = link = parts[1];
									url = urls['Grid ' + parts[0] + '.png' + imgSize];
									num = parts[2];
								} else {
									name = parts[1] + ' (' + parts[0] + ')';
									link = 'Mods/' + parts[0] + '/' + parts[1];
									url = urls['Grid ' + name + '.png' + imgSize];
									num = parts[2];
								}
							} else {
								parts = $.map( this.split( ',' ), $.trim );
								if ( !mod ) {
									name = link = parts[0];
									url = urls['Grid ' + parts[0] + '.png' + imgSize];
									num = parts[1];
								} else {
									name = parts[0] + ' (' + mod + ')';
									link = 'Mods/' + mod + '/' + parts[0];
									url = urls['Grid ' + name + '.png' + imgSize];
									num = parts[1];
								}
							}
							
							html += '<span class="image">';
							if ( name ) {
								if ( url ) {
									html += '<a title="' + link + '" href="' + window.mcw.wikiURL + link.replace( / /g, '_' ) + '"><img width="32" height="32" src="' + url + '" alt="' + name + '"></a>';
									if ( num ) {
										html += '<span class="number"><a title="' + link + '" href="' + window.mcw.wikiURL + link.replace( / /g, '_' ) + '">' + num + '</a></span>';
									}
								} else {
									html += '<a class="new" title="File:Grid ' + name + '.png" href="' + window.mcw.baseURL + 'index.php?title=Special:Upload&wpDestFile=Grid_' + name.replace( / /g, '_' ) + '.png"></a>';
								}
							} else {
								html += '&nbsp;';
							}
							html += '</span>';
						} else {
							name = this.trim();
							html += '<span>';
							if ( urls[name + imgSize] ) {
								html += '<a href="' + window.mcw.wikiURL + 'File:' + name.replace( / /g, '_' ) + '"><img src="' + urls[name + imgSize] + '" alt="' + name + '"></a>';
							} else {
								html += '<a class="new" title="File:' + name + '" href="' + window.mcw.baseURL + 'index.php?title=Special:Upload&wpDestFile=' + name.replace( / /g, '_' ) + '">File:' + name + '</a>';
							}
							html += '</span>';
						}
					} );
					
					$( this ).append( html ).data( 'imgs', null );
				} );
			} );
		} );
	}
};
window.mcw.animation();

/**
 * Pause grid GUI templates (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.
 */
$( '#content' ).delegate( '.grid-Crafting_Table, .grid-furnace, .grid-Brewing_Stand', {
	'mouseenter': function() { 
		$( this ).find( '.animated' ).removeClass( 'animated' ).addClass( 'paused' );
	},
	'mouseleave': function() {
		$( this ).find( '.paused' ).removeClass( 'paused' ).addClass( 'animated' );
	}
} );


/**
 * Add fake last-child class in navboxes for IE8
 */
if ( $.client.profile().name === 'msie' && $.client.profile().versionBase === '8' ) {
	$( '.navbox-list li:last' ).addClass( 'last-child' );
}

/**
 * Back to Top Button
 */
addOnloadHook(function() {
        var elems = document.getElementsByClassName('editsection');
        for (i = 0; i < elems.length; i++) {
                var span = document.createElement('span');
                var link = document.createElement('a');
                link.href = '#top';
                link.appendChild(document.createTextNode('back to top'));
                span.appendChild(document.createTextNode('['));
                span.appendChild(link);
                span.appendChild(document.createTextNode('] '));
                elems[i].insertBefore(span, elems[i].firstChild);
        }
});