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.
// <nowiki>
// This script was created when MediaWiki started to honour Exif orientation
// information. As a consequence, many files needed an Exif orientation reset.
// Allowed manually working on galleries populated by bot.

$(document).ready(function () {

var requestResetExif = function(anchor) {
	var $el = $(anchor);
	var file = $el.parent().data('reFile');
	
	$el.text('working...');
	
	var doEdit = function(result) {
		if (!result) return;
		text = result.replace(/\{\{rotate\|.+?\}\}/ig, '');
		
		if (text.length !== result.length) {
			// there was already a rotate-request; do not overwrite since users are easily upset these days
			addToDoneQueue(file, $el.parent().parent().parent());
			$el.fadeOut();
			return;
		}
		
		text = '{{rotate|resetexif}}\n' + text;
	
		var params = {
			action: 'edit',
			title: file,
			nocreate: 1,
			redirect: 1,
			summary: 'Correcting image orientation: Requesting Rotatebot to reset [[COM:EXIF#Orientation|EXIF Orientation]] as the image is physically in correct orientation.',
			text: text,
			token: (mw.user.tokens.get('csrfToken')),
			format: 'json'
		};
		
		editDone = function(editStat) {
			if (!editStat) return;
			if (editStat.error) {
				alert('Unable to tag file ' + file + '. Maybe reloading the page helps.\n' + result.error.code + '\n' + result.error.info);
				$el.text('Error!');
			} else {
				addToDoneQueue(file, $el.parent().parent().parent());
			}
			$el.fadeOut();
		}
		
		$.post(mw.util.wikiScript('api'), params, editDone);
	}
	$.ajax({
		url: mw.config.get('wgScript'),
		data: { 'action': 'raw', title: file.replace(/ /g, '_'), maxage: 0 },
		dataType: 'text',
		error: function() {
			$el.text('Error!');
		},
		success: doEdit,
		type: 'GET',
		cache: false
	});
}

$('.gallerybox').each(function(i, e) {
	try {
		$e = $(e);
		var file = decodeURIComponent($e.find('.thumb').find('a').attr('href').match(/\/(File:.+)$/i)[1].replace(/_/g, ' '));
		$e.find('.gallerytext').data('reFile', file).prepend($('<a>', { href: '#', text: '-Exif; -list' }).click(
			function(e) {
				e.preventDefault();
				requestResetExif(this);
			}
		), '; ',
		$('<a>', { href: '#', text: 'rm from list only' }).click(
			function(e) {
				e.preventDefault();
				$(this).fadeOut();
				addToDoneQueue($(this).parent().data('reFile'), $(this).parent().parent().parent());
			}
		), '<br/>');
	} catch (ex) {
	}
});

var doneQueue = [];
var DOMQueue = [];
var lastListPageContent = '';

var addToDoneQueue = function(file, domE) {
	if (sendingRequest) {
		setTimeout(function() {
			addToDoneQueue(file, domE);
		}, 1000);
		return;
	}
	doneQueue.push(file);
	DOMQueue.push(domE);
	reQueueNode.find('#queueCounter').text(doneQueue.length);
	if (doneQueue.length > 35) processDoneQueue();
}

var processing = false;
var sendingRequest = false;
var processDoneQueue = function() {
	if (processing) return;
	processing = true;
	var doRemove = function(pageText) {
		var l = doneQueue.length;
		sendingRequest = true; // Prevent adding further files to the list
		
		reQueueNode.find('#queueCounter').text("Processing..");
		
		if (lastListPageContent && lastListPageContent !== pageText) {
			reQueueNode.append('<br/>Warning! Someone else is working on the list.');
		}
		
		for (var i = 0; i < l; i++) {
			var file = doneQueue[i];
			file = file.replace('File:', '');
			var reFile = new RegExp( '\n' + $.escapeRE(file) + '\\|.+' );
			pageText = pageText.replace(reFile, '');
		}
		var params = {
			action: 'edit',
			title: mw.config.get('wgPageName'),
			nocreate: 1,
			redirect: 1,
			summary: 'Removing ' + doneQueue.length + ' files done from this list.',
			text: pageText,
			token: (mw.user.tokens.get('csrfToken')),
			format: 'json'
		};
		
		removalDone = function(editStat) {
			processing = false;
			sendingRequest = false;
			lastListPageContent = pageText;
			if (!editStat) return;
			if (editStat.error) {
				alert('Unable to remove done files from list. Maybe reloading the page helps.\n' + result.error.code + '\n' + result.error.info);
			} else {
				doneQueue = [];
				var l = DOMQueue.length;
				for (var i = 0; i < l; i++) {
					DOMQueue[i].fadeOut();
				}
				DOMQueue = [];
			}
			reQueueNode.find('#queueCounter').text(doneQueue.length);
		}
		$.post(mw.util.wikiScript('api'), params, removalDone);
		reQueueNode.find('#queueCounter').text("Processing...");
	}
	$.get(mw.config.get('wgScript'), { 'action': 'raw', title: mw.config.get('wgPageName') , dummy: Math.round(Math.random()*4294967296), maxage: 0 }, doRemove);
	reQueueNode.find('#queueCounter').text("Processing.");
}

var reQueueNode = $('<div>', { style: 'position:fixed; background: #efe; top: 30px; left: 30px; border:solid 2px #000; z-index:1005;' }).append(
	$('<span>', { id: 'queueCounter', text: '0' }), ' items in removal queue. ', $('<a>', { href: '#', text: 'remove from list now' }).click(function(e) {
		e.preventDefault();
		processDoneQueue();
	})
);

$('body').prepend(reQueueNode);

});

// </nowiki>