User:Mr. Stradivarius/gadgets/ConfirmRollback.js

// /*                           ConfirmRollback * * This script allows you to customise your rollback links. You can either * allow them, hide them, or ask for confirmation when you click them. * Furthermore, you can have different rollback settings for different pages, * and different settings for mobile and desktop devices. * * To install, add the following to your Special:MyPage/skin.js:

importScript('User:Mr. Stradivarius/gadgets/ConfirmRollback.js') // Linkback: User:Mr. Stradivarius/gadgets/ConfirmRollback.js

* See User:Mr. Stradivarius/gadgets/ConfirmRollback for documentation. */

mw.loader.using( [ 'oojs-ui' ], function {	"use strict";

// Get a rollback status of either "hide", "confirm" or "allow" for a given // page type and device type. function getRollbackStatus ( pageType, deviceType ) { var defaultConfig = { desktop: { watchlist: 'confirm', contributions: 'allow', recentchanges: 'allow', relatedchanges: 'allow', history: 'allow', diff: 'allow' },			mobile: { watchlist: 'confirm', contributions: 'confirm', recentchanges: 'confirm', relatedchanges: 'confirm', history: 'confirm', diff: 'confirm' }		};		var scriptConfig = window.ConfirmRollback || {}; var deviceDefaults = defaultConfig[ deviceType ];

function resolveRollbackStatus ( cfg ) { // resolve the config object recursively. We need to be recursive // because the config syntax is very flexible. var ret; if ( typeof( cfg ) === 'object' ) { if ( cfg.mobile || cfg.desktop ) { return resolveRollbackStatus( cfg[ deviceType ] ); } else { ret = cfg[ pageType ]; }			} else if ( cfg === 'hide' || cfg === 'allow' || cfg === 'confirm' ) { ret = cfg; }			return ret || deviceDefaults[ pageType ] || 'confirm'; }

return resolveRollbackStatus( scriptConfig ); }

// Makes the message that says something like // "Revert 5 edits by Mr. Stradivarius?" function makeRollbackMessage( event ) { var targetText = $( event.target ).text; var count = targetText.match(/\d/) ? targetText.match(/\d+/)[0] : null; var edits = count ? count + ' edits' : 'edit'; var user = mw.util.getParamValue( 'from', event.target.href ); return 'Roll back ' + edits + ' by ' + user + '?'; }

// Handles rollback clicks on mobile devices. This uses the default browser // window.confirm dialog, as OO-js UI windows on mobile are tiny and // unreadable. function handleMobileClicks( $rollbackLinks ) { $rollbackLinks.click( function ( event ) {			var message = makeRollbackMessage( event );			if ( !confirm( message ) ) {				return event.preventDefault;			}		} ); }

// Handle rollback clicks on desktop. This uses OO-js UI, which looks // pretty on desktops. function handleDesktopClicks( $rollbackLinks ) { // Initialize the dialog object. var confirmationDialog = new OO.ui.MessageDialog; var windowManager = new OO.ui.WindowManager; $( 'body' ).append( windowManager.$element ); windowManager.addWindows( [ confirmationDialog ] );

$rollbackLinks.click( function ( event ) {			event.preventDefault;			var message = makeRollbackMessage( event );			windowManager.openWindow( confirmationDialog, { title: 'Confirm rollback', message: message, actions: [ { action: 'rollback', label: 'OK', flags: [ 'primary', 'destructive' ] }, { label: 'Cancel' } ]			} ).then( function ( opening ) { opening.then( function ( opened ) {					opening.then( function ( closing, data ) { // The dialog is open. Check for the rollback action // and if detected, follow the original rollback link // URL. if ( data && data.action === 'rollback' ) { window.open( $( event.target ).attr( 'href' ), '_top' ); }					} );				} );			} );		} );	}

var pageType, deviceType, rollbackStatus, $rollbackLinks; var mwConfig = mw.config.get( ['wgCanonicalSpecialPageName', 'wgAction'] );

// Find the page type, and exit if we are not viewing a page on which // rollback links can appear. if ( mwConfig.wgCanonicalSpecialPageName === 'Watchlist' ) { pageType = 'watchlist'; } else if ( mwConfig.wgCanonicalSpecialPageName === 'Contributions' ) { pageType = 'contributions'; } else if ( mwConfig.wgCanonicalSpecialPageName === 'Recentchanges' ) { pageType = 'recentchanges'; } else if ( mwConfig.wgCanonicalSpecialPageName === 'Recentchangeslinked' ) { pageType = 'relatedchanges'; } else if ( mwConfig.wgAction === 'history' ) { pageType = 'history'; } else if ( $( location ).attr( 'href' ).indexOf( '&diff' ) !== -1 ) { pageType = 'diff'; } else { return; }

deviceType = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ? 'mobile' : 'desktop'; rollbackStatus = getRollbackStatus( pageType, deviceType ); $rollbackLinks = $( '.mw-rollback-link' );

if ( rollbackStatus === 'hide' ) { $rollbackLinks.css( 'display', 'none' ); } else if ( rollbackStatus === 'allow' ) { $rollbackLinks.css( 'display', 'inline' ); } else if ( rollbackStatus === 'confirm' ) { // Display rollback links if they are hidden. $rollbackLinks.css( 'display', 'inline' ); // Handle rollback clicks. if ( deviceType === 'mobile' ) { handleMobileClicks( $rollbackLinks ); } else { handleDesktopClicks( $rollbackLinks ); }	} } );

//