Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/**
* Ajax Undo links
*
* Adds Ajax undo links (with and without summary prompt) next to the normal undo or rollback link
* on page histories, on diff pages and on contributions pages
* Rewritten in 2018-08 by Perhelion
**/
/* global $:false, mw:false */

(function () {
'use strict';

var summary = null;
function doUndo(diffUndoUrl, self) {
	var	$ajaxUndoLinkob = $(self).html($.createSpinner()),
		undoId = mw.util.getParamValue('undo', diffUndoUrl),
		pageName = mw.util.getParamValue('title', diffUndoUrl),
		success = function (data, e) {
			console.log(data, e);
			if (data.edit && data.edit.result === 'Success') {
				// if (typeof data.edit.nochange === 'string') nothing changed
				 if ((e = $ajaxUndoLinkob.parent('span')).length)
				 	$ajaxUndoLinkob = e;
				$ajaxUndoLinkob.text('(undone)').off('click').css('color', 'green');
			} else if (data.error && data.error.code === 'undofailure') { fault(data.error.code, data); } else { fault(data, e, 'Error: Unknown result from API.'); }
		},
		fault = function (r, e) {
			mw.loader.using([], function () {
				mw.log.warn(r, e);
				$ajaxUndoLinkob.text('(error)').addClass('error');
				e = (e.error && typeof e.error.code === 'string') ? e.error : e;
				mw.notify(e.info, { title: r, type: 'warn' });
			});
		},
		data = {
			action: 'edit',
			title: pageName,
			minor: 1,
			bot: 1,
			undo: undoId
		};
	if (summary && summary.length) data.summary = 'Undo revision ' + undoId + ' ' + summary;
	new mw.Api().postWithEditToken(data).done(success).fail(fault);
}
function createUndoLink(diffUndoUrl) {
	var $undoLink = $('<a>', { title: diffUndoUrl } ).text('AjaxUndo').on('click', function (e) {
		e.preventDefault();
		e = this;
		if (e.textContent !== 'AjaxUndo') {
			summary = window.prompt('Enter optional summary', '');
			if (summary === null) return; // break
		}
		mw.loader.using(['mediawiki.api', 'mediawiki.util', 'jquery.spinner'],
			function () { doUndo(diffUndoUrl, e); }
		);
	});
	return [$undoLink, ' - ', $undoLink.clone(true).text('with\u00A0summary')];
}
$(function () {
	var $undoLinks, $diffUndoLink;
	if (mw.config.get('wgAction') === 'history' && ($undoLinks = $('.mw-history-undo:first')).length) {
		$undoLinks.find('a').each(function () {
			var $ajaxUndoLink = createUndoLink(this.href);
			$(this).parent().after(' | ', $ajaxUndoLink);
		});
	} else if (mw.config.get('wgCanonicalSpecialPageName') === 'Contributions' && ($undoLinks = $('ul.mw-contributions-list')).length) {
		$undoLinks = $undoLinks.find('.mw-tag-mw-rollback'); // li
		$undoLinks.each(function () {
			var $li = $(this),
				$UndoLink = $li.find('.mw-rollback-link > a'),
				$ajaxUndoLink = createUndoLink($UndoLink.attr('href') + '&undo=' + $li.attr('data-mw-revid'));
			$UndoLink.after(' | ', $ajaxUndoLink);
		});
	} else if (/\bdiff=/.test(window.location.search) && ($diffUndoLink = $('table.diff')).length) {
		$diffUndoLink = $diffUndoLink.find('.diff-ntitle > #mw-diff-ntitle1 a:last');
		var diffUndoUrl = $diffUndoLink.attr('href'),
			$ajaxDiffUndoLink = createUndoLink(diffUndoUrl);
		$diffUndoLink.parent().append(' (', $ajaxDiffUndoLink, ')');
	}
});
}());