Diferencia entre revisiones de «MediaWiki:Common.js»

De WikiMinecraft
Saltar a: navegación, buscar
Línea 1: Línea 1:
/* Cualquier código JavaScript escrito aquí se cargará para todos los usuarios en cada carga de página */
+
( function() {
/* Any JavaScript here will be loaded for all users on every page load. */
+
'use strict';
  
// add &__vanilla=1 to URL to disable all scripts except gadgets (as enabled in [[Special:Preferences]])
+
/**
if (mw.util.getParamValue('__vanilla'))
+
* Instead of cluttering up the global scope with
throw void 0; // return is invalid here. oh well.
+
* variables, they should instead be set as a
+
* property of this global variable
/*
+
*
== [[WT:PREFS]] v2.0 ==
+
* E.g: Instead of
*/
+
*  myVar = 'blah';
 +
* use
 +
*   mcw.myVar = 'blah';
 +
*/
 +
window.mcw = {};
  
try { (function () {
 
"use strict";
 
  
var prefs;
+
/* Legacy support */
try {
+
mcw.baseURL = '/';
prefs = window.localStorage.getItem('AGprefs');
+
mcw.wikiURL = '/';
} catch (e) {
 
prefs = jQuery.cookie('AGprefs');
 
}
 
prefs = prefs && (window.JSON ? window.JSON.parse(prefs) : eval('(' + prefs + ')'));
 
  
if (wgUserGroups.indexOf('autoconfirmed') !== -1)
 
return;
 
  
if (wgUserGroups.indexOf('user') === -1)
+
/* Variables for interface text used throughout the script, for ease of translating */
if ((wgAction === 'view') && (wgPageName === 'Wiktionary:Preferences/V2')) {
+
mcw.i18n = {
mw.loader.load('ext.gadget.AGprefs');
+
// Collapsible tables and page loader
}
+
hideText: 'hide',
 
+
showText: 'show',
if (!prefs)
+
return;
+
// Page loader
 
+
loadErrorTitle: 'An error occurred loading the content',
mw.loader.state('the_pope_is_an_atheist_woman_alien', 'missing');
+
for (var key in prefs.modules) {
+
// File upload
if (prefs.modules[key]) {
+
defaultLicense: 'License'
mw.loader.load(key);
+
};
} else {
 
// unavoidable race condition. to prevent it, every enabled-by-default gadget should have "site" as a dependency
 
if (mw.loader.getState(key) !== 'ready') {
 
mw.loader.moduleRegistry[key].dependencies.push('the_pope_is_an_atheist_woman_alien');
 
mw.loader.state(key, 'missing');
 
} else {
 
// XXX
 
mw.log.warn(key + ": the milk has been spilt.");
 
}
 
}
 
}
 
 
 
for (var key in prefs.sheets) {
 
importStylesheet('MediaWiki:Gadget-' + key);
 
}
 
  
for (var key in prefs.scripts) {
+
/* Add extra buttons to the classic toolbar */
importScript('MediaWiki:Gadget-' + key);
+
if ( mw.user.options.get( 'showtoolbar' ) && !mw.user.options.get( 'usebetatoolbar' ) ) {
 +
importScript( 'MediaWiki:Toolbar.js' );
 
}
 
}
  
if (wgUserGroups.indexOf('user') !== -1) {
 
var changes = [];
 
for (var key in prefs.gadgets)
 
changes.push('gadget-' + key + '=' + (prefs.gadgets[key] ? '1' : '0'));
 
 
(new mw.Api()).postWithToken('options', {
 
action: 'options',
 
change: changes.join('|')
 
}).fail(function () {
 
jQuery.cookie('AGprefs', null);
 
try { window.localStorage.removeItem('AGprefs'); } catch (e) { /* */ }
 
mw.util.jsMessage(
 
'<b>Your <a href="/wiki/Wiktionary:Preferences/V2">per-browser preferences</a> have been migrated</b><br/><br/>' +
 
'From now on, you should use your <a href="/wiki/Special:Preferenced">user preferences page</a>. ' +
 
'Preferences will no longer apply after you log out.'
 
);
 
});
 
}
 
  
})(); } catch (e) { mw.log.warn(e); }
+
/* Wait for DOMContentLoaded */
 
+
$( function() {
/*</pre>
 
===importScript===
 
<pre>*/
 
  
 
/**
 
/**
  * importScript inserts a javascript page either
+
  * Collapsible tables
*    from Wiktionary: importScript('User:Connel MacKensie/yetanother.js');
 
*    from another Wikimedia wiki: importScript('User:Lupin/insane.js','en.wikipedia.org');
 
 
  *
 
  *
  *   by specifying the third argument, an oldid can be passed to ensure that updates to the script are not included.
+
  * Based on http://www.mediawiki.org/wiki/Manual:Collapsible_tables#Common.js_script_.28before_1.18.29
*    by specifying the fourth argument, a specific version of JavaScript can be declared.
+
*/
*
+
mcw.makeCollapsible = function( $content ) {
*    based on [[w:MediaWiki:Common.js]] 2007-11-29
+
if ( $content === undefined ) {
**/
+
$content = $( 'table.collapsible' );
function importScript(page, wiki, oldid, jsver) {
+
} else {
if (wiki || oldid || jsver) {
+
$content = $content.find( 'table.collapsible' );
mw.log.warn("importScript called with more than one argument. This may be unreliable.");
+
}
 +
if ( !$content.length ) {
 +
return false;
 
}
 
}
 +
 +
var buttonText = ' <span class="collapsible-button">[<span class="jslink">' + mcw.i18n.hideText + '</span>]</span> ';
 +
 +
$content.each( function() {
 +
var $table = $( this ), $header, $collapseButton, firstWidth, secondWidth;
 +
 +
// This table is already collapsible
 +
if ( $table.data( 'collapsible' ) ) {
 +
return true;
 +
}
 +
 +
// Use the collapse-button if specified otherwise the first header cell of the first row
 +
$header = $table.find( 'tr:first .collapse-button' );
 +
if ( !$header.length ) {
 +
$header = $table.find( 'tr:first > th:first' );
 +
}
 +
 +
// No header or the table body is empty
 +
if ( !$header.length || !$table.find( 'tr:not(tr:first)' ).text().replace( /\n/g, '' ).length ) {
 +
return true;
 +
}
 +
 +
// For the button to float properly, it has to be /before/ the cell text
 +
if ( $table.hasClass( 'collapse-button-none' ) ) {
 +
$header.append( buttonText );
 +
} else {
 +
$header.prepend( buttonText );
 +
}
 +
 +
// Find max button size, and set its min-width to it
 +
$collapseButton = $table.find( '.collapsible-button' );
 +
firstWidth = $collapseButton.width();
 +
$collapseButton.find( '> .jslink' ).text( mcw.i18n.showText );
 +
secondWidth = $collapseButton.width();
 +
 +
if ( firstWidth != secondWidth ) {
 +
if ( firstWidth < secondWidth ) {
 +
$collapseButton.css( 'min-width', secondWidth );
 +
} else {
 +
$collapseButton.css( 'min-width', firstWidth );
 +
}
 +
}
 +
 +
// Set the text back to hide if it's not collapsed to begin with
 +
if ( !$table.hasClass( 'collapsed' ) ) {
 +
$collapseButton.find( '> .jslink' ).text( mcw.i18n.hideText );
 +
}
 +
 +
$table.data( 'collapsible', true );
 +
} );
 +
};
  
// Default to local
+
$( '#mw-content-text' ).on( 'click', 'table.collapsible .collapsible-button .jslink', function( e ) {
if (!wiki) {
+
var $table = $( this ).closest( 'table.collapsible' );
wiki=wgScript;
+
 +
// Stop table sorting activating when clicking the link
 +
e.stopPropagation();
 +
 +
if ( $table.hasClass( 'collapsed' ) ) {
 +
$table.removeClass( 'collapsed' ).addClass( 'expanded' );
 +
$( this ).text( mcw.i18n.hideText );
 
} else {
 
} else {
wiki='//'+escape(wiki)+'/w/index.php';
+
$table.removeClass( 'expanded' ).addClass( 'collapsed' );
 +
$( this ).text( mcw.i18n.showText );
 
}
 
}
 +
} );
 +
mcw.makeCollapsible();
  
var url = wiki + '?title='
 
+ mw.util.wikiUrlencode(page)
 
+ (oldid ? '&oldid=' + encodeURIComponent(oldid) : '')
 
+ '&action=raw&ctype=text/javascript';
 
  
//Only include scripts once
+
/**
if (loadedScripts[url]) {
+
* Fix edit summary prompt for undo
return false;
+
*
}
+
* Fixes the fact that the undo function combined with the "no edit summary prompter"
loadedScripts[url] = true;
+
* causes problems if leaving the edit summary unchanged.
 
+
* Added by [[wikipedia:User:Deskana]], code by [[wikipedia:User:Tra]].
var scriptElem = document.createElement("script");
+
* See https://bugzilla.wikimedia.org/show_bug.cgi?id=8912
scriptElem.setAttribute("src",url);
+
*/
scriptElem.setAttribute("type", jsver ? "application/javascript;version=" + jsver : "text/javascript");
+
if ( document.location.search.indexOf( "undo=" ) !== -1 && document.getElementsByName( 'wpAutoSummary' )[0] ) {
document.getElementsByTagName("head")[0].appendChild(scriptElem);
+
document.getElementsByName( 'wpAutoSummary' )[0].value='1';
return true;
 
 
}
 
}
  
/*</pre>
 
=== DOM creation ===
 
<pre>*/
 
 
/**
 
/**
  * Create a new DOM node for the current document.
+
  * Element animator
*    Basic usage:  var mySpan = newNode('span', "Hello World!")
 
*    Supports attributes and event handlers*: var mySpan = newNode('span', {style:"color: red", focus: function(){alert(this)}, id:"hello"}, "World, Hello!")
 
*    Also allows nesting to create trees: var myPar = newNode('p', newNode('b',{style:"color: blue"},"Hello"), mySpan)
 
 
  *
 
  *
  * *event handlers, there are some issues with IE6 not registering event handlers on some nodes that are not yet attached to the DOM,
+
  * Will cycle the active class on any child elements
  * it may be safer to add event handlers later manually.
+
  * within an element with the animated class.
**/
+
*/
function newNode(tagname){
+
mcw.animation = function() {
var node = document.createElement(tagname);
+
if ( mcw.animate === undefined && $( '.animated' ).length ) {
 
+
mcw.animate = setInterval( function() {
for (var i = 1; i < arguments.length; ++i){
+
$( '.animated' ).each( function() {
if (typeof arguments[i] == 'string') { // text
+
var $current = $( this ).children( '.active' ), $next = $current.nextAll( ':not(.skip):first' );
node.appendChild(document.createTextNode(arguments[i]));
+
if ( !$next.length ) {
} else if (typeof arguments[i] == 'object') {
+
$next = $( this ).children( ':not(.skip):first' );
if (arguments[i].nodeName) { //If it is a DOM Node
 
node.appendChild(arguments[i]);
 
} else { // Attributes (hopefully)
 
for (var j in arguments[i]){
 
if (j == 'class') { //Classname different because...
 
node.className = arguments[i][j];
 
} else if (j == 'style') { //Style is special
 
node.style.cssText = arguments[i][j];
 
} else if (typeof arguments[i][j] == 'function') { //Basic event handlers
 
newNode.addEventHandler(node, j, arguments[i][j]);
 
} else {
 
node.setAttribute(j, arguments[i][j]); //Normal attributes
 
}
 
 
}
 
}
}
+
$current.removeClass( 'active' );
}
+
$next.addClass( 'active' );
 +
} );
 +
}, 2000 );
 
}
 
}
 
node.addEventHandler = function(eventName, handler) {
 
newNode.addEventHandler(this, eventName, handler);
 
};
 
 
return node;
 
}
 
 
newNode.addEventHandler = function(node, eventName, handler)
 
{
 
try{ node.addEventListener(eventName,handler,false); //W3C
 
}catch(e){try{ node.attachEvent('on'+eventName,handler,"Language"); //MSIE
 
}catch(e){ node['on'+eventName]=handler; }} //Legacy
 
 
};
 
};
/*</pre>
+
mcw.animation();
  
=== CSS ===
 
<pre>*/
 
  
 
/**
 
/**
  * Cross browser CSS - yurk
+
  * Pause grid GUI templates (e.g. [[Template:Grid/Crafting Table]]) on mouseover
  * @deprecated: Use mw.util.addCSS() instead
+
*
 +
  * This is so people have a chance to look at each image on the cell
 +
* and click on pages they want to view.
 
  */
 
  */
var p_styleSheet=false;
+
$( '#mw-content-text' ).on( {
+
'mouseenter': function() {  
window.addCSSRule = function (selector,cssText) {
+
$( this ).find( '.animated' ).removeClass( 'animated' ).addClass( 'paused' );
mw.log.warn("deprecated function addCSSRule called; use mw.util.addCSS(css) instead");
+
},
mw.util.addCSS( selector+'{' + cssText + '}' );
+
'mouseleave': function() {
}
+
$( this ).find( '.paused' ).removeClass( 'paused' ).addClass( 'animated' );
 
 
/*</pre>
 
 
 
===Cookies===
 
<pre>
 
*/
 
 
 
/* @deprecated: Use $.cookie instead */
 
function setCookie(cookieName, cookieValue) {
 
mw.log.warn("deprecated function setCookie called; use jQuery.cookie instead");
 
var today = new Date();
 
var expire = new Date();
 
var nDays = 30;
 
expire.setTime( today.getTime() + (3600000 * 24 * nDays) );
 
document.cookie = cookieName + "=" + escape(cookieValue)
 
+ ";path=/"
 
+ ";expires="+expire.toGMTString();
 
}
 
 
 
function getCookie(cookieName) {
 
  mw.log.warn("deprecated function getCookie called; use jQuery.cookie instead");
 
  var start = document.cookie.indexOf( cookieName + "=" );
 
  if ( start == -1 ) return "";
 
  var len = start + cookieName.length + 1;
 
  if ( ( !start ) &&
 
( cookieName != document.cookie.substring( 0, cookieName.length ) ) )
 
  {
 
return "";
 
  }
 
  var end = document.cookie.indexOf( ";", len );
 
  if ( end == -1 ) end = document.cookie.length;
 
  return unescape( document.cookie.substring( len, end ) );
 
}
 
 
 
function deleteCookie(cookieName) {
 
mw.log.warn("deprecated function deleteCookie called; use jQuery.cookie instead");
 
if (getCookie(cookieName)) {
 
document.cookie = cookieName + "=" + ";path=/" + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
 
 
}
 
}
}
+
}, '.grid-generic, .grid-Crafting_Table, .grid-Furnace, .grid-Brewing_Stand' );
  
/*</pre>
 
  
==Wiktionary Customisation==
+
/**
<pre>*/
+
* Add fake last-child class in navboxes for IE8
 
+
*/
if ( document.getElementById('footer') ) {
+
if ( $.client.profile().name === 'msie' && $.client.profile().versionBase === '8' ) {
jQuery.ready()
+
$( '.navbox-list li:last' ).addClass( 'last-child' );
 
}
 
}
  
//initialize the storage for script options. Gadgets that set script
 
//options should also include this line as they are loaded before us.
 
if ( typeof WiktScriptPrefs == 'undefined') {
 
WiktScriptPrefs = {};
 
}
 
  
/*</pre>
+
/**
===[[MediaWiki:Youhavenewmessages]] to display differently for non-newbies with JS than for others===
+
* Page loader
<pre>*/
+
*
/* Suspected unresponsive page culprit: see the GP (Nov. 2010, "Blocking script execution on each page") */
+
* Allows a page to be downloaded and shown within another page.
/* if (wgUserGroups && wgUserGroups.join("").indexOf("autoconfirmed") > -1)
+
* Use with [[Template:LoadPage]]
{
+
*/
addCSSRule(".msgfornewbies", "display: none");
+
var $loadPage = $( '.load-page' );
}else{
+
if ( $loadPage.length ) {
addCSSRule(".msgfornonnewbies", "display: none");
+
// We need the spinner to show loading is happening, but we don't want
} */
+
// to have a delay while the module downloads, so we'll load this now,
/*</pre>
+
// regardless of if something is clicked
 
+
mw.loader.load( 'jquery.spinner' );
===[[WT:FEED]]===
+
<pre>*/
+
var $buttonText = $( '<span/>' )
if ( !wgUserName ) {
+
.addClass( 'load-page-button' )
importScript('User:Conrad.Irwin/feedback.js');
+
.css( {
 +
display: 'inline-block',
 +
marginLeft: '0.8em',
 +
fontWeight: 'normal'
 +
} )
 +
.html( '[<span class="jslink">' + mcw.i18n.hideText + '</span>]' );
 +
$loadPage.find( '.mw-headline:first' ).each( function() {
 +
var $button, firstWidth, secondWidth;
 +
 +
// Add the button
 +
$( this ).append( $buttonText.clone() );
 +
 +
// Find max button size, and set its min-width to it
 +
$button = $( this ).find( '> .load-page-button' );
 +
firstWidth = $button.width();
 +
$button.find( '> .jslink' ).text( mcw.i18n.showText );
 +
secondWidth = $button.width();
 +
 +
if ( firstWidth != secondWidth ) {
 +
if ( firstWidth < secondWidth ) {
 +
$button.css( 'min-width', secondWidth );
 +
} else {
 +
$button.css( 'min-width', firstWidth );
 +
}
 +
}
 +
} );
 
}
 
}
/*</pre>
 
===WT:PREFS===
 
<pre>*/
 
  
if ( jQuery.cookie('WiktPrefs') || mw.config.get('wgPageName') == "Wiktionary:Per-browser_preferences") {
+
$( '#mw-content-text' ).on( 'click', '.load-page-button > .jslink', function() {
//importScript('User:Connel_MacKenzie/custom.js');
+
var $this = $( this ),
importScript('User:Hippietrail/custom.js');
+
$button = $this.parent(),
}
+
$body = $this.closest( '.load-page' ),
 
+
$content = $body.find( '.load-page-content' );
/*</pre>
+
 
+
if ( !$body.data( 'loaded' ) ) {
===Edit page javascript===
+
var oldButton = $button.html();
<pre>*/
+
// Just in-case the spinner module is still not ready yet
$(document).ready( function() {
+
mw.loader.using( 'jquery.spinner', function() {
if ( wgAction == 'edit' || wgAction == 'submit' || document.getElementById('editpage-specialchars') ) {
+
$button.html( $.createSpinner() );
  importScript('MediaWiki:Edit.js');
+
} );
}
+
});
+
new mw.Api().get( {
/*</pre>
+
action: 'parse',
 
+
prop: 'text',
===Page specific extensions===
+
title: mw.config.get( 'wgPageName' ),
<pre>*/
+
text: '{' + '{:' + $body.data( 'page' ) + '}}'
 
+
} ).done( function( data ) {
/*</pre>
+
$content.html( data.parse.text['*'] ).show();
====Wiktionary:Main Page====
+
<pre>*/
+
$button.html( oldButton ).find( '> .jslink' ).text( mcw.i18n.hideText );
// Hide the title and "Redirected from" (maybe we should keep the redirected from so's people update their bookmarks ;)
+
// Broken in IE!
+
$body.data( 'loaded', true );
if ( wgPageName == 'Wiktionary:Main_Page' && !( wgAction == 'view' || wgAction == 'submit' ) ){
+
mw.util.addCSS( '.firstHeading { display: block !important; }' );
+
// Add Ajax compatible functions here
mw.util.addCSS( '#contentSub { display: inline !important; }' );
+
// TODO: Use mw.hook once we get MW1.22
}
+
mcw.animation();
 
+
mcw.makeCollapsible( $content );
if (wgPageName == 'Wiktionary:Main_Page') {
+
if ( $content.find( 'table.sortable' ).length ) {
$(function () {
+
mw.loader.using( 'jquery.tablesorter', function() {
mw.util.addPortletLink('p-lang', '//meta.wikimedia.org/wiki/Wiktionary#List_of_Wiktionaries',
+
$content.find( 'table.sortable' ).tablesorter();
'Complete list', 'interwiki-completelist', 'Complete list of Wiktionaries');
+
} );
});
+
}
}
+
} ).fail( function( _, error ) {
 
+
$button.html( oldButton );
/*</pre>
+
====Special:Search====
+
var errorText = '';
<pre>*/
+
if ( error.textStatus ) {
 
+
errorText = error.textStatus;
if ( wgPageName == 'Special:Search') {
+
} else if ( error.error ) {
importScript('MediaWiki:SpecialSearch.js');
+
errorText = error.error.info;
importScript('User:Yair rand/FindTrans.js');
+
}
}
+
jQuery(document).ready(function () { if(document.getElementById('preloadGuide')) {
+
mw.notify( errorText, { title: mcw.i18n.loadErrorTitle, autoHide: false } );
importScript('MediaWiki:SpecialSearch.js');
+
} );
}});
+
} else if ( $this.text() === mcw.i18n.showText ) {
 
+
$content.show();
/*</pre>
+
$this.text( mcw.i18n.hideText );
====Unsupported titles====
 
<pre>*/
 
 
 
if (wgTitle.indexOf('Unsupported titles/') === 0)
 
$(document).ready(function () {
 
//if (wgCanonicalNamespace != 'Appendix') return;
 
//pages have been moved to mainspace, so commenting out this line
 
var newTitle;
 
if (document.getElementById('unsupportedpage')) {
 
newTitle = document.getElementById('unsupportedpage').title;
 
 
} else {
 
} else {
newTitle = "[" + wgTitle.slice(19) + "]";
+
$content.hide();
 +
$this.text( mcw.i18n.showText );
 
}
 
}
document.getElementById('firstHeading').innerHTML = newTitle;
+
} );
});
 
  
/*</pre>
+
/**
 
+
* Make simple search suggestions box separately styled
====Custom search engines====
+
*/
<pre>*/
+
mw.loader.using( 'mediawiki.searchSuggest', function() {
 
+
$( '.suggestions:first' ).addClass( 'searchbar' );
if( wgPageName=='Help:Tips_and_tricks' ){
+
} );
importScript('MediaWiki:CustomSearch.js');
 
}
 
  
/*</pre>
 
 
====Turn headings in comments into real headings on JavaScript source pages====
 
<pre>*/
 
 
else if ((wgNamespaceNumber == 2 || wgNamespaceNumber == 8) && wgTitle.lastIndexOf('.js') != -1 && wgAction == 'view') {
 
importScript('MediaWiki:JavascriptHeadings.js');
 
}
 
 
/*</pre>
 
====Geonotice====
 
<pre>*/
 
/*Ended December 2009
 
else if (wgPageName == "Special:Watchlist") //watchlist scripts
 
{
 
importScriptURI('http://toolserver.org/~para/geoip.fcgi');
 
addOnloadHook(function() { importScriptURI('http://en.wiktionary.org/w/index.php?title=MediaWiki:Geonotice.js&action=raw&ctype=text/javascript&maxage=3600'); });
 
}
 
*/
 
/*</pre>
 
====New-section redirects====
 
<pre>*/
 
// This allows the new-section link (the "+" tab) to point to a different
 
// URL, as specified by the page (so that, for example, the new-section link
 
// for the Grease pit will add a new section to the appropriate monthly
 
// subpage):
 
importScript('MediaWiki:NewSectionRedirects.js');
 
/*</pre>
 
 
===Add editor.js for editing translations===
 
<pre>*/
 
 
importScript('User:Conrad.Irwin/editor.js');
 
 
/*</pre>
 
 
===Import newentrywiz.js===
 
<pre>*/
 
jQuery(document).ready(function(){
 
if(document.getElementById('necblah')){
 
  importScript('User:Yair rand/newentrywiz.js');
 
}
 
});
 
 
 
/*</pre>
 
===Import adddefinition.js===
 
<pre>*/
 
importScript('User:Yair rand/adddefinition.js');
 
/*</pre>
 
===Import rhymesedit.js===
 
<pre>*/
 
wgNamespaceNumber == 106 && importScript("User:Yair rand/rhymesedit.js");
 
/*</pre>
 
===Import Targeted Translations===
 
<pre>*/
 
importScript("User:Yair rand/TargetedTranslations.js");
 
/*</pre>
 
 
==URL Fixes==
 
<pre>*/
 
  
 
/**
 
/**
  * doRedirect will redirect if a did you mean box is found, and create a
+
  * Collapsible details for [[Template:History2]]
  * "redirected from X" if a rdfrom is passed in the get parameters
+
  *
  * The first half is an ugly workaround for Bugzilla:3339, :(
+
  * Allows version history to be split up into snapshots
  * The second half is an ugly workaround for not having serverware support :(
+
  */
**/
+
/*if ( $( '.history2' ).find( 'pre' ).length ) {
 +
var histExpandText = 'View snapshot history', histCollapseText = 'Hide snapshot history';
  
/*</pre>
+
$( '.history2 th:first' ).append( '<span class="toggleHistDetails">[<span class="jslink">' + histExpandText + '</span>]</span>' );
===Did you mean ____ redirects===
 
<pre>*/
 
  
jQuery(document).ready(function () {
+
var histLink = $( '.toggleHistDetails .jslink' );
// REDIRECTED FROM
+
histLink.click( function() {
if( window.location.href.indexOf('rdfrom=') != -1 ) {
+
if ( $( '.history2 .details' ).length ) {
var wiktDYMfrom = decodeURIComponent(window.location.href.replace(/^(.+[&\?]rdfrom=([^&]+).*|.*)?$/,"$2"));
+
$( '.history2 .overview' ).toggle();
 
+
$( '.history2 .details' ).toggle();
jQuery('#siteSub').after(
+
} else {
newNode('div', {id: 'contentSub'}, '(Auto-redirected from ',
+
$( '.history2 tr' ).each( function() {
newNode('a', {href: mw.util.getUrl(wiktDYMfrom) + '?redirect=no', 'class': 'new'}, wiktDYMfrom),
+
if ( !$( this ).find( 'pre' ).length || !$( this ).find( 'th' ).length ) {
')'));
+
return true;
 
+
}
} else {
+
// DID YOU MEAN
+
var header = $( this ), row = header, text = header.find( '> td' ).html() + '</td></tr>',
+
rowspan = header.find( '> th' ).prop( 'rowspan' );
var target = jQuery('#did-you-mean a').html(),
+
pagetitle = jQuery('h1').first().text().replace(/^\s+|\s+$/g, '');
+
row.addClass( 'overview' );
 
+
if ( rowspan > 1 ) {
if (target && target != pagetitle
+
for ( var i = 1; i < rowspan; i++ ) {
&& !window.location.href.match(/[&\?]redirect=no|[&\?]action=(?!view)/)
+
row = row.next();
&& (jQuery.cookie('WiktionaryDisableAutoRedirect') != 'true')
+
if ( !row.length ) {
&& wgArticleId === 0
+
break;
&& !/Redirected from/.test(jQuery('#contentSub').html())
+
}
) {
+
row.addClass( 'overview' );
document.location = mw.util.getUrl( target, { "rdfrom": pagetitle } );
+
 +
text += '\n<tr><td>' + row.find( '> td' ).html() + '</td></tr>';
 +
}
 +
}
 +
 +
var versions = text.split( '<pre>' ), data = [];
 +
rowspan = 0;
 +
$.each( versions, function() {
 +
var parts = this.split( '</' + 'pre>' ), version = parts[0].replace( /\n/g, '' ), text = parts[1];
 +
 +
if ( !version || !text ) {
 +
return true;
 +
}
 +
 +
text = text.replace( /<tr>/g, '<tr class="details">' );
 +
 +
if ( text.slice( text.lastIndexOf( '</tr>' ) ).indexOf( '<td>' ) > -1 ) {
 +
text = text.slice( 0, text.lastIndexOf( '</tr>' ) );
 +
}
 +
 +
if ( text.slice( text.lastIndexOf( '<td>' ) ).indexOf( '</td>' ) < 0 ) {
 +
text += '</td></tr>';
 +
}
 +
 +
if ( version.match( /\d\dw\d\d\w/ ) ) {
 +
version = '<a title="Version history/Development versions" href="/' + 'Version_history/Development_versions#' + version + '">' + version + '</a>';
 +
} else {
 +
version = '<a title="Version history" href="/' + 'Version_history#' + version + '">' + version + '</a>';
 +
}
 +
 +
var rows;
 +
if ( text.match( /<td>/g ) ) {
 +
rows = text.match( /<td>/g ).length + 1;
 +
} else {
 +
rows = 1;
 +
}
 +
rowspan += rows;
 +
data.push( '<th rowspan="' + rows + '">' + version + '</th><td>' + text );
 +
} );
 +
 +
var html = '<tr class="details"><th rowspan="' + rowspan + '">' + header.find( '> th' ).html() + '</th>' + data.join( '<tr class="details">' );
 +
$( '<table>' + html + '</table>' ).find( 'td > ol' ).each( function() {
 +
var text = $( this ).html();
 +
html = html.split( '<ol>' + text + '</ol>' ).join( '<ul>' + text + '</ul>' );
 +
} );
 +
 +
row.after( html );
 +
} );
 +
 +
$( '.history2 .overview' ).hide();
 
}
 
}
}
+
 
+
if ( histLink.text() === histExpandText) {
// Random page in a given language
+
histLink.text( histCollapseText );
document.location.toString().replace(/[?&]rndlang=([^&#]+)[^#]*(?:#(.+))?/, function (m, lang, headlang) {
+
} else {
var script = 'http://toolserver.org/~hippietrail/randompage.fcgi';
+
histLink.text( histExpandText );
 
 
var insert = document.getElementById('contentSub');
 
if (headlang) {
 
var heading = document.getElementById(headlang);
 
if (heading) heading = heading.parentNode;
 
if (heading) {
 
insert = newNode('div', {style: 'font-size: 84%; line-height: 1.2em;'});
 
heading.parentNode.insertBefore(insert, heading.nextSibling)
 
}
 
 
}
 
}
 +
} );
 +
}*/
  
if (!insert || insert.innerHTML != "") return;
+
/**
 
+
* Issue tracker loader
insert.appendChild(newNode('span', {style: 'color: #888;'}, "Another ",
+
*/
newNode('a', {href: script + '?langs=1'}, "Random"), " word in ",
+
/**if ( $( '#issue-list' ).length ) {
newNode('a', {href: script + '?langname=' + lang}, decodeURIComponent(lang))
+
var page = $( '#issue-list' ).data( 'name' ) || mw.config.get( 'wgPageName' ),
));
+
amount = $( '#issue-list' ).data( 'num' ) || 20;
});
+
})
+
if ( $.isArray( page ) ) {
 
+
page = page.join( '" OR summary ~ "' );
/*</pre>
 
 
 
===Fix Wikified section titles===
 
<pre>*/
 
jQuery(document).ready(function () {
 
// {temp|template}
 
if (/\.7B\.7Btemp\.7C(.*?)\.7D\.7D/.test(window.location.href)) {
 
var url=window.location.href.replace(/\.7B\.7Btemp.7C/g, ".7B.7B");
 
window.location = url;
 
 
}
 
}
});
+
 
+
var jql = encodeURIComponent( 'project in (MC, MCPE) AND resolution = Unresolved AND ( summary ~ "' + page + '" )' );
jQuery(document).ready(function () {
+
if(wgAction != 'edit')
+
return;
+
$.ajax(  
if(! /[?&]section=\d/.test(window.location.href))
+
'https://mojang.atlassian.net/rest/api/latest/search?maxResults=' + amount + '&fields=summary&jql=' + jql
return;
+
).done( function( search ) {
var wpSummary = document.getElementById('wpSummary');
+
if ( !search.issues.length ) {
if(! wpSummary)
+
$( '#issue-list' ).text( 'No issues were found.' );
return;
+
return false;
if(wpSummary.value.substr(0, 3) != '/* ')
 
return;
 
if(wpSummary.value.substr(wpSummary.value.length - 4) != ' */ ')
 
return;
 
wpSummary.value = wpSummary.value.replace(/\{\{temp(late)?\|/g, '{{');
 
});
 
 
 
/*</pre>
 
== Visibility toggling ==
 
<pre>*/
 
var VisibilityToggles = {
 
// toggles[category] = [[show, hide],...]; statuses[category] = [true, false,...]; buttons = <li>
 
toggles: {}, statuses: {}, buttons: null,
 
 
 
// Add a new toggle, adds a Show/Hide category button in the toolbar,
 
// and will call show_function and hide_function once on register, and every alternate click.
 
register: function (category, show_function, hide_function) {
 
 
 
var id = 0;
 
if (!this.toggles[category]) {
 
this.toggles[category] = [];
 
this.statuses[category] = [];
 
} else {
 
id = this.toggles[category].length;
 
}
 
this.toggles[category].push([show_function, hide_function]);
 
this.statuses[category].push(this.currentStatus(category));
 
this.addGlobalToggle(category);
 
 
 
(this.statuses[category][id] ? show_function : hide_function)();
 
 
 
return function () {
 
var statuses = VisibilityToggles.statuses[category];
 
statuses[id] = !statuses[id]
 
VisibilityToggles.checkGlobalToggle(category);
 
return (statuses[id] ? show_function : hide_function)();
 
 
}
 
}
  
},
+
var compIssues = [], pocketIssues = [];
 
+
$.each( search.issues, function() {
// Add a new global toggle to the side bar
+
if ( this.key.indexOf( 'MCPE' ) < 0 ) {
addGlobalToggle: function(category) {
+
compIssues.push( '<li>[<a href="https://mojang.atlassian.net/browse/' + this.key + '">' + this.key + '</a>] - ' + this.fields.summary + '</li>' );
if (document.getElementById('p-visibility-'+category))
+
} else {
return;
+
pocketIssues.push( '<li>[<a href="https://mojang.atlassian.net/browse/' + this.key + '">' + this.key + '</a>] - ' + this.fields.summary + '</li>' );
if (!this.buttons) {
 
this.buttons = newNode('ul');
 
var collapsed = $.cookie("vector-nav-p-visibility") == "false", toolbox = newNode('div', {'class': "portal portlet "+(collapsed?"collapsed":"expanded"), 'id': 'p-visibility'},
 
newNode('h3', 'Visibility'),
 
newNode('div', {'class': "pBody body"}, collapsed?undefined:{'style':'display:block;'}, this.buttons)
 
  );
 
var sidebar = document.getElementById('mw-panel') || document.getElementById('column-one');
 
var insert = null;
 
if (insert = (document.getElementById('p-lang') || document.getElementById('p-feedback')))
 
sidebar.insertBefore(toolbox, insert);
 
else
 
sidebar.appendChild(toolbox);
 
 
 
}
 
var status = this.currentStatus(category);
 
var newToggle = newNode('li', newNode('a', {
 
id: 'p-visibility-' + category,
 
style: 'cursor: pointer',
 
href: '#visibility-' + category,
 
click: function(e)
 
{
 
VisibilityToggles.toggleGlobal(category);
 
if (e && e.preventDefault)
 
e.preventDefault();
 
else
 
window.event.returnValue = false;
 
return false;
 
}},
 
(status ? 'Hide ' : 'Show ') + category));
 
for (var i=0; i < this.buttons.childNodes.length; i++) {
 
if (this.buttons.childNodes[i].id < newToggle.id) {
 
this.buttons.insertBefore(newToggle, this.buttons.childNodes[i]);
 
return;
 
 
}
 
}
 +
} );
 +
 +
var html = '';
 +
if ( compIssues.length ) {
 +
html = '<p><b>Computer:</b></p><ul>' + compIssues.join( '\n' ) + '</ul>';
 
}
 
}
this.buttons.appendChild(newToggle);
+
if ( pocketIssues.length ) {
},
+
html += '\n<p><b>Pocket Edition:</b></p><ul>' + pocketIssues.join( '\n' ) + '</ul>';
 
 
// Update the toggle-all buttons when all things are toggled one way
 
checkGlobalToggle: function(category) {
 
var statuses = this.statuses[category];
 
var status = statuses[0];
 
for (var i = 1; i < statuses.length; i++) {
 
if (status != statuses[i])
 
return;
 
 
}
 
}
document.getElementById('p-visibility-' + category).innerHTML = (status ? 'Hide ' : 'Show ') + category;
+
},
+
if ( search.total > amount ) {
 
+
var extra = search.total - amount;
// Toggle all un-toggled elements when the global button is clicked
+
html += '\n<p><a href="https://mojang.atlassian.net/issues/?jql=' + jql + '">View ' + extra + ' more result';
toggleGlobal: function(category) {
+
var status = document.getElementById('p-visibility-' + category).innerHTML.indexOf('Show ') == 0;
+
if ( extra > 1 ) {
for (var i = 0; i < this.toggles[category].length; i++ ) {
+
html += 's';
if (this.statuses[category][i] != status) {
 
this.toggles[category][i][status ? 0 : 1]();
 
this.statuses[category][i] = status;
 
 
}
 
}
 +
 +
html += '</a></p>';
 
}
 
}
document.getElementById('p-visibility-' + category).innerHTML = (status ? 'Hide ' : 'Show ') + category;
 
var current = jQuery.cookie('Visibility');
 
if (!current)
 
current = ";";
 
current = current.replace(';' + category + ';', ';');
 
if (status)
 
current = current + category + ";";
 
setCookie('Visibility', current);
 
},
 
  
currentStatus: function(category) {
+
$( '#issue-list' ).html( html );
if (window.location.hash.toLowerCase().split('_')[0] == '#' + category.toLowerCase())
+
} );
return true;
 
if (window.location.href.search(/[?](.*&)?hidecats=/) > 0)
 
{
 
var hidecats = window.location.href;
 
hidecats = hidecats.replace(/^[^?]+[?]((?!hidecats=)[^&]*&)*hidecats=/, '');
 
hidecats = hidecats.replace(/&.*/, '');
 
hidecats = hidecats.split(',');
 
for (var i = 0; i < hidecats.length; ++i)
 
if (hidecats[i] == category || hidecats[i] == 'all')
 
return false;
 
else if (hidecats[i] == '!' + category || hidecats[i] == 'none')
 
return true;
 
}
 
if (jQuery.cookie('WiktionaryPreferencesShowNav') == 'true')
 
return true;
 
if ((jQuery.cookie('Visibility') || "").indexOf(';' + category + ';') >= 0)
 
return true;
 
// TODO check category-specific cookies
 
return false;
 
}
 
 
}
 
}
 +
*/
  
/*</pre>
 
=== NavBars ===
 
<pre>*/
 
var NavigationBarHide = 'hide ▲';
 
var NavigationBarShow = 'show ▼';
 
  
function NavToggleCategory(navFrame)
+
/**
{
+
* Set unlicensed as the default license on file pages
var table = navFrame.getElementsByTagName('table')[0];
+
*
if (table && table.className == "translations")
+
* That way the file will be categorised so someone can find a license for the file
return "translations";
+
*/
 
+
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Upload' ) {
var heading = navFrame.previousSibling;
+
if ( $( '#wpLicense' ).val() === '' ) {
while (heading) {
+
$( '#wpLicense' ).val( mcw.i18n.defaultLicense );
if (/[hH][4-6]/.test(heading.nodeName)) {
 
if (heading.getElementsByTagName('span')[1])
 
heading = heading.getElementsByTagName('span')[0];
 
return $(heading).text().toLowerCase()
 
// jQuery's .text() is inconsistent about whitespace:
 
.replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ')
 
// remove numbers added by the "Auto-number headings" pref:
 
.replace(/^[1-9][0-9.]+ ?/, '');
 
}
 
else if (/[hH][1-3]/.test(heading.nodeName))
 
break;
 
heading = heading.previousSibling;
 
 
}
 
}
return "other boxes";
+
 +
mw.loader.using( 'mediawiki.legacy.upload', function() {
 +
var change = setInterval( function() {
 +
if ( licenseSelectorCheck ) {
 +
$( '#wpLicense' ).change();
 +
clearInterval( change );
 +
}
 +
}, 500 );
 +
} );
 
}
 
}
  
function createNavToggle(navFrame){
 
var navHead, navToggle, navContent;
 
for (var j=0; j < navFrame.childNodes.length; j++) {
 
var div = navFrame.childNodes[j];
 
switch (div.className) {
 
case 'NavHead':
 
navHead = div;
 
break;
 
case 'NavContent':
 
navContent = div;
 
break;
 
}
 
}
 
if (!navHead || !navContent)
 
return;
 
// Step 1, don't react when a subitem is clicked.
 
for (var i=0; i<navHead.childNodes.length; i++) {
 
var child = navHead.childNodes[i];
 
if (child.nodeName == "A") {
 
child.onclick = function (e)
 
{
 
if (e && e.stopPropagation)
 
e.stopPropagation();
 
else
 
window.event.cancelBubble = true;
 
}
 
}
 
}
 
// Step 2, toggle visibility when bar is clicked.
 
// NOTE This function was chosen due to some funny behaviour in Safari.
 
navToggle = newNode('a', {href: 'javascript:(function(){})()'}, '');
 
navHead.insertBefore(newNode('span', {'class': 'NavToggle'}, '[', navToggle, ']'), navHead.firstChild);
 
  
navHead.style.cursor = "pointer";
+
/**
navHead.onclick = VisibilityToggles.register(NavToggleCategory(navFrame),
+
* Creates minecraft style tooltips
function show() {
+
*
navToggle.innerHTML = NavigationBarHide;
+
* Replaces normal tooltips. Supports minecraft [[formatting codes]] (except k), and a description with line breaks (/).
if (navContent)
+
* Use mcw.useNativeMinetip = true to use normal tooltips, with the description added
navContent.style.display = "block";
+
*/
},
+
mcw.minetip = {
function hide() {
+
// Add normal minetip events, removing legacy tooltip
navToggle.innerHTML = NavigationBarShow;
+
create: function() {
if (navContent)
+
var tooltip;
navContent.style.display = "none";
+
});
+
$( '#mw-content-text' ).on( {
};
+
'mouseenter.minetip': function( e ) {
 
+
var $elem = $( this ),
jQuery(document).ready( function ()
+
title = $elem.data( 'minetip-title' ),
{
+
description = $elem.data( 'minetip-text' );
var divs = $(".NavFrame");
+
for (var i=0; i<divs.length; i++) {
+
// No title or title only contains formatting codes
// NOTE: some templates use a class of NavFrame for the style, but for legacy reasons, are not NavFrames
+
if ( title === undefined || title && title.replace( /&([0-9a-fl-o])|\s+/g, '' ) === '' ) {
if (divs[i].className == "NavFrame") {
+
// Use title attribute of the element or the first link directly under it
createNavToggle(divs[i]);
+
var attrTitle = $elem.attr( 'title' ) || $elem.find( '> a:first' ).attr( 'title' );
}
+
if ( title === undefined ) {
}
+
title = attrTitle;
 
+
} else {
});
+
title += attrTitle;
 
+
}
/*</pre>
+
 
+
if ( title ) {
===Hidden Quotes===
+
// Set the retrieved title as data for future use
<pre>*/
+
$elem.data( 'minetip-title', title );
 
+
} else {
function setupHiddenQuotes(li) {
+
return;
var HQToggle, liComp, dl;
 
var HQShow = 'quotations ▼';
 
var HQHide = 'quotations ▲';
 
for (var k = 0; k < li.childNodes.length; k++) {
 
// Look at each component of the definition.
 
liComp = li.childNodes[k];
 
if ( liComp.nodeName.toLowerCase() === "dl" && !dl ) {
 
dl = liComp;
 
}
 
// If we find a ul or dl, we have quotes or example sentences, and thus need a button.
 
if (/^(ul|UL)$/.test(liComp.nodeName)) {
 
HQToggle = newNode('a', {href: 'javascript:(function(){})()'}, '');
 
li.insertBefore(newNode('span', {'class': 'HQToggle'}, ' [', HQToggle, ']'), dl || liComp);
 
HQToggle.onclick = VisibilityToggles.register('quotations',
 
function show() {
 
HQToggle.innerHTML = HQHide;
 
for (var child = li.firstChild; child != null; child = child.nextSibling) {
 
if (/^(ul|UL)$/.test(child.nodeName)) {
 
child.style.display = 'block';
 
}
 
 
}
 
}
},
+
}
function hide() {
+
HQToggle.innerHTML = HQShow;
+
$elem.add( '*', $elem ).filter( '[title]' ).removeAttr( 'title' );
for (var child = li.firstChild; child != null; child = child.nextSibling) {
+
if (/^(ul|UL)$/.test(child.nodeName)) {
+
if ( title === 0 ) {
child.style.display = 'none';
+
return;
}
+
}
 +
 +
var text = '<span class="title">' + title + '&f</span>';
 +
if ( description ) {
 +
text += '\n<span class="description">' +
 +
description.replace( /\\\//g, '&#47;' ).replace( /\//g, '<br>' ) +
 +
'&f</span>';
 +
}
 +
 +
if ( !$( '#minetip-tooltip' ).length ) {
 +
$( 'body' ).append( '<div id="minetip-tooltip"/>' );
 +
}
 +
tooltip = $( '#minetip-tooltip' );
 +
 +
// Add classes for minecraft formatting codes
 +
while ( text.match( /&[0-9a-el-o]/ ) ) {
 +
text = text.replace( /&([0-9a-el-o])(.*?)(&f|$)/g, '<span class="format-$1">$2</span>&f' );
 +
}
 +
// Remove reset formatting
 +
text = text.replace( /&f/g, '' );
 +
 +
tooltip.html( text );
 +
 +
// 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;
 +
 +
var top = e.clientY - 34,
 +
left = e.clientX + 14,
 +
width = tooltip.outerWidth( true ),
 +
height = tooltip.outerHeight( true ),
 +
 +
$win = $( window ),
 +
winWidth = $win.width(),
 +
winHeight = $win.height();
 +
 +
// 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 below the cursor
 +
if ( left < 0 ) {
 +
left = 0;
 +
top += 82;
 +
 +
// Go above the cursor if too low
 +
if ( top + height > winHeight ) {
 +
top -= 77 + height;
 
}
 
}
});
+
// Don't go off the top of the screen
 
+
} else if ( top < 0 ) {
break;
+
top = 0;
}
+
// Don't go off the bottom of the screen
}
+
} else if ( top + height > winHeight ) {
}
+
top = winHeight - height;
+
}
jQuery(document).ready(function () {
+
if (wgNamespaceNumber == 0) {
+
// Apply the positions
var ols, lis, li;
+
tooltip.css( {
// First, find all the ordered lists, i.e. all the series of definitions.
+
top: top,
var ols = document.getElementsByTagName('ol');
+
left: left
for(var i = 0; i < ols.length; i++) {
+
} );
// Then, for every set, find all the individual definitions.
+
},
for (var j = 0; j < ols[i].childNodes.length; j++) {
+
'mouseleave.minetip': function() {
li = ols[i].childNodes[j];
+
if ( !tooltip ) {
if (li.nodeName.toUpperCase() == 'LI') {
+
return;
setupHiddenQuotes(li);
 
 
}
 
}
 +
 +
tooltip.remove();
 
}
 
}
}
+
}, '.minetip, .grid .image, .grid .item, .grid2 .item' ).off( '.minetipNative' );
}
+
},
});
+
// Remove all events
 
+
destroy: function() {
/*</pre>
+
$( '#mw-content-text' ).off( '.minetip .minetipNative' );
 
+
$( '#minetip-tooltip' ).remove();
== Interproject links ==
+
},
<pre>*/
+
// Add native browser tooltip events, removing normal minetip
 
+
native: function() {
/*
+
$( '#mw-content-text' ).on( 'mouseenter.minetipNative', '.minetip, .grid .image, .grid .item, .grid2 .item', function() {
#########
+
var title = $( this ).data( 'minetip-title' ),
### ProjectLinks
+
description = $( this ).data( 'minetip-text' ),
###  by [[user:Pathoschild]] (idea from an older, uncredited script)
+
existingTitle = $( this ).attr( 'title' ) || $( this ).find( '> a:first' ).attr( 'title' );
###    * generates a sidebar list of links to other projects from {{projectlinks}}
+
#########
+
if ( title || title === 0 || $( this ).attr( 'title' ) ) {
*/
+
// Remove titles within so they don't interfere
jQuery(document).ready(function () {
+
$( this ).find( '[title]' ).removeAttr( 'title' );
var elements = new Array();
+
}
var spans = document.getElementsByTagName('span');
+
 
+
if ( title === 0 ) {
// filter for projectlinks
+
$( this ).removeAttr( 'title' );
for (var i=0, j=0; i<spans.length; i++) {
+
return;
if (spans[i].className == 'interProject') {
+
} else if ( !title && ( !existingTitle || !description ) ) {
elements[j] = spans[i].getElementsByTagName('a')[0];
+
return;
j++;
+
} else if ( !title && existingTitle ) {
}
+
$( this ).data( 'minetip-title', existingTitle );
}
 
 
 
if (j == 0)
 
return;
 
 
 
// sort alphabetically
 
function sortbylabel(a,b) {
 
// get labels
 
a = a.innerHTML.replace(/^.*<a[^>]*>(.*)<\/a>.*$/i,'$1');
 
b = b.innerHTML.replace(/^.*<a[^>]*>(.*)<\/a>.*$/i,'$1');
 
 
 
// return sort order
 
if (a < b) return -1;
 
if (a > b) return 1;
 
return 0;
 
}
 
elements.sort(sortbylabel);
 
 
 
// Create the list of project links
 
var pllist = newNode('ul');
 
for (var i=0; i<elements.length; i++) {
 
pllist.appendChild(newNode('li', elements[i]));
 
}
 
var collapsed = $.cookie("vector-nav-p-projects") == "false";
 
var projectBox = newNode('div', {'class': 'portlet portal '+(collapsed?"collapsed":"expanded"), id: 'p-projects'},
 
newNode('h3', 'In other projects'),
 
newNode('div', {'class': 'pBody body'}, collapsed?undefined:{'style':'display:block;'}, pllist)
 
);
 
 
 
var insert = document.getElementById('p-tb');
 
if (!insert)
 
return;
 
 
 
if (insert.nextSibling)
 
insert.parentNode.insertBefore(projectBox, insert.nextSibling);
 
else
 
insert.parentNode.appendChild(projectBox);
 
});
 
 
 
/*</pre>
 
===Scripts specific to Internet Explorer===
 
<pre>*/
 
if (navigator.appName == "Microsoft Internet Explorer") {
 
/** Internet Explorer bug fix **************************************************
 
*
 
*  Description: Fixes IE horizontal scrollbar bug
 
*  Maintainers: [[User:Tom-]]?
 
*/
 
 
 
var oldWidth;
 
var docEl = document.documentElement;
 
 
 
function fixIEScroll()
 
{
 
if (!oldWidth || docEl.clientWidth > oldWidth)
 
doFixIEScroll();
 
else
 
setTimeout(doFixIEScroll, 1);
 
 
 
oldWidth = docEl.clientWidth;
 
}
 
 
 
function doFixIEScroll() {
 
docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? "hidden" : "";
 
}
 
 
document.attachEvent("onreadystatechange", fixIEScroll);
 
document.attachEvent("onresize", fixIEScroll);
 
 
 
// In print IE (7?) does not like line-height
 
mw.util.addCSS( '@media print { sup, sub, p, .documentDescription { line-height: normal; }}');
 
 
 
// IE overflow bug
 
mw.util.addCSS('div.overflowbugx { overflow-x: scroll !important; overflow-y: hidden !important; } div.overflowbugy { overflow-y: scroll !important; overflow-x: hidden !important; }');
 
 
 
// IE zoomfix
 
// Use to fix right floating div/table inside tables
 
mw.util.addCSS('.iezoomfix div, .iezoomfix table { zoom: 1;}');
 
 
 
// Import scripts specific to Internet Explorer 6
 
if (navigator.appVersion.substr(22, 1) == "6") {
 
importScript("MediaWiki:Common.js/IE60Fixes.js")
 
}
 
}
 
 
 
/*</pre>
 
===Category page fixes===
 
<pre>*/
 
 
 
$(document).ready(function($){
 
var s, c = "", lang;
 
if( wgNamespaceNumber === 14 && ( s = document.getElementById("catfix") ) ) {
 
lang = s.className.split("CATFIX-")[1]
 
if (lang.length > 0)
 
{
 
c = "#" + lang;
 
}
 
 
 
s = s.getElementsByTagName("*")[0] || document.createElement("span");
 
$("#mw-pages>.mw-content-ltr").find("li>a").each(function(){
 
var li = this.parentNode, clone = s.cloneNode( false );
 
li.removeChild( this );
 
this.setAttribute("href", this.getAttribute("href", 2) + c );
 
clone.appendChild( this );
 
li.appendChild( clone );
 
})
 
}
 
})
 
 
 
/*</pre>
 
===Temporary button for enabling two proposed scripts===
 
<pre>*/
 
 
 
if ( $.cookie("YRNewStuff") || location.search.indexOf("tabbedlanguages=on") != -1 )
 
{
 
importScript("User:Yair rand/editor2.js")
 
importScript("User:Yair rand/TabbedLanguages2.js")
 
}
 
 
 
jQuery(document).ready(function () {
 
if(document.getElementById('YRNewStuff-enable-button'))
 
{
 
document.getElementById('YRNewStuff-enable-button').innerHTML = ""
 
var toggle = newNode('span', {click: function ()
 
{
 
if( $.cookie("YRNewStuff") ){
 
$.cookie("YRNewStuff", null,{path:"/"})
 
toggle.innerHTML = "Enable tabbed languages and definition editing options."
 
 
}
 
}
else{
+
$.cookie("YRNewStuff",1,{expires:30,path:"/"})
+
var text = title || existingTitle;
toggle.innerHTML = "Disable tabbed languages and definition editing options."
+
if ( description ) {
 +
text += '\n' + description;
 
}
 
}
} }, ($.cookie("YRNewStuff")?"Disable":"Enable")+" tabbed languages and definition editing options.")
+
+
// Remove formatting
document.getElementById('YRNewStuff-enable-button').appendChild(toggle);
+
text = text.replace( /&([0-9a-fl-o])/g, '' )
 +
.replace( /\\\//g, '&#47;' )
 +
.replace( /\//g, '\n' )
 +
.replace( /&#47;/g, '/' );
 +
 +
$( this ).attr( 'title', text );
 +
} ).off( '.minetip' );
 
}
 
}
})
+
};
  
/*</pre>
+
if ( mcw.useNativeMinetip ) {
===WT:ES Discussion tool===
+
mcw.minetip.native();
<pre>*/
+
} else {
 
+
mcw.minetip.create();
wgPageName == "Wiktionary:Etymology_scriptorium" && importScript("User:Yair rand/DiscussionSandbox.js");
+
}
  
$(document).ready(function() {
 
$("table.unit-tests th.unit-tests-img-corner").bind("click", function () {
 
var table = this;
 
while (table.tagName !== "TABLE")
 
table = table.parentNode;
 
table.classList.toggle("unit-tests-hide-passing");
 
})
 
});
 
  
/**
+
} );
* Collapsible tables
+
} )();
*
 
* @version 2.0.1 (2013-03-26)
 
* @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';
 
 
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 createClickHandler( tableIndex ) {
 
return function ( e ) {
 
e.preventDefault();
 
collapseTable( tableIndex );
 
}
 
}
 
 
function createCollapseButtons() {
 
var tableIndex = 0;
 
var NavigationBoxes = {};
 
var Tables = document.getElementsByTagName( 'table' );
 
 
for ( var i = 0; i < Tables.length; i++ ) {
 
if ( $( Tables[i] ).hasClass( '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.style.styleFloat = 'right';
 
Button.style.cssFloat = 'right';
 
Button.style.fontWeight = 'normal';
 
Button.style.textAlign = 'right';
 
Button.style.width = '6em';
 
 
ButtonLink.style.color = Header.style.color;
 
ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
 
$( ButtonLink ).on( 'click', createClickHandler( tableIndex ) );
 
ButtonLink.appendChild( ButtonText );
 
 
Button.appendChild( document.createTextNode( '[' ) );
 
Button.appendChild( ButtonLink );
 
Button.appendChild( document.createTextNode( ']' ) );
 
 
Header.insertBefore( Button, Header.childNodes[0] );
 
tableIndex++;
 
}
 
}
 
 
for ( var i = 0; i < tableIndex; i++ ) {
 
if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) ||
 
( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) )
 
) {
 
collapseTable( i );
 
}
 
}
 
}
 
 
$( createCollapseButtons );
 

Revisión del 06:53 10 abr 2014

( function() {
'use strict';

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


/* Legacy support */
mcw.baseURL = '/';
mcw.wikiURL = '/';


/* Variables for interface text used throughout the script, for ease of translating */
mcw.i18n = {
	// Collapsible tables and page loader
	hideText: 'hide',
	showText: 'show',
	
	// Page loader
	loadErrorTitle: 'An error occurred loading the content',
	
	// File upload
	defaultLicense: 'License'
};

/* Add extra buttons to the classic toolbar */
if ( mw.user.options.get( 'showtoolbar' ) && !mw.user.options.get( 'usebetatoolbar' ) ) {
	importScript( 'MediaWiki:Toolbar.js' );
}


/* Wait for DOMContentLoaded */
$( function() {

/**
 * Collapsible tables
 *
 * Based on http://www.mediawiki.org/wiki/Manual:Collapsible_tables#Common.js_script_.28before_1.18.29
 */
mcw.makeCollapsible = function( $content ) {
	if ( $content === undefined ) {
		$content = $( 'table.collapsible' );
	} else {
		$content = $content.find( 'table.collapsible' );
	}
	if ( !$content.length ) {
		return false;
	}
	
	var buttonText = ' <span class="collapsible-button">[<span class="jslink">' + mcw.i18n.hideText + '</span>]</span> ';
	
	$content.each( function() {
		var $table = $( this ), $header, $collapseButton, firstWidth, secondWidth;
		
		// This table is already collapsible
		if ( $table.data( 'collapsible' ) ) {
			return true;
		}
		
		// Use the collapse-button if specified otherwise the first header cell of the first row
		$header = $table.find( 'tr:first .collapse-button' );
		if ( !$header.length ) {
			$header = $table.find( 'tr:first > th:first' );
		}
		
		// No header or the table body is empty
		if ( !$header.length || !$table.find( 'tr:not(tr:first)' ).text().replace( /\n/g, '' ).length ) {
			return true;
		}
		
		// For the button to float properly, it has to be /before/ the cell text
		if ( $table.hasClass( 'collapse-button-none' ) ) {
			$header.append( buttonText );
		} else {
			$header.prepend( buttonText );
		}
		
		// Find max button size, and set its min-width to it
		$collapseButton = $table.find( '.collapsible-button' );
		firstWidth = $collapseButton.width();
		$collapseButton.find( '> .jslink' ).text( mcw.i18n.showText );
		secondWidth = $collapseButton.width();
		
		if ( firstWidth != secondWidth ) {
			if ( firstWidth < secondWidth ) {
				$collapseButton.css( 'min-width', secondWidth );
			} else {
				$collapseButton.css( 'min-width', firstWidth );
			}
		}
	
		// Set the text back to hide if it's not collapsed to begin with
		if ( !$table.hasClass( 'collapsed' ) ) {
			$collapseButton.find( '> .jslink' ).text( mcw.i18n.hideText );
		}
		
		$table.data( 'collapsible', true );
	} );
};

$( '#mw-content-text' ).on( 'click', 'table.collapsible .collapsible-button .jslink', 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( mcw.i18n.hideText );
	} else {
		$table.removeClass( 'expanded' ).addClass( 'collapsed' );
		$( this ).text( mcw.i18n.showText );
	}
} );
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';
}

/**
 * Element animator
 *
 * Will cycle the active class on any child elements
 * within an element with the animated class.
 */
mcw.animation = function() {
	if ( mcw.animate === undefined && $( '.animated' ).length ) {
		mcw.animate = setInterval( function() {
			$( '.animated' ).each( function() {
				var $current = $( this ).children( '.active' ), $next = $current.nextAll( ':not(.skip):first' );
				if ( !$next.length ) {
					$next = $( this ).children( ':not(.skip):first' );
				}
				$current.removeClass( 'active' );
				$next.addClass( 'active' );
			} );
		}, 2000 );
	}
};
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.
 */
$( '#mw-content-text' ).on( {
	'mouseenter': function() { 
		$( this ).find( '.animated' ).removeClass( 'animated' ).addClass( 'paused' );
	},
	'mouseleave': function() {
		$( this ).find( '.paused' ).removeClass( 'paused' ).addClass( 'animated' );
	}
}, '.grid-generic, .grid-Crafting_Table, .grid-Furnace, .grid-Brewing_Stand' );


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


/**
 * Page loader
 *
 * Allows a page to be downloaded and shown within another page.
 * Use with [[Template:LoadPage]]
 */
var $loadPage = $( '.load-page' );
if ( $loadPage.length ) {
	// We need the spinner to show loading is happening, but we don't want
	// to have a delay while the module downloads, so we'll load this now,
	// regardless of if something is clicked
	mw.loader.load( 'jquery.spinner' );
	
	var $buttonText = $( '<span/>' )
		.addClass( 'load-page-button' )
		.css( {
			display: 'inline-block',
			marginLeft: '0.8em',
			fontWeight: 'normal'
		} )
		.html( '[<span class="jslink">' + mcw.i18n.hideText + '</span>]' );
	$loadPage.find( '.mw-headline:first' ).each( function() {
		var $button, firstWidth, secondWidth;
		
		// Add the button
		$( this ).append( $buttonText.clone() );
		
		// Find max button size, and set its min-width to it
		$button = $( this ).find( '> .load-page-button' );
		firstWidth = $button.width();
		$button.find( '> .jslink' ).text( mcw.i18n.showText );
		secondWidth = $button.width();
		
		if ( firstWidth != secondWidth ) {
			if ( firstWidth < secondWidth ) {
				$button.css( 'min-width', secondWidth );
			} else {
				$button.css( 'min-width', firstWidth );
			}
		}
	} );
}

$( '#mw-content-text' ).on( 'click', '.load-page-button > .jslink', function() {
	var $this = $( this ),
		$button = $this.parent(),
		$body = $this.closest( '.load-page' ),
		$content = $body.find( '.load-page-content' );
	
	if ( !$body.data( 'loaded' ) ) {
		var oldButton = $button.html();
		// Just in-case the spinner module is still not ready yet
		mw.loader.using( 'jquery.spinner', function() {
			$button.html( $.createSpinner() );
		} );
		
		new mw.Api().get( {
			action: 'parse',
			prop: 'text',
			title: mw.config.get( 'wgPageName' ),
			text: '{' + '{:' + $body.data( 'page' ) + '}}'
		} ).done( function( data ) {
			$content.html( data.parse.text['*'] ).show();
			
			$button.html( oldButton ).find( '> .jslink' ).text( mcw.i18n.hideText );
			
			$body.data( 'loaded', true );
			
			// Add Ajax compatible functions here
			// TODO: Use mw.hook once we get MW1.22
			mcw.animation();
			mcw.makeCollapsible( $content );
			if ( $content.find( 'table.sortable' ).length ) {
				mw.loader.using( 'jquery.tablesorter', function() {
					$content.find( 'table.sortable' ).tablesorter();
				} );
			}
		} ).fail( function( _, error ) {
			$button.html( oldButton );
			
			var errorText = '';
			if ( error.textStatus ) {
				errorText = error.textStatus;
			} else if ( error.error ) {
				errorText = error.error.info;
			}
			
			mw.notify( errorText, { title: mcw.i18n.loadErrorTitle, autoHide: false } );
		} );
	} else if ( $this.text() === mcw.i18n.showText ) {
		$content.show();
		$this.text( mcw.i18n.hideText );
	} else {
		$content.hide();
		$this.text( mcw.i18n.showText );
	}
} );

/**
 * Make simple search suggestions box separately styled
 */
mw.loader.using( 'mediawiki.searchSuggest', function() {
	$( '.suggestions:first' ).addClass( 'searchbar' );
} );


/**
 * Collapsible details for [[Template:History2]]
 *
 * Allows version history to be split up into snapshots
 */
/*if ( $( '.history2' ).find( 'pre' ).length ) {
	var histExpandText = 'View snapshot history', histCollapseText = 'Hide snapshot history';

	$( '.history2 th:first' ).append( '<span class="toggleHistDetails">[<span class="jslink">' + histExpandText + '</span>]</span>' );

	var histLink = $( '.toggleHistDetails .jslink' );
	histLink.click( function() {
		if ( $( '.history2 .details' ).length ) {
			$( '.history2 .overview' ).toggle();
			$( '.history2 .details' ).toggle();
		} else {
			$( '.history2 tr' ).each( function() {
				if ( !$( this ).find( 'pre' ).length || !$( this ).find( 'th' ).length ) {
					return true;
				}
				
				var header = $( this ), row = header, text = header.find( '> td' ).html() + '</td></tr>',
					rowspan = header.find( '> th' ).prop( 'rowspan' );
				
				row.addClass( 'overview' );
				if ( rowspan > 1 ) {
					for ( var i = 1; i < rowspan; i++ ) {
						row = row.next();
						if ( !row.length ) {
							break;
						}
						row.addClass( 'overview' );
						
						text += '\n<tr><td>' + row.find( '> td' ).html() + '</td></tr>';
					}
				}
				
				var versions = text.split( '<pre>' ), data = [];
				rowspan = 0;
				$.each( versions, function() {
					var parts = this.split( '</' + 'pre>' ), version = parts[0].replace( /\n/g, '' ), text = parts[1];
					
					if ( !version || !text ) {
						return true;
					}
					
					text = text.replace( /<tr>/g, '<tr class="details">' );
					
					if ( text.slice( text.lastIndexOf( '</tr>' ) ).indexOf( '<td>' ) > -1 ) {
						text = text.slice( 0, text.lastIndexOf( '</tr>' ) );
					}
					
					if ( text.slice( text.lastIndexOf( '<td>' ) ).indexOf( '</td>' ) < 0 ) {
						text += '</td></tr>';
					}
					
					if ( version.match( /\d\dw\d\d\w/ ) ) {
						version = '<a title="Version history/Development versions" href="/' + 'Version_history/Development_versions#' + version + '">' + version + '</a>';
					} else {
						version = '<a title="Version history" href="/' + 'Version_history#' + version + '">' + version + '</a>';
					}
					
					var rows;
					if ( text.match( /<td>/g ) ) {
						rows = text.match( /<td>/g ).length + 1;
					} else {
						rows = 1;
					}
					rowspan += rows;
					data.push( '<th rowspan="' + rows + '">' + version + '</th><td>' + text );
				} );
				
				var html = '<tr class="details"><th rowspan="' + rowspan + '">' + header.find( '> th' ).html() + '</th>' + data.join( '<tr class="details">' );
				$( '<table>' + html + '</table>' ).find( 'td > ol' ).each( function() {
					var text = $( this ).html();
					html = html.split( '<ol>' + text + '</ol>' ).join( '<ul>' + text + '</ul>' );
				} );
				
				row.after( html );
			} );
			
			$( '.history2 .overview' ).hide();
		}
		
		if ( histLink.text() === histExpandText) {
			histLink.text( histCollapseText );
		} else {
			histLink.text( histExpandText );
		}
	} );
}*/

/**
 * Issue tracker loader
 */
/**if ( $( '#issue-list' ).length ) {
	var page = $( '#issue-list' ).data( 'name' ) || mw.config.get( 'wgPageName' ),
		amount = $( '#issue-list' ).data( 'num' ) || 20;
	
	if ( $.isArray( page ) ) {
		page = page.join( '" OR summary ~ "' );
	}
	
	var jql = encodeURIComponent( 'project in (MC, MCPE) AND resolution = Unresolved AND ( summary ~ "' + page + '" )' );
		
	
	$.ajax( 
		'https://mojang.atlassian.net/rest/api/latest/search?maxResults=' + amount + '&fields=summary&jql=' + jql
	).done( function( search ) {
		if ( !search.issues.length ) {
			$( '#issue-list' ).text( 'No issues were found.' );
			return false;
		}

		var compIssues = [], pocketIssues = [];
		$.each( search.issues, function() {
			if ( this.key.indexOf( 'MCPE' ) < 0 ) {
				compIssues.push( '<li>[<a href="https://mojang.atlassian.net/browse/' + this.key + '">' + this.key + '</a>] - ' + this.fields.summary + '</li>' );
			} else {
				pocketIssues.push( '<li>[<a href="https://mojang.atlassian.net/browse/' + this.key + '">' + this.key + '</a>] - ' + this.fields.summary + '</li>' );
			}
		} );
		
		var html = '';
		if ( compIssues.length ) {
			html = '<p><b>Computer:</b></p><ul>' + compIssues.join( '\n' ) + '</ul>';
		}
		if ( pocketIssues.length ) {
			html += '\n<p><b>Pocket Edition:</b></p><ul>' + pocketIssues.join( '\n' ) + '</ul>';
		}
		
		if ( search.total > amount ) {
			var extra = search.total - amount;
			html += '\n<p><a href="https://mojang.atlassian.net/issues/?jql=' + jql + '">View ' + extra + ' more result';
			
			if ( extra > 1 ) {
				html += 's';
			}
			
			html += '</a></p>';
		}

		$( '#issue-list' ).html( html );
	} );
}
*/


/**
 * Set unlicensed as the default license on file pages
 *
 * That way the file will be categorised so someone can find a license for the file
 */
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Upload' ) {
	if ( $( '#wpLicense' ).val() === '' ) {
		$( '#wpLicense' ).val( mcw.i18n.defaultLicense );
	}
	
	mw.loader.using( 'mediawiki.legacy.upload', function() {
		var change = setInterval( function() {
			if ( licenseSelectorCheck ) {
				$( '#wpLicense' ).change();
				clearInterval( change );
			}
		}, 500 );
	} );
}


/**
 * Creates minecraft style tooltips
 *
 * Replaces normal tooltips. Supports minecraft [[formatting codes]] (except k), and a description with line breaks (/).
 * Use mcw.useNativeMinetip = true to use normal tooltips, with the description added
 */
mcw.minetip = {
	// Add normal minetip events, removing legacy tooltip
	create: function() {
		var tooltip;
		
		$( '#mw-content-text' ).on( {
			'mouseenter.minetip': function( e ) {
				var $elem = $( this ),
					title = $elem.data( 'minetip-title' ),
					description = $elem.data( 'minetip-text' );
				
				// No title or title only contains formatting codes
				if ( title === undefined || title && title.replace( /&([0-9a-fl-o])|\s+/g, '' ) === '' ) {
					// Use title attribute of the element or the first link directly under it
					var attrTitle = $elem.attr( 'title' ) || $elem.find( '> a:first' ).attr( 'title' );
					if ( title === undefined ) {
						title = attrTitle;
					} else {
						title += attrTitle;
					}
					
					if ( title ) {
						// Set the retrieved title as data for future use
						$elem.data( 'minetip-title', title );
					} else {
						return;
					}
				}
				
				$elem.add( '*', $elem ).filter( '[title]' ).removeAttr( 'title' );
				
				if ( title === 0 ) {
					return;
				}
				
				var text = '<span class="title">' + title + '&f</span>';
				if ( description ) {
					text += '\n<span class="description">' +
						description.replace( /\\\//g, '&#47;' ).replace( /\//g, '<br>' ) +
						'&f</span>';
				}
				
				if ( !$( '#minetip-tooltip' ).length ) {
					$( 'body' ).append( '<div id="minetip-tooltip"/>' );
				}
				tooltip = $( '#minetip-tooltip' );
				
				// Add classes for minecraft formatting codes
				while ( text.match( /&[0-9a-el-o]/ ) ) {
					text = text.replace( /&([0-9a-el-o])(.*?)(&f|$)/g, '<span class="format-$1">$2</span>&f' );
				}
				// Remove reset formatting
				text = text.replace( /&f/g, '' );
				
				tooltip.html( text );
				
				// 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;
				
				var top = e.clientY - 34,
					left = e.clientX + 14,
					width = tooltip.outerWidth( true ),
					height = tooltip.outerHeight( true ),
					
					$win = $( window ),
					winWidth = $win.width(),
					winHeight = $win.height();
				
				// 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 below the cursor
				if ( left < 0 ) {
					left = 0;
					top += 82;
					
					// Go above the cursor if too low
					if ( top + height > winHeight ) {
						top -= 77 + height;
					}
				// 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 .image, .grid .item, .grid2 .item' ).off( '.minetipNative' );
	},
	// Remove all events
	destroy: function() {
		$( '#mw-content-text' ).off( '.minetip .minetipNative' );
		$( '#minetip-tooltip' ).remove();
	},
	// Add native browser tooltip events, removing normal minetip
	native: function() {
		$( '#mw-content-text' ).on( 'mouseenter.minetipNative', '.minetip, .grid .image, .grid .item, .grid2 .item', function() {
			var title = $( this ).data( 'minetip-title' ),
				description = $( this ).data( 'minetip-text' ),
				existingTitle = $( this ).attr( 'title' ) || $( this ).find( '> a:first' ).attr( 'title' );
			
			if ( title || title === 0 || $( this ).attr( 'title' ) ) {
				// Remove titles within so they don't interfere
				$( this ).find( '[title]' ).removeAttr( 'title' );
			}
			
			if ( title === 0 ) {
				$( this ).removeAttr( 'title' );
				return;
			} else if ( !title && ( !existingTitle || !description ) ) {
				return;
			} else if ( !title && existingTitle ) {
				$( this ).data( 'minetip-title', existingTitle );
			}
			
			var text = title || existingTitle;
			if ( description ) {
				text += '\n' + description;
			}
			
			// Remove formatting
			text = text.replace( /&([0-9a-fl-o])/g, '' )
				.replace( /\\\//g, '&#47;' )
				.replace( /\//g, '\n' )
				.replace( /&#47;/g, '/' );
			
			$( this ).attr( 'title', text );
		} ).off( '.minetip' );
	}
};

if ( mcw.useNativeMinetip ) {
	mcw.minetip.native();
} else {
	mcw.minetip.create();
}


} );
} )();