User:Peter Bowman/bot-rollback.js

From Meta, a Wikimedia project coordination wiki

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

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * Add rollback buttons with 'markbot' functionality. Based on
 * mediawiki.page.rollback module from MW core.
 *
 * @author Peter Bowman
 */
( function ( mw, $ ) {
	mw.hook( 'wikipage.content' ).add( function ( $content ) {
		var api,
			$rollbackLinks = $content.find( '.mw-rollback-link' );
		
		if ( !$rollbackLinks.length ) {
			return;
		}
		
		mw.loader.using( [
			'mediawiki.util',
			'mediawiki.user',
			'mediawiki.api',
			'jquery.spinner'
		] )
		.then( function ( require ) {
			api = new mw.Api( { parameters: {
				errorformat: 'html',
				errorlang: mw.config.get( 'wgUserLanguage' ),
				errorsuselocal: true
			} } );
			
			return mw.user.getRights();
		} )
		.then( function ( rights ) {
			if ( rights.indexOf( 'markbotedits' ) === -1 ) {
				return $.Deferred().reject();
			}
			
			return api.loadMessagesIfMissing( [ 'actioncomplete', 'rollbackfailed' ] );
		} )
		.done( function () {
			var isDiff = !!mw.util.getParamValue( 'diff' ),
				isHistory = mw.config.get( 'wgAction' ) === 'history',
				isContribs = mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Contributions';
			
			$rollbackLinks.each( function () {
				var $spinner, $container,
					$this = $( this ),
					$link = $this.find( 'a' ).first().clone(),
					url = $link.attr( 'href' ) + '&bot=1',
					page = mw.util.getParamValue( 'title', url ),
					user = mw.util.getParamValue( 'from', url );
				
				if ( mw.user.options.get( 'norollbackdiff' ) ) {
					url += '&hidediff=1';
				}
				
				$link.text( 'mb' ).attr( 'href', url );
				
				$container = $( '<span>' )
					.addClass( 'bot-rollback-link' )
					.append( $link );
				
				if ( isDiff || isContribs ) {
					mw.util.addCSS( [
						'.bot-rollback-link::before { content: "[" }',
						'.bot-rollback-link::after { content: "]" }'
					].join( '' ) );
					
					$this.after( ' ', $container );
				} else if ( isHistory ) {
					$container = $( '<span>' ).append( $container ).insertAfter( $this.parent() );
				}
				
				$link.one( 'click', function ( e ) {
					if ( !page || !user ) {
						// Let native browsing handle the link
						return true;
					}

					// Hide the link and create a spinner to show it inside the brackets.
					$spinner = $.createSpinner( { size: 'small', type: 'inline' } );
					$link.hide().after( $spinner );

					api.rollback( page, user, { markbot: true } )
						.then( function ( data ) {
							mw.notify( $.parseHTML( data.messageHtml ), {
								title: mw.msg( 'actioncomplete' )
							} );

							$this.remove();
							$container.remove();
						}, function ( errorCode, data ) {
							mw.notify( api.getErrorMessage( data ), {
								type: errorCode === 'alreadyrolled' ? 'warn' : 'error',
								title: mw.msg( 'rollbackfailed' ),
								autoHide: false
							} );

							// Restore the link (enables user to try again)
							$spinner.remove();
							$link.show();
						} );

					e.preventDefault();
				} );
			} );
		} );
	} );
}( mediaWiki, jQuery ) );