MediaWiki:Common.js

From Uncyclopedia, the content-free encyclopedia
Jump to navigation Jump to search

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

  • Internet Explorer: hold down the Ctrl key and click the Refresh or Reload button, or press Ctrl+F5.
  • Firefox: hold down the Shift key while clicking Reload; alternatively press Ctrl+F5 or Ctrl-Shift-R.
  • Opera, Konqueror and Safari users can just click the Reload button.
  • Chrome: press Ctrl+F5 or Shift+F5
/**<pre><nowiki>
 *
 * Some tips when editing this page...
 *
 ** Make sure that your code has been tested in the latest version of Firefox AND Internet Explorer! (Nobody cares about older versions)
 ** No compressed JS. Ever. As of MediaWiki 1.19+ we have [[mw:ResourceLoader]] to compress JS and make it fugly.
 ** Make sure that your code follows some coding conventions, preferrably MediaWiki's (see http://www.mediawiki.org/wiki/Manual:Coding_conventions)
 *
 * Your friendly neighborhood MediaWiki developer,
 * --Jack Phoenix, 26 July 2009
 * <jack@countervandalism.net>
 *
 * Tools: [http://uncyclopedia.wikia.com/index.php?title=-&action=raw&smaxage=0&gen=js reload cache]
 *
 * More notes: It is not enough to just define a function in this file; you must also write
 * a "hook" so that the function ever gets called.  The usual notion is to define it as the
 * handler for the onload event of the article's BODY.  MediaWiki used to provide
 *   addOnloadHook(yourFunctionName);
 * This has been withdrawn.  It only ever took effect after all content on the page loaded, 
 * including images, rendering it problematic for hiding an image.  MediaWiki now recommends
 * use of a jQuery function that fires the moment the DOM is ready for modification, even
 * though the page might not have been rendered:
 *   jQuery(document).ready(yourFunctionName);
 *  or    $(document).ready(yourFunctionName);
 * Yahoo and Google have equivalents too, but the jQuery one is widely used in this file,
 * Wikia has already loaded it, and it is open-source.  This makes it preferable to using
 * your favorite proprietary library, and loading into everyone's cache multiple ways of
 * doing the same thing.  --Spike Jun'14, revised May'19
 */

/* Non-namespace logos */
//===================================================
// faux-namespace fixes
//	(including hack for browsers with NO CSS3 support [IE6, etc])
//	- Bizzeebeever, 2011 (if this breaks shit, you know who to ban)
//===================================================
//add faux namespaces to {namespaces} as follows:
//	"namespaceName" : { tabText : "Tab text goes here", className : "Logo CSS class name" }
//		//tabText: [optional] default is namespaceName
//		//className [optional] will be given prefix "ns-". default is "ns-[namespaceName]"
//make sure if you are adding more than one to use a comma after each line except the last.
//<body> element for specified namespaces will be given the "ns-[className]" class.
//create your new stylesheet selector + rule in MediaWiki:Common.css accordingly
//	i.e. "body.ns-why #p-logo > a { background-image:url( someimage.png ) };")

$(document).ready(function() {
	var namespaces = {
		$className: function( str ) {
			if ( str in this ) {
				return ' ns-' + ( this[str].className || str ).replace( /[\W]*/g, '' ).toLowerCase();
			}
		},
		$tabText: function ( str ) {
			if ( str in this ) {
				return this[str].tabText || str;
			}
		},
		//===add faux-namespaces below this line===
		'Un-Bestiary': { tabText: 'Bestiary' },
		'Uncycloversity': { tabText: 'Resource' }
	};
	var namespace = mw.config.get("wgPageName").match( /^(Talk:)?[-\w\?]+/ )[0].replace( 'Talk:', '' );
	// grab namespace, stripping off "Talk:" if this is a talk page
	if ( !namespace ) {
		return;
	}
	// if empty namespace, probably an error
	if ( namespace in namespaces ) {
		// if a namespace hack is defined above...
		try {
			document.body.className += namespaces.$className( namespace );
			// apply custom style
			document.getElementById( 'ca-nstab-main' ).getElementsByTagName("a")[0].innerHTML = namespaces.$tabText( namespace );
			// Change tab text
		} catch( e ) { return; }
	}
} );
// end faux-namespace fixes

//Function to remove title
function noTitle() {
	if( $( '#notitle' )[0] ) {
		$( '#firstHeading' ).hide();
	}
}
$(document).ready( noTitle );
//Custom per-page logos

function logotipo() {
	if( document.getElementById( 'logotipo' ) ) {
		if ( document.getElementById( 'logotipo' ).getElementsByTagName("a")[0].firstChild.src !== null ) {
 			var logoURL = document.getElementById( 'logotipo' ).getElementsByTagName("a")[0].firstChild.src;
			document.getElementById( 'p-logo' ).innerHTML= '<a style="background-image: url('
			+ logoURL + ')" href="/wiki/Main_Page" title="Visit the main page"/>';
		}
	}
}
$(document).ready(logotipo);

/** Dismiss notice remover
 * (only removes if you have made a custom sitenotice designed to use its own close button)
 */
function removeSitenoticeDismiss() {
	snh = document.getElementById( 'siteNoticehide' );
	if( !snh ) {
		return;
	}
	snh = snh.parentNode;
	snh.href = 'javascript:dismissNotice();';
	noticetr = document.getElementById( 'mw-dismissable-notice' );
	if( !noticetr ) {
		snh.parentNode.removeChild( snh );
		return;
	}
	noticetr = noticetr.firstChild.firstChild;
	noticetr.removeChild( noticetr.lastChild );
}
$(document).ready(removeSitenoticeDismiss);

/** Username replace function ([[template:USERNAME]]) *******************************
 * Inserts user name into <span class="insertusername"></span>
 * Originally by [[wikia:User:Splarka|Splarka]]
 * New version by [[User:Spang|Spang]]
 */
function UserNameReplace() {
	if( typeof( disableUsernameReplace ) != 'undefined' && disableUsernameReplace
	|| mw.config.get('wgUserName') === null ) { return; }
	$("SPAN.insertusername").html(mw.config.get('wgUserName'));
}
$( UserNameReplace );

/** Title rewrite ********************************************************
 * Rewrites the page's title
 * [[Template:Title]] puts an invisible DIV in the article with the desired new title,
 *   always accompanied by another DIV with the desired alignment for the title.
 *   Here we copy their text to the page's H1 element.
 *   We also change "document.title" (the text on the browser tab and the window's
 *    top bar) unless the new text seems to contain HTML, which would display raw.
 * User can define SKIP_TITLE_REWRITE == 1 in personal JavaScript to inhibit this.
 *
 * By [[User:Sikon|Sikon]]
 * Recoded with jQuery by Spike, Nov'15; bugs fixed Aug'16
 */
function rewriteTitle() {
	if( typeof( SKIP_TITLE_REWRITE ) !== 'undefined' && SKIP_TITLE_REWRITE ) {
		return;
	}
 
	var $titleMeta = $("#title-meta"); 
	if( $titleMeta.length === 0 ) { 
		return;
	}
	
	var newPageTitle = $titleMeta.html(),
		newDocumentTitle = $titleMeta.text().replace(/<[^>]+>/ig, ""),
		titleAlign = $("#title-align").text();
	$("#firstHeading").html(newPageTitle).css("text-align", titleAlign);
	document.title = newDocumentTitle;
}
rewriteTitle();

/** Dynamic navigation bars ************************************************
 * Allows navigation templates to expand and collapse their content to save space
 * Documentation on Wikipedia at Wikipedia:NavFrame
 */
 
var collapseCaption = 'hide';
var expandCaption = 'show';

// Set up the words in your language
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} event Event object
 */
function toggleNavigationBar( indexNavigationBar, event ) {
	var navToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
	var navFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
	var navChild;

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

	// If shown now
	if ( navToggle.firstChild.data === navigationBarHide ) {
		for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
			if ( $( navChild ).hasClass( '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( 'NavContent' ) ) {
				navChild.style.display = 'block';
			}
		}
		navToggle.firstChild.data = navigationBarHide;
	}

	event.preventDefault();
}

/**
 * Adds show/hide-button to navigation bars.
 *
 * @param {jQuery} $content
 */
function createNavigationBarToggleButton( $content ) {
	var i, j, navChild, navToggle, navToggleText, isCollapsed,
		indexNavigationBar = 0;
	// Iterate over all < div >-elements
	var $divs = $content.find( 'div.NavFrame:not(.mw-collapsible)' );
	$divs.each( function ( i, navFrame ) {
		indexNavigationBar++;
		navToggle = document.createElement( 'a' );
		navToggle.className = 'NavToggle';
		navToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
		navToggle.setAttribute( 'href', '#' );
		$( navToggle ).on( 'click', $.proxy( toggleNavigationBar, null, indexNavigationBar ) );

		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 ( 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 ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
				if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
					navChild.style.display = 'none';
				}
			}
		}
		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 ( 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 );
	} );
}

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

/** Another collapsible whatnits implementation - for the sidebar mostly, but can be used with whatever
	I'd write some documentation or something, but I can't be arsed. -Lyrithya

********************************************* star */
/*
jQuery( document ).ready( function() {
	$( '.collapsed > *' ).next().css( 'display', 'none' );
	$( '.expanded > *' ).click( function() {
		$( this ).next().toggle();
		$( this ).parent().toggleClass( 'expanded' );
		$( this ).parent().toggleClass( 'collapsed' );
	});
	$( '.collapsed > *' ).click( function() {
		$( this ).next().toggle();
		$( this ).parent().toggleClass( 'collapsed' );
		$( this ).parent().toggleClass( 'expanded' );
	});
});*/

/** This snippet from wikipedia:MediaWiki:Common.js makes autocollapsing work
 *	-DWWH
 */
function mwCollapsibleSetup( $collapsibleContent ) {
	var $element,
		$toggle,
		autoCollapseThreshold = 2;
	$.each( $collapsibleContent, function ( index, element ) {
		$element = $( element );
		if ( $element.hasClass( 'collapsible' ) ) {
			$element.find( 'tr:first > th:first' ).prepend( $element.find( 'tr:first > * > .mw-collapsible-toggle' ) );
		}
		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();
			}
		}
		// because of colored backgrounds, style the link in the text color
		// to ensure accessible contrast
		$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 );

/** Archive edit tab disabling *************************************
 * Disables the edit tab on old forum topic pages to stop noobs bumping old topics.
 * Page can still be edited by going via the edit tab on the history etc, or by
 * typing the edit address manually.
 * By [[User:Spang|Spang]]
 */
function disableOldForumEdit() {
	if( typeof( enableOldForumEdit ) != 'undefined' && enableOldForumEdit ) {
		return;
	}
	if( !$( '#ca-edit' )[0] || !$( '#old-forum-warning' )[0] ) {
		return;
	}
	var $editLink = $( '#ca-edit > a' )[0];
	$editLink.removeAttribute( 'href', 0 );
	$editLink.style.color = 'gray';
	$editLink.innerHTML = 'No Editing';
}
$( disableOldForumEdit );

/** Add section tab disabling *************************************
 * Disables the add section tab on any page you like, mainly useful for your userpage
 * (depending on how you have your userpage set up)
 * To use it, include any HTML element with an ID of disableAddSection, such as <div id="disableAddSection"></div>
 * By Olipro
 */
function disableAddSection() {
  if ($("#disableAddSection").length > 0) { $("#ca-addsection").remove(); };
}

$( disableAddSection );

/** Remove example text **************************************************
 * Automatically removes any example text left on the page upon saving.
 * By [[User:Spang]]
 */
function stripExamples() {
	try {
		var tb = document.forms[0].wpTextbox1;
		var tbh = tb.scrollTop;
		tb.value = tb.value.replace(/(?:\'\'\'Bold text\'\'\'|\'\'Italic text\'\'|\[\[Link title\]\]|\[http:\/\/www\.example\.com link title\]|\n== Headline text ==\n|\[\[Image:Example\.jpg\]\]|\[\[File:Example\.jpg\]\]|<math>Insert formula here<\/math>|<nowiki>Insert non-formatted text here<\/nowiki>|<code><\/code>|\[\[Media:Example\.ogg\]\]|\n(?=\n\n\n))/g,'');
		tb.scrollTop = tbh;
		return true;
	} catch( e ) {
		return true;
	}
}
$(
	function() {
		if ( ( mw.config.get('wgAction') == 'edit'
		|| mw.config.get('wgAction') == 'submit' )
		&& mw.config.get('wgCanonicalSpecialPageName') == false ) {
			document.forms[0].wpSave.setAttribute( 'onclick', 'return stripExamples()' );
		}
	}
)

/** JavaScript for the UnNews namespace ***********************************
 */
function unNewsFrontPageJS() {
/* For any article: if an Audio is available, move the indication inside the masthead. */
  if ($("TABLE.UnNewsAudioAvailable").length > 0) {
    $("TD.masthead_right").replaceWith($("TABLE.UnNewsAudioAvailable"));
    };
/* For the Front Page: Remove all the p-cactions, such as View source and History */
  if (mw.config.get('wgPageName') == "UnNews:Main_Page") {
    $("DIV#p-cactions").remove();
    };
  };

if (mw.config.get('wgNamespaceNumber') == 102) { $( unNewsFrontPageJS ); };

/** Sortable table fixes **************************************************
 * Fixes some problems the default sortable table script has.
 * Slightly modifies the ts_resortTable function found in wikibits.js
 */
function ts_resortTable( lnk ) {
	var span = lnk.getElementsByTagName( 'span' )[0];
	var td = lnk.parentNode;
	var tr = td.parentNode;
	var column = td.cellIndex;
	var table = tr.parentNode;

	while( table && !( table.tagName && table.tagName.toLowerCase() == 'table' ) ) {
		table = table.parentNode;
	}

	if( !table ) {
		return;
	}

	if( table.rows.length <= 1 ) {
		return;
	}

	if( ts_number_transform_table == null ) {
		ts_initTransformTable();
	}

	var rowStart = table.tHead && table.tHead.rows.length > 0 ? 0 : 1;
	var itm = '';
	for( var i = rowStart; i < table.rows.length; i++ ) {
		if( table.rows[i].cells.length > column ) {
			itm = ts_getInnerText( table.rows[i].cells[column] );
			itm = itm.replace(/^[\s\xa0]+/,"").replace(/[\s\xa0]+$/,"");
			if( itm != '' ) {
				break;
			}
		}
	}
	var sortfn = ts_sort_generic;
	var preprocessor = ts_toLowerCase;
	if( /^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/.test( itm ) ) {
		preprocessor = ts_dateToSortKey;
	} else if( /^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/.test( itm ) ) {
		preprocessor = ts_dateToSortKey;
	} else if( /^\d\d[\/.-]\d\d[\/.-]\d\d$/.test( itm ) ) {
		preprocessor = ts_dateToSortKey;
	} else if( /(^[\u00a3$\u20ac\u00a4\u00a5]|\u00a2$)/.test( itm ) ) {
		preprocessor = ts_currencyToSortKey;
	} else if( ts_number_regex.test( itm ) || /sm=n$/.test( itm ) ) {
		preprocessor = ts_parseFloat;
	}
	var reverse = span.getAttribute( 'sortdir' ) == 'down';
	var newRows = new Array;
	var staticRows = new Array;
	for( var j = rowStart; j < table.rows.length; j++ ) {
		var row = table.rows[j];
		if( ( ' ' + row.className + ' ' ).indexOf( ' unsortable ' ) < 0 ) {
			var keyText = ts_getInnerText( row.cells[column] );
			var oldIndex = reverse ? -j : j;
			var preprocessed = preprocessor( keyText );
			newRows[newRows.length] = new Array( row, preprocessed, oldIndex );
		} else {
			staticRows[staticRows.length] = new Array( row, false, j-rowStart );
		}
	}
	newRows.sort( sortfn );
	var arrowHTML;
	if( reverse ) {
		arrowHTML = "<img src=\"" + ts_image_path + ts_image_down + "\" alt=\"&darr;\"/>";
		newRows.reverse();
		span.setAttribute( 'sortdir', 'up' );
	} else {
		arrowHTML = "<img src=\"" + ts_image_path + ts_image_up + "\" alt=\"&uarr;\"/>";
		span.setAttribute( 'sortdir', 'down' );
	}
	for( var i = 0; i < staticRows.length; i++ ) {
		var row = staticRows[i];
		newRows.splice( row[2], 0, row );
	}
	for( var i = 0; i < newRows.length; i++ ) {
		if( ( ' ' + newRows[i][0].className + ' ' ).indexOf( ' sortbottom ' ) == -1 ) {
			table.tBodies[0].appendChild( newRows[i][0] )
		}
	}
	for( var i = 0; i < newRows.length; i++ ) {
		if( ( ' ' + newRows[i][0].className + ' ' ).indexOf( ' sortbottom ' ) != -1 ) {
			table.tBodies[0].appendChild( newRows[i][0] )
		}
	}
	var spans = getElementsByClassName( tr, 'span', 'sortarrow' );
	for( var i = 0; i < spans.length; i++ ) {
		spans[i].innerHTML = "<img src=\"" + ts_image_path + ts_image_none
		+ "\" alt=\"&darr;\"/>";
	}
	span.innerHTML = arrowHTML;
	if( ts_alternate_row_colors ) {
		ts_alternate( table );
	}
}

/** IP template for ban patrol ******
 * Others can be added for other or all pages.
 */ /*
if( mwCustomEditButtons && wgPageName == 'Uncyclopedia:Ban_Patrol' ) {
	mwCustomEditButtons[mwCustomEditButtons.length] = {
		'imageFile': 'http://images1.wikia.com/uncyclopedia/images/d/d7/IP_button.png',
		'speedTip': 'IP template',
		'tagOpen': '{' + '{' + 'IP|',
		'tagClose': '}' + '}',
		'sampleText': '127.0.0.1'
	};
} */

/** COMMENTED-OUT FORMER CODE **************************
 * Nachteule told me to add this on my talkpage - Dr. S
 * Both of these are deprecated and were removed in MW 1.20 --SPIKE
 * window.wgMWSuggestTemplate = "http://uncyclopedia.wikia.com/api.php?action=opensearch\x26search={searchTerms}\x26namespace={namespaces}\x26suggest";
 * window.wgSearchNamespaces = [0];
 */

//Pull "logothing" logos and stamps out of content area so they're positioned correctly
if(document.getElementsByClassName("logothing")[0]) {
	var fs = document.getElementsByClassName("logothing");
	for (var i = 0; i < fs.length; i++) {
		document.getElementById("content").parentNode.insertBefore(fs[i],
		document.getElementById("content"));
	}
}