ميډياويکي:Gadget-FastRollback.js

د ويکيسيند لخوا

يادښت: د غوره توبونو د خوندي کولو وروسته، خپل د کتنمل (بروزر) ساتل شوې حافظه تازه کړی.

  • فايرفاکس/ سفري: په دې کتنمل کې د Reload د ټکوهلو په وخت د Shift تڼۍ نيولې وساتی، او يا هم Ctrl-F5 يا Ctrl-Rتڼۍ کېښکاږۍ (په Apple Mac کمپيوټر باندې ⌘-R کېښکاږۍ)
  • گووگل کروم: په دې کتنمل کې د Ctrl-Shift-R تڼۍ کېښکاږۍ (د مک لپاره ⌘-Shift-R)
  • انټرنټ اېکسپلورر: په دې کتنمل کې د Refresh د ټکوهلو په وخت کې د Ctrl تڼۍ کېښکاږلې ونيسۍ، او يا هم د Ctrl-F5 تڼۍ کېښکاږۍ
  • اوپرا: په دې کتنمل کې د خپل براوزر ساتل شوې حافظه پدې توگه سپينولی شی Tools→Preferences
/*jshint undef:true, latedef:true, undef:true, shadow:true, scripturl:true */
/*global mw, jQuery */
(function () {
	
var api = new mw.Api();
	
function processLink(link, title, token, user, markbot) {
	var wrapper = link.parentNode;
	var bracketed = (wrapper.textContent[0] === '[');
	
	link.addEventListener('click', function (ev) {
		ev.preventDefault();

		var summary = prompt('About to rollback edits by [[User:' + user + ']] to [[' + title + ']].\n\nEdit summary (empty for default):',
			'Reverted edits by [[Special:Contributions/' + user + '|' + user + ']]. If you think this rollback is in error, please leave a message on my [[User talk:' + mw.config.get('wgUserName') + '|talk page]].');
		if (summary === null)
			return;
		
		wrapper.textContent = bracketed ? '[wait]' : 'wait';
		api.post({
			action: 'rollback',
			title: title,
			user: user,
			token: token,
			markbot: markbot ? '1' : void(0),
			summary: summary ? summary : void(0)
		}).then(function (result) {
			var diffLink = document.createElement('a');
			diffLink.href = mw.config.get('wgScript') + '?diff=' + result.rollback.revid + '&diffonly=1';
			diffLink.textContent = 'diff';
			
			var reloadLink = document.createElement('a');
			reloadLink.href = 'javascript:location.reload();';
			reloadLink.textContent = 'reload';
			
			wrapper.textContent = '';
			if (bracketed) wrapper.appendChild(document.createTextNode('['));
			wrapper.appendChild(document.createTextNode('done: '));
			wrapper.appendChild(diffLink);
			wrapper.appendChild(document.createTextNode(' | '));
			wrapper.appendChild(reloadLink);
			if (bracketed) wrapper.appendChild(document.createTextNode(']'));
		}, function (code, result, xhr) {
			link.textContent = 'retry';
			
			var cnode = document.createElement('code');
			cnode.style.borderBottom = '1px dotted black';
			cnode.style.cursor = 'help';
			
			cnode.textContent = code;
			switch (code) {
			case 'http':
				cnode.title = 'HTTP error: ' + result.textStatus;
				break;
			case 'ok-but-empty':
				cnode.title = 'Received empty response from the server';
				break;
			default:
				cnode.title = result.error.info;
			}

			wrapper.textContent = '';
			if (bracketed) wrapper.appendChild(document.createTextNode('['));
			wrapper.appendChild(document.createTextNode('error: '));
			wrapper.appendChild(cnode);
			wrapper.appendChild(document.createTextNode(' ('));
			wrapper.appendChild(link);
			wrapper.appendChild(document.createTextNode(')'));
			if (bracketed) wrapper.appendChild(document.createTextNode(']'));

			console.error(result);
		});
	}, false);
}
	
jQuery(document).ready(function() {

var rolllinks = document.getElementsByClassName('mw-rollback-link');

for (var i = 0; i < rolllinks.length; ++i) {
	var links = rolllinks[i].getElementsByTagName('a');
	if (links.length !== 1)
		continue;
	var link = links[0];
	try {
		var uri = new mw.Uri(link.href);
		if (uri.query.action === 'rollback')
			processLink(link, uri.query.title, uri.query.token, uri.query.from, uri.query.bot && true);
	} catch (e) {
		/* swallow */
	}
}

function makeRestoreLink(oldid, uname) {
	var link = document.createElement('a');
	var span = document.createElement('span');
	link.href = mw.config.get('wgScript') + '?action=edit&oldid=' + oldid;

	function doRestore() {
		function showError(action, code, result) {
			var cnode = document.createElement('code');
			cnode.textContent = code;
			switch (code) {
			case 'http':
				cnode.title = 'HTTP error: ' + result.textStatus;
				break;
			case 'ok-but-empty':
				cnode.title = 'Received empty response from the server';
				break;
			case 'edit-failure':
				cnode.textContent = result.edit.code;
				cnode.title = 'Edit error: ' + result.edit.info;
				break;
			default:
				cnode.title = result.error.info;
			}

			var retryLink = document.createElement('a');
			retryLink.href = link.href;
			retryLink.textContent = 'retry';
			retryLink.addEventListener('click', function (ev) {
				ev.preventDefault();
				doRestore();
			}, false);

			span.textContent = '';
			span.appendChild(document.createTextNode('error: '));
			span.appendChild(cnode);
			span.appendChild(document.createTextNode(' ('));
			span.appendChild(retryLink);
			span.appendChild(document.createTextNode(')'));
		}

		var summary = prompt('Edit summary for this reversion:', 'Restored revision ' + oldid + ' by [[User:' + uname + ']]');
		if (summary === null)
			return;

		span.textContent = 'grabbing oldid';
		if (link.parentNode) {
			link.parentNode.insertBefore(span, link);
			link.parentNode.removeChild(link);
		}

		api.get({
			action: 'query',
			pageids: mw.config.get('wgArticleId'),
			prop: 'revisions',
			rvstartid: oldid,
			rvlimit: 1,
			rvprop: 'content'
		}).then(function (result, xhr) {
			console.info(result);
			var starttimestamp = (new Date(xhr.getResponseHeader('Date'))).toISOString(); // XXX: acceptable?
			var content = result.query.pages[mw.config.get('wgArticleId')].revisions[0]['*'];

			span.textContent = 'grabbing latest revision';
			api.get({
				action: 'query',
				pageids: mw.config.get('wgArticleId'),
				prop: 'revisions',
				rvlimit: 1,
				rvprop: 'ids|timestamp'
			}).then(function (result) {
				console.info(result);
				var basetimestamp = result.query.pages[mw.config.get('wgArticleId')].revisions[0].timestamp;
				if (result.query.pages[mw.config.get('wgArticleId')].revisions[0].revid === Number(oldid)) {
					span.textContent = 'this is already the latest revision';
					return;
				}

				span.textContent = 'reverting';
				api.post({
					action: 'edit',
					pageid: mw.config.get('wgArticleId'),
					token: mw.user.tokens.get('csrfToken'),
					basetimestamp: basetimestamp,
					starttimestamp: starttimestamp,
					nocreate: '1',
					text: content,
					summary: summary
				}).then(function (result) {
					if (result.edit.result === 'Success') {
						span.textContent = 'done';
					} else {
						showError('saving', 'edit-failure', result);
					}
				}, function (code, result) {
					showError('saving', code, result);
				});
			}, function (code, result) {
				showError('grabbing latest revision data', code, result);
			});
		}, function (code, result) {
			showError('grabbing old revision text', code, result);
		});
	}

	link.addEventListener('click', function (ev) {
		ev.preventDefault();
		doRestore();
	}, false);

	return link;
}

// are we viewing an old revision?
var revnav = document.getElementById('mw-revision-nav');
if (revnav) {
	var uname = document.getElementById('mw-revision-info').getElementsByClassName('mw-userlink')[0].textContent;
	var oldid = mw.config.get('wgRevisionId'); // XXX: suppress if this is the latest revid

	var link = makeRestoreLink(oldid, uname);
	link.textContent = 'restore this version';

	revnav.appendChild(document.createTextNode(' ('));
	revnav.appendChild(link);
	revnav.appendChild(document.createTextNode(')'));
	return;
}

// intentionally not enabled on history pages;
// I want the user to see to what version they are reverting
// either directly or at least a diff
// may be changed on request, though

function addRestoreLink(titlenode) {
	if (!titlenode)
		return;

	var titlelinks = titlenode.getElementsByTagName('a');
	var userlink = titlenode.parentNode.getElementsByClassName('mw-userlink')[0];
	var uname = userlink.textContent;
	
	var uri = new mw.Uri(titlelinks[0].href);
	// XXX: suppress for latest revid
	var rlink = makeRestoreLink(uri.query.oldid, userlink.textContent);
	rlink.textContent = 'restore';
	titlelinks[1].parentNode.insertBefore(rlink, titlelinks[1].nextSibling);
	titlelinks[1].parentNode.insertBefore(document.createTextNode(' | '), titlelinks[1].nextSibling);
}

// are we viewing a diff?
var ot = document.getElementById('mw-diff-otitle1');
var nt = document.getElementById('mw-diff-ntitle1');
var ri = document.getElementById('mw-revision-info');
if ((nt || ot) && mw.config.get('wgArticleId')) {
	addRestoreLink(ot);
	addRestoreLink(nt);
} else if (ri && (mw.config.get('wgRevisionId') !== mw.config.get('wgCurRevisionId'))) {
	var userlink = ri.getElementsByClassName('mw-userlink')[0];
	var rlink = makeRestoreLink(mw.config.get('wgRevisionId'), userlink.textContent);
	rlink.textContent = 'restore';
	var fh = document.getElementById('firstHeading');
	var span = document.createElement('span');
	span.className = 'mw-editsection';
	span.appendChild(document.createTextNode('['));
	span.appendChild(rlink);
	span.appendChild(document.createTextNode(']'));
	fh.appendChild(span);
}

});

})();