User:Rillke/forWikisource.js

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
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>
 * Purge link for Page-namespace of Wikisource
 * @description
 *  Adds a "Purge"-link to the "p-views"-menu.
 *  Clicking this link will post a purge-request to Commons and reloads the image
 * 
 * @compatibility
 *  Tested with recent versions of Firefox (works) Internet Explorer 8 (no cross-site-XHRs)
 *  NoScript and other extension/add-ons preventing cross-site-XHRs will prevent this script working properly
 *
 * Derived from [[:commons:MediaWiki:Gadgetprototype.js]]
 *
 * @rev 1 (2012-05-02)
 * @author Rillke, 2012
 * @license GPL v.3
 */

/*global jQuery:false, mediaWiki:false*/
/*jshint curly:false*/

(function($, mw) {
'use strict';

// Only run on page-pages (proofRead)
if (104 !== mw.config.get('wgNamespaceNumber')) return;

var prp = window.proofReadPurge = {
	fileNameFromImg: function($el) {
		try {
			return 'File:' + decodeURIComponent($el.attr('src')).match(/\/\S\/\S\S\/(\S+\.\S{2,5})\//)[1].replace(/_/g, ' ');
		} catch (ex) {
			try {
				return 'File:' + decodeURIComponent($el.attr('src')).match(/thumb\.php.*(?:\?|\&)f=(\S+\.\S{2,5})(?:\&.+)?$/)[1].replace(/_/g, ' ');
			} catch (ex2) {}
		}
	},
	setState: function(statusText) {
		this.$purgeLinkText.text(statusText);
	},
	purge: function() {
		// Set a time-threshold to detect browsers not actually sending the request 
		// due to same-domain-origin-enforcement
		var isTimeover = false;
		setTimeout(function() {
			isTimeover = true;
		}, 250);
		
		var _loaded = function(state) {
			prp.setState(state);
			prp.running = false;
			setTimeout(function() {
				prp.setState('Purge');
			}, 1500);
		};
		var _loadImage = function() {
			prp.setState('loading image');
			var imgSrc = prp.$ProofReadImage.attr('src');
			imgSrc = (imgSrc + '?dummy=' + Math.floor(Math.random()*10000000));
			var imgPathParts = imgSrc.split('\/');
			var imgLastPart = imgPathParts[imgPathParts.length-1].match(/(\D*|(?:\D*\d{1,3}\-)*)(\d+)(px.+)/);
			if (imgLastPart) {
				imgPathParts[imgPathParts.length-1] = imgLastPart[1] + (parseInt(imgLastPart[2], 10)+1) + imgLastPart[3];
				imgSrc = imgPathParts.join('\/');
			}
			prp.$ProofReadImage
				.load(function() {
					_loaded('Purge Ok!');
				})
				.error(function() {
					_loaded('Image error!');
				})
				.attr('src', '')
				.attr('src', imgSrc);
		};
		
		var $dialogDiv = $('<div>', { text: "You browser does not allow sending an automated purge request to Commons." });
		var manualUrl = '//commons.wikimedia.org/w/index.php?' + $.param({ title: prp.fileName, action: 'purge' });
		var _showDialog = function() {
			mw.loader.using('jquery.ui', function() {
				$dialogDiv.dialog({
					title: "Manual purge required",
					buttons: {
						"Ok, purged!": function() {
							_loadImage();
						}
					},
					modal: true,
					width: Math.min(550, $(window).width())
				});
			});
		};
		var _showPopUp = function() {
			var popup = window.open(manualUrl, "purgewindow", "width=550,height=400,resizable=yes");
			var $purgeLink = $('<a>', { href: manualUrl, target: 'purgewindow', text: 'Purge image on Commons' });
			if (popup) {
				$dialogDiv.append($('<p>', { text: 'If the opened page contains a button, press it. If no window has opened follow the link below.' }), $purgeLink);
			} else {
				$dialogDiv.append($('<p>', { text: 'Please open the link below.' }), $purgeLink);
			}
			_showDialog();
		};
		var _complete = function() {
			if (isTimeover) {
				_loadImage();
			} else {
				var $iFrame = $('<iframe>', { style: 'height:300px; width:99%' });
				if (0 === $iFrame.length) {
					_showPopUp();
				} else {
					var isTimeout, isTimeover2;
					setTimeout(function() {
						isTimeout = true;
						$iframeWrap.remove();
						_showPopUp();
					}, 5000);
					setTimeout(function() {
						isTimeover2 = true;
					}, 250);
					
					var $iframeWrap = $('<div>').append($('<p>', { text: 'If the page below contains a button, press it.' }), $iFrame);
					$dialogDiv.append($iframeWrap);
					$iFrame.error(function() {
						$iframeWrap.remove();
						if (!isTimeout) _showPopUp();
					}).load(function(e) {
						if (!isTimeover2) {
							$iFrame.triggerHandler('error');
							return;
						}
						if (!isTimeout) _showDialog();
					}).attr('src', manualUrl);
				}
			}
		};
		// You can make cross-site XHRs; the server will recieve them 
		// but unless a specific resp.-header is set, the browser will treat them as failed
		
		prp.setState('sending request');
		$.ajax({
			url: '//commons.wikimedia.org/w/api.php',
			cache: false,
			dataType: 'json',
			data: {
				titles: this.fileName,
				format: 'xml',
				action: 'purge'
			},
			type: 'POST',
			complete: _complete
		});
		
	},
	init: function() {
		prp.running = false;
		prp.$ProofReadImage = $('#ProofReadImage');
		prp.fileName = prp.fileNameFromImg(prp.$ProofReadImage);
		if (!prp.fileName) return;
		
		var purgeLink = mw.util.addPortletLink('p-views', '#', 'Purge', 'ca-purgelink', 'Purges the file on this page.');
		if (!purgeLink) purgeLink = mw.util.addPortletLink('p-cactions', '#', 'Purge', 'ca-purgelink', 'Purges the file on this page.');
		if (!purgeLink) return;
		
		prp.$purgeLink = $(purgeLink).click(function(e) {
			e.preventDefault();
			if (prp.running) return;
			prp.running = true;
			prp.purge();
		});
		if ('vector' === mw.config.get('skin')) prp.$purgeLink.addClass('collapsible');
		
		prp.$purgeLinkText = prp.$purgeLink.find('a');
		if (0 === prp.$purgeLinkText.length) prp.$purgeLinkText = prp.$purgeLink;
	}
};

mw.loader.using(['ext.proofreadpage.page', 'mediawiki.util'], function() {
	$(prp.init);
});

})(jQuery, mediaWiki);
//</nowiki>