MediaWiki:Common.js

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

/** * Extra toolbar options * * Description: Adds extra buttons to the editing toolbar. * Due to the way this works, it has to be loaded before the * toolbar loads (so it can't be in the onload function). *  * Maintainers: wikipedia:User:MarkS, wikipedia:User:Voice of All, wikipedia:User:R. Koot */ var buttons = ;

$.each( buttons, function { mwCustomEditButtons.push( this ); } );

$( function { 'use strict';

/** * Collapsible tables * * Based on http://www.mediawiki.org/wiki/Manual:Collapsible_tables#Common.js_script_.28before_1.18.29 * * @maintainers User:Ultradude25 */ if ( $( 'table.collapsible' ).length ) { var collapseText = 'Collapse', expandText = 'Expand', collapseButton, buttonText = ' [ ' + collapseText + ' ] '; $( 'table.collapsible' ).each( function {       var table = $( this ), header;        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 );        }        collapseButton.click( function( e ) { // Stop table sorting activating when clicking link e.stopPropagation; if ( table.hasClass( 'collapsed' ) ) { table.removeClass( 'collapsed' ).addClass( 'expanded' ); $( this ).text( collapseText ); } else { table.removeClass( 'expanded' ).addClass( 'collapsed' ); $( this ).text( expandText ); }       } );    } ); }

/** * 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 (used in Template:Grid) * * Will cycle the active class on any child elements within an element with the animated class. */ if ( $( '.animated' ).length ) { 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 ); }

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

/** * 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 baseURL = '/', loadText = 'Load content', showText = 'Expand content', hideText = 'Collapse content';

$( '.load-page' ).find( '.mw-headline:first' ).append( ' [ ' + loadText + ' ] ' );

$( '.load-page-button > .jslink' ).live( 'click', function {   var $this = $( this ), $body = $this.closest( '.load-page' ), $content = $body.find( '.load-page-content' );    if ( $body.hasClass( 'loading' ) ) {        return;    }    if ( $this.text === loadText ) {        $body.addClass( 'loading' );        $( 'body' ).css( 'cursor', 'wait' );        $.ajax( { url: baseURL + 'api.php?format=json&action=parse&prop=text&redirects=1&page=' + mw.util.wikiUrlencode( $body.data( 'page' ) ), dataType: 'json', timeout: 20000 } ).done( function( data ) { if ( data.error ) { if ( $( '#error-dialog' ).length ) { return; }               mw.loader.using( 'jquery.ui.dialog', function {                    $body.removeClass( 'loading' );                    $( 'body' ).css( 'cursor', 'auto' );                    $( '#netbar' ).after( ' ' );                    $( '#error-dialog' ).html( ' Error: ' + data.error.info + ' ' ).dialog( { title: 'Hey! Listen!', resizable: false, width: 400, modal: true, buttons: { 'Retry': function { $this.click; $( this ).dialog( 'destroy' ); $( '#error-dialog' ).remove; },                           Cancel: function { $( this ).dialog( 'destroy' ); $( '#error-dialog' ).remove; return; }                       }                    } );                } );                return; }           $content.html( data.parse.text['*'] ); $this.text( hideText ); $body.removeClass( 'loading' ); $( 'body' ).css( 'cursor', 'auto' ); } ).fail( function( error ) { if ( $( '#error-dialog' ).length ) { return; }           mw.loader.using( 'jquery.ui.dialog', function {                $body.removeClass( 'loading' );                $( 'body' ).css( 'cursor', 'auto' );                $( '#netbar' ).after( ' ' );                if ( !error.responseText ){                    $( '#error-dialog' ).html( ' Error: No response from the server ' );                } else {                    $( '#error-dialog' ).html( ' Error: ' + error.responseText + ' ' );                }                $( '#error-dialog' ).dialog( { title: 'Hey! Listen!', resizable: false, width: 400, modal: true, buttons: { 'Retry': function { $this.click; $( this ).dialog( 'destroy' ); $( '#error-dialog' ).remove; },                       Cancel: function { $( this ).dialog( 'destroy' ); $( '#error-dialog' ).remove; return; }                   }                } );            } );        } );    } else if ( $this.text === showText ) {        $content.show;        $this.text( hideText );    } else {        $content.hide;        $this.text( showText );    } } );

/** * Frame parser (for Template:Grid) * * Requests the urls for all the animated grids on a page in 2 * API requests (due to a bug, 1 API request when it is fixed) * and appends them to the correct location. */ var baseURL = '/', wikiURL = '/wiki/', $grids = $( '.grid' ), titles = [], titleCount = 0, section = 0; if ( $grids.length ) { $grids.each( function {       var imgs = $( this ).data( 'imgs' ), mod = $( this ).data( 'mod' );        if ( !imgs ) {            return true;        }        imgs = imgs.split( ';' );        imgs.shift;        $.each( imgs, function { if ( !this.trim ) { return true; }           if ( titleCount === 50 ) { titleCount = 0; section++; }           if ( !titles[section] ) { titles[section] = ''; }           if ( this.indexOf( ':' ) > -1 ) { this.replace( /([^:]*):?([^,]*)/, function( $, mod, name ) {                   if ( mod.trim.toLowerCase === 'v' || mod.trim.toLowerCase === 'vanilla' ) {                        if ( titles[section].indexOf( 'File:Grid ' + name.trim + '.png' ) < 0 ) {                            titles[section] += 'File:Grid ' + name.trim + '.png|';                            titleCount++;                        }                    } else {                        if ( titles[section].indexOf( 'File:Grid ' + name.trim + ' (' + mod.trim + ').png' ) < 0 ) {                            titles[section] += 'File:Grid ' + name.trim + ' (' + mod.trim + ').png|';                            titleCount++;                        }                    }                } ); } else { this.replace( /([^,]*)/, function( $, name ) {                   if ( !mod || mod.trim.toLowerCase === 'v' || mod.trim.toLowerCase === 'vanilla' ) {                        if ( titles[section].indexOf( 'File:Grid ' + name.trim + '.png' ) < 0 ) {                            titles[section] += 'File:Grid ' + name.trim + '.png|';                            titleCount++;                        }                    } else {                        if ( titles[section].indexOf( 'File:Grid ' + name.trim + ' (' + mod.trim + ').png' ) < 0 ) {                            titles[section] += 'File:Grid ' + name.trim + ' (' + mod.trim + ').png|';                            titleCount++;                        }                    }                } ); }       } );    } );    /* 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... */   if ( titles ) { var promise = [], redirects = {}, urls = {}; $.each( titles, function( index ) {           var titleSection = this.slice( 0, -1 );            promise.push( $.ajax( {                   type: 'POST',                    url: baseURL + 'api.php?action=query&format=json&redirects',                    data: { titles: titleSection },                    timeout: 20000                } ).done( function( data ) {                    if ( data.query.redirects ) {                        $.each( data.query.redirects, function { redirects[this.to] = this.from; titles[index] = titles[index].replace( this.from, this.to ); } );                   }                } ).fail( function( error ) {                    console.error( error );                } ) );       } );        $.when.apply( $, promise ).then( function {            promise.length = 0;            $.each( titles, function { var titles = this.slice( 0, -1 ); promise.push(                   $.ajax( { type: 'POST', url: baseURL + 'api.php?action=query&format=json&prop=imageinfo&iiprop=url&iiurlwidth=32&iiurlheight=32', data: { titles: titles }, timeout: 20000 } ).done( function( data ) { $.each( data.query.pages, function( index ) {                           if ( index < 0 ) {                                return true;                            }                            if ( redirects.hasOwnProperty( this.title ) ) {                                urls = this.imageinfo[0].thumburl;                            } else {                                urls = this.imageinfo[0].thumburl;                            }                        } ); } ).fail( function( error ) { console.error( error ); } )               );            } );            $.when.apply( $, promise ).then( function { $grids.each( function {                   var $grid = $( this ), imgs = $grid.data( 'imgs' ), mod = $( this ).data( 'mod' ), html = '';                    if ( !imgs ) {                        return true;                    }                    imgs = imgs.split( ';' );                    imgs.shift;                    $.each( imgs, function { if ( !this.trim ) { html += gridFormat; return true; }                       if ( this.indexOf( ':' ) > -1 ) { this.replace( /([^:]*):?([^,]*),?(\d*)/, function( $, mod, name, num ) {                               if ( mod.trim.toLowerCase === 'v' || mod.trim.toLowerCase === 'vanilla' ) {                                    html += gridFormat( name.trim, name.trim, urls[name.trim], num );                                } else {                                    var img = name.trim + ' (' + mod.trim + ')';                                    html += gridFormat( img, 'Mods/' + mod.trim + '/' + name.trim,  urls[img], num );                                }                            } ); } else { this.replace( /([^,]*),?(\d*)/, function( $, name, num ) {                               if ( !mod || mod.trim.toLowerCase === 'v' || mod.trim.toLowerCase === 'vanilla' ) {                                    html += gridFormat( name.trim, name.trim, urls[name.trim], num );                                } else {                                    var img = name.trim + ' (' + mod.trim + ')';                                    html += gridFormat( img, 'Mods/' + mod.trim + '/' + name.trim,  urls[img], num );                                }                            } ); }                   } );                    $grid.find( '> .border > span > .animated' ).append( html );                } ); } );       } );    } }

function gridFormat( name, link, url, num ) { var html = ' '; if ( name ) { if ( url ) { html += ''; if ( num ) { html += ' ' + num + ' '; }       } else { html += ''; }   } else { html += ' '; }   return html += ' '; }

/** * Fix missing toolbar images */ $( '#mw-editbutton-bold' )    .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/e/e2/Button_bold.png' ); $( '#mw-editbutton-italic' )  .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/1/1d/Button_italic.png' ); $( '#mw-editbutton-link' )    .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/c/c0/Button_link.png' ); $( '#mw-editbutton-extlink' ) .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/e/ec/Button_extlink.png' ); $( '#mw-editbutton-headline' ) .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/f/fb/Button_headline.png' ); $( '#mw-editbutton-image' )   .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/d/de/Button_image.png' ); $( '#mw-editbutton-media' )   .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/1/19/Button_media.png' ); $( '#mw-editbutton-nowiki' )  .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/8/82/Nowiki_icon.png' ); $( '#mw-editbutton-signature' ).prop( 'src', '//upload.wikimedia.org/wikipedia/commons/6/6d/Button_sig.png' ); $( '#mw-editbutton-hr' )      .prop( 'src', '//upload.wikimedia.org/wikipedia/commons/0/0d/Button_hr.png' );

} );