User:Yuval CT/LicenseReview.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.
// Original Flickrreview script written by [[User:Patstuart]]
// Rewritten and extended by [[User:ZooFari]]
// Special thanks to [[User:Krinkle]] and [[User:DieBuche]] for assistance
// Large parts rewritten by Rillke
// See [[User talk:Rillke/LicenseReview.js]] for documentation
// This is updated version of [[User:Rillke/LicenseReview.js]] by [[User:Tulsi Bhagat]] 
// <nowiki>
$(function() {
var conf = mw.config.get(),
	userName = conf.wgUserName;

if (6 !== conf.wgNamespaceNumber) return;

var cleanUp = function(input) {
	return input
	.replace(/(== ?Summary ?==)/g, '=={{int:filedesc}}==')
	.replace(/(== ?Licensing ?==)/g, '=={{int:license-header}}==');
};

var thxPatterns = {
	flickr: 'Thanks for licensing this image using a free license! '
			+ 'Your choice of a free license has allowed us to use your image in <a href="http://commons.wikimedia.org/">Wikimedia Commons</a>. ' 
			+ 'The image is now used to illustrate <a href="http://commons.wikimedia.org/wiki/Special:GlobalUsage/%FILE%">one or more pages</a> ' 
			+ 'on <a href="http://en.wikipedia.org/">Wikipedia</a> or other free knowledge projects.'
};

var linkSanitizer = [
	// Google+
	// $1: userID; $2: albumID; $3: photoID
	{ match: /\/\/plus\.google\.[^\/]+\/photos\/(\d+)\/albums\/(\d+)\/(\d+)/g, replace: '//picasaweb.google.com/lh/sredir?uname=$1&target=PHOTO&id=$3&noredirect=1' }

];

var sanitizeLinks = function(textIn) {
	textIn = textIn || '';
	$.each(linkSanitizer, function(i, el) {
		textIn = textIn.replace(el.match, el.replace);
	});
	return textIn;
};

$.extend(thxPatterns, window.LRThxPatterns);

var licenseReviewMaybeSave = function(val, summary, minor, justsave, oldtext) {
	document.editform.wpSummary.value = summary;
	document.editform.wpMinoredit.checked = minor;

	if (justsave) {
		document.editform.submit();
		return true;
	}
	if (!oldtext) oldtext = val;
	
	// First Flickr-check
	var gotResult, $submitButton, thxPattern, match = oldtext.match(/\d{1,11}@\D\d{2}/);
	if (!match) match = oldtext.match(/flickr\.com\/people\/(\S+?)\/? /);
	if (!match) match = oldtext.match(/flickr\.com\/people\/(\S+)/);
	if (!match) match = oldtext.match(/flickr\.com\/photos\/(\S+?)\//);
	if (!match) match = oldtext.match(/flickr\.com\/photos\/(\S+)/);
	if (match) {
		thxPattern = thxPatterns.flickr;
	}
	
	var checkBlacklistCB = function(isBad) {
		if (!isBad) {
			$submitButton.prop('disabled', false).removeClass('ui-state-disabled');
			gotResult = true;
		}
	};
	
	if (match) {
		match = (match[1] || match[0]);
		ajaxIsBadAuthor(match, checkBlacklistCB);
		if (thxPattern) {
			$('body').append('<div id="mw-licensereview-add" style="display:none" title="You may use this thank-you text">'
			+	'<textarea id="ProposalThankyoumessage" readonly="readonly" style="width:400px;height:130px;" rows="5" cols="50" onclick="select()">'
			+	mw.html.escape(thxPattern.replace(/\%FILE\%/g, conf.wgPageName.replace('File:', '')))
			+	'</textarea>'
			+	'</div>'
			);
			$('#mw-licensereview-add').dialog({
				buttons: {
					"Ok": function() {
						if (gotResult) document.editform.submit();
					}
				},
				modal:true,
				width: 430
			});
			$submitButton = $('.ui-dialog-buttonpane').find('button:first');
			$submitButton.prop('disabled', true).addClass('ui-state-disabled');
			$('#ProposalThankyoumessage').keyup(function (e) {
				if ( (13 === (e.keyCode - 0)) ) $submitButton.click();
			});
		}
		return;
	} else {
		document.editform.submit();
		return true;
	}
};

var getSource = function(val) {
	var ret, r = val.match(/\|Source\s*=(.+)/i);
	if (r && r[1]) {
		ret = $.trim(r[1]);
	}
	if (!ret) {
		r = val.match(/http:\/\/photozou.jp[^\s\]\|]+/i);
		if (r) {
			ret = r[0];
		}
	}
	return ((ret || 'http://'));
};

var lrw = window.licenseReviewer = {

promptForSource: function(prefill) {
	return prompt("Link:", getSource(prefill));
},

// LRP - License review passed
LicenseReview_P: function () {
	var tb1 = document.editform.wpTextbox1,
		noChanges = tb1.value;

	if ( /\{\{Licen[cs]e ?review\}\}/i.test(noChanges) ) {
		var LRsite = lrw.promptForSource(tb1.value);
		if (null === LRsite) return mw.notify('License-review: Aborted');
		tb1.value = tb1.value.replace(/({{(L|l)icen[cs]e[ _]?(R|r)eview}})/g, '{{LicenseReview|site=' + LRsite + '|user=' + userName + '|date={{subst:#time:Y-m-d}}}}');
		if (noChanges === tb1.value) alert("RegExp did not match. Likely no changes. Please report to [[User talk:Tulsi Bhagat/LicenseReview.js]]");
		tb1.value = cleanUp(tb1.value);
		
		// submit
		licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
	}
	else {
		tb1.value = tb1.value
			.replace(/({{User:Flickr Review Bot.*?}})|({{(F|f)lickr(R|r)?eview.*?}})|({{User:FlickreviewR.*?}})/g, '{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}}}')
			.replace(/({{\s*(?:Template:)?(P|p)anoramior?eview.*?}})/g, '{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}}}')
			.replace(/({{User:Picasa Review Bot.*?}})|({{(P|p)icasar?eview}})/g, '{{Picasareview|' + userName + '|{{subst:#time:Y-m-d}}}}')
			.replace(/{{(([^\}]*?))(P|p)icasareview}}/g, '{{$1}}{{Picasareview|' + userName + '|{{subst:#time:Y-m-d}}}}')
			.replace(/{{(([^\}]*?))(P|p)anoramioreview(?:\/bot)?}}/g, '{{$1}}{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}}}')
			.replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}}}')
			.replace(/({{\s*(?:Template:)?(C|c)c-by-3.0-IndiaFM}})/g, '{{Cc-by-3.0-IndiaFM|status=confirmed|reviewer=~~~~}}')
			.replace(/({{\s*(?:Template:)?(C|c)c-by-3.0-BollywoodHungama}})/g, '{{Cc-by-3.0-BollywoodHungama|status=confirmed|reviewer=~~~~}}')
			.replace(/({{\s*(?:Template:)?(B|b)ollywoodHungama}})/g, '{{BollywoodHungama|status=confirmed|reviewer=~~~~}}')
			.replace(/({{\s*(?:Template:)?(B|b)ollywoodhungama}})/g, '{{BollywoodHungama|status=confirmed|reviewer=~~~~}}')
			.replace(/({{\s*(?:Template:)?(C|c)c-by(?:-sa)?-3.0-FilmiTadka}})/g, '{{Cc-by-sa-3.0-FilmiTadka|passed|~~~~}}')
			.replace(/({{\s*(?:Template:)?(I|i)pernity(R|r)eview}})/g, '{{Ipernityreview|' + userName + '|{{subst:#time:Y-m-d}}}}')
			.replace(/({{\s*(?:Template:)?(I|i)ndafotó review}})/g, '{{Indafotó review|site=[http://indafoto.hu Indafotó]|user=' + userName + '|date={{subst:#time:Y-m-d}}}}')
			.replace(/({{\s*(?:Template:)?(N|n)ROER}})/g, '{{NROER|status=confirmed|reviewer=' + userName + '|date={{subst:#time:Y-m-d}}}}')
			.replace(/(\[\[(C|c)ategory:(P|d)D files for review\]\])/g, '');
 
		// if no replacements
		if (noChanges === tb1.value){
			$('body').append('<div id="mw-licensereview-add" style="display:none" title="No template detected">'
			+		'<label for="mw-licensereview-pick">No template found. Add template:</label>'
			+		'<select id="mw-licensereview-pick" name="mw-licensereview-pick">'
			+			'<option value="LR">LicenseReview</option>'
			+			'<option value="FR">Flickrreview</option>'
			+			'<option value="PR">Panoramioreview</option>'
			+			'<option value="PICR">Picasareview</option>'
			+			'<option value="IR">Ipernityreview</option>'
			+		'</select>'
			+'</div>');
			$('#mw-licensereview-add').dialog({
				buttons: {
					"Ok": function() {
						licenseReviewer.LicenseReview_A( $('#mw-licensereview-pick').val() );
						$(this).dialog('close');
					}
				},
				modal:true 
			});
		} else {
			// if replacements
			tb1.value = cleanUp(tb1.value);
 
			// submit
			licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed using [[User:Tulsi Bhagat/LicenseReview.js|LicenseReview.js]]', true, false, noChanges);
		}
	}
},

// Add a License-review template
LicenseReview_A: function (pick) {
	var tb1 = document.editform.wpTextbox1;
	if (pick) {
		switch (pick) {
			case "FR" : tb1.value+='{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}}}';
				tb1.value = cleanUp(tb1.value);
				// submit
				licenseReviewMaybeSave(tb1.value, '[[Commons:Flickr files|Flickr review]]', false);
				break;
			case "PR" : tb1.value+='{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}}}';
				tb1.value = cleanUp(tb1.value);
				// submit
				licenseReviewMaybeSave(tb1.value, '[[Commons:License review|Panoramio review]]', false);
				break;
			case "PICR" : tb1.value+='{{Picasareview|' + userName + '|{{subst:#time:Y-m-d}}}}';
				tb1.value = cleanUp(tb1.value);
				// submit
				licenseReviewMaybeSave(tb1.value, '[[Commons:License review|Picasa review]]', false);
				break;
			case "IR" : tb1.value+='{{Ipernityreview|' + userName + '|{{subst:#time:Y-m-d}}}}';
				tb1.value = cleanUp(tb1.value);
				// submit
				licenseReviewMaybeSave(tb1.value, '[[Commons:License review|Ipernity review]]', false);
				break;
			case "LR" : var site = lrw.promptForSource(tb1.value);
				if (null === site) return mw.notify('License-review: Aborted');
				tb1.value+='{{LicenseReview|site=' + site + '|user=' + userName + '|date={{subst:#time:Y-m-d}}}}';
				tb1.value = cleanUp(tb1.value);
				// submit
				licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]]', false);
				break;
		}
	}
},

// LRF - License review failed
LicenseReview_F: function () {
	var tb1 = document.editform.wpTextbox1,
		isBollyWood = /\{\{Cc\-by\-3.0\-IndiaFM\}\}/i.test(tb1.value) || /(\{\{(C|c)c-by-3.0-BollywoodHungama\}\})/.test(tb1.value),
		isFlickr = /[Ff]lickr/.test(tb1.value),
		options;
	
	options = '<option value="NS">-- No source indicated --</option>';
	if (isBollyWood) {
		options += '<option value="BOLLY">Screenshot of Bollywood image</option>';
	} else {
		options += '<option value="ARR">All rights reserved</option>'
		+		'<option value="NC">Non-commercial</option>'
		+		'<option value="ND">Non-derivative</option>'
		+		'<option value="NCD">Non-commercial + Non-derivative</option>'
		+		'<option value="NCS">Non-commercial-ShareAlike</option>'
		+		'<option value="PANO">Panoramio review unnecessary</option>'
		+		'<option value="PICASA?">Picasa review unnecessary</option>';
	}
	if (isFlickr) {
		options += '<option value="ARR?">ARR (Puf)(Flickr-only)</option>'
		+		'<option value="NC?">NC (Puf)(Flickr-only)</option>'
		+		'<option value="ND?">ND (Puf)(Flickr-only)</option>'
		+		'<option value="NCD?">NC+D (Puf)(Flickr-only)</option>'
		+		'<option value="NCS?">NC-SA (Puf)(Flickr-only)</option>'
		+		'<option value="PDMARK">PD-Mark</option>';
	}

	
	$('body').append('<div id="mw-licensereview-selector" style="display:none" title="Pick a license">'
	+		'<label for="mw-licensereview-pick">Which License?</label>'
	+		'<select id="mw-licensereview-pick" name="mw-licensereview-pick">'
	+			options
	+		'</select>'
	+'</div>');
	$('#mw-licensereview-selector').dialog({
		buttons: {
			"Ok": function() {
				licenseReviewer.LicenseReview_C( $('#mw-licensereview-pick').val() );
				$(this).dialog('close');
			}
		},
		modal:true 
	});
},

// License review failed, got reason, processing
LicenseReview_C: function (pick) {
	var tb1 = document.editform.wpTextbox1,
		isFlickr = /[Ff]lickr/.test(tb1.value),
		reFlickr = /({{User:Flickr Review Bot.*?}})|({{(F|f)lickrr?eview.*?}})|({{User:FlickreviewR.*?}})/g,
		rePano = /({{(P|p)anoramior?eview(?:\/bot\|.*?)?}})/g,
		rePicasa = /({{User:Picasa Review Bot.*?}})|({{(P|p)icasar?eview}})/g,
		rePicasa2 = /{{(([^\}]*?))(P|p)icasareview}}/g,
		rePano2 = /{{(([^\}]*?))(P|p)anoramioreview}}/g,
		reFlickr2 = /{{(([^\}]*?))(F|f)lickrreview}}/g,
		reLR = /{{(L|l)icen[cs]e[ _]?(R|r)eview}}/g,
		reLicenses = /\{\{(?:Template:)?(cc-by(?:-sa)?-\d\.\d|pd-self)\}\}/gi,
		summary = '',
		minor = false,
		userTag = ''; // You can create new templates if you want and add them to the switch in order to notify the user with a default template
	// First changing/ adding review-tags
	if (pick) {
		switch (pick) {
			case "ARR" : 
				if (isFlickr) {
					tb1.value = "{{subst:Uffd|2=ARR}} \n" + tb1.value.replace(reFlickr, '');
					userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
				} else {
					tb1.value = "" + tb1.value.replace(reFlickr, '{{subst:Uffd|2=ARR}}')
						.replace(rePano, '{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}')
						.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}')
						.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}')
						.replace(rePano2, '{{$1}}{{panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}')
						.replace(reLR, '{{copyvio|1=Posted to source as All Rights Reserved. Only free files are allowed on Commons.}}')
						.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=ARR}}');
				}
				break;
			case "NC" : 
				if (isFlickr) {
					tb1.value = "{{subst:Uffd|2=NC}} \n" + tb1.value.replace(reFlickr, '');
					userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
				} else {
					tb1.value = "" + tb1.value.replace(reFlickr, '{{subst:Uffd|2=NC}}')
						.replace(rePano, '{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-3.0}}')
						.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-3.0}}')
						.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-3.0}}')
						.replace(rePano2, '{{$1}}{{panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-3.0}}')
						.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nc. Non-commercial restriction is not allowed on Commons.}}')
						.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=NC}}');
				}
				break;
			case "ND" : 
				if (isFlickr) {
					tb1.value = "{{subst:Uffd|2=ND}} \n" + tb1.value.replace(reFlickr, '');
					userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
				} else {
					tb1.value = "" + tb1.value.replace(reFlickr, '{{subst:Uffd|2=ND}}')
						.replace(rePano, '{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-3.0}}')
						.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-3.0}}')
						.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-3.0}}')
						.replace(rePano2, '{{$1}}{{panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-3.0}}')
						.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nd. Non-derivative restriction is not allowed on Commons.}}')
						.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=ND}}');
				}
				break;
			case "NCD" : 
				if (isFlickr) {
					tb1.value = "{{subst:Uffd|2=NCD}} \n" + tb1.value.replace(reFlickr, '');
					userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
				} else {
					tb1.value = "" + tb1.value.replace(reFlickr, '{{subst:Uffd|2=NCD}}')
						.replace(rePano, '{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-3.0}}')
						.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-3.0}}')
						.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-3.0}}')
						.replace(rePano2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-3.0}}')
						.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nc-nd. Non-derivative and non-commercial restriction are not allowed on Commons.}}')
						.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=NCD}}');
				}
				break;
			case "NCS" : 
				if (isFlickr) {
					tb1.value = "{{subst:Uffd|2=NCS}} \n" + tb1.value.replace(reFlickr, '');
					userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
				} else {
					tb1.value = "" + tb1.value.replace(reFlickr, '{{subst:Uffd|2=NCS}}')
						.replace(rePano, '{{Panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-3.0}}')
						.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-3.0}}')
						.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-3.0}}')
						.replace(rePano2, '{{$1}}{{panoramioreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-3.0}}')
						.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nc-sa. Non-commercial restriction is not allowed on Commons.}}')
						.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=NCS}}');
				}
				break;
			case "NS" : 
				tb1.value = "{{subst:nsd}} \n" + tb1.value
					.replace(reFlickr, '{{Flickr no source|' + userName + '|{{subst:#time:Y-m-d}}}}')
					.replace(rePano, '{{Panoramio no source|' + userName + '|{{subst:#time:Y-m-d}}}}')
					.replace(rePicasa, '{{$1}}{{Picasa no source|' + userName + '|{{subst:#time:Y-m-d}}}}')
					.replace(rePano2, '{{$1}}{{Panoramio no source|' + userName + '|{{subst:#time:Y-m-d}}}}')
					.replace(reLR, '{{LicenseReview|site=?}}')
					.replace(reFlickr2, '{{$1}}{{Flickr no source|' + userName + '|{{subst:#time:Y-m-d}}}}');
				userTag = '{{subst:image source|1=%FILE%}}';
				break;
			case "PANO" : tb1.value = "" + tb1.value.replace(/({{(P|p)anoramior?eview.*?}})/g, '{{Panoramioreviewunnecessary}}');
				break;
			case "PICASA" : tb1.value = "" + tb1.value.replace(/({{User:Picasa Review Bot.*?}})|({{(P|p)icasar?eview}})/g, '{{Picasareviewunnecessary}}');
				break;
			case "ARR?" : tb1.value = "" + tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|All rights reserved}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}');
				break;
			case "NC?" : tb1.value = "" + tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-2.0}}');
				break;
			case "ND?" : tb1.value = "" + tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-2.0}}');
				break;
			case "NCD?" : tb1.value = "" + tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-2.0}}');
				break;
			case "NCS?" : tb1.value = "" + tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-2.0}}');
				break;
			case 'BOLLY': tb1.value = "{{Copyvio|1=[[Commons:License review|License review]] of Bollywood Hungama failed: Image is a screenshot, wallpaper or promotional poster. See [[Template:Cc-by-3.0-BollywoodHungama]]. ~~~~}}" + tb1.value.replace(/(\{\{Cc\-by\-3.0\-IndiaFM\}\})/ig, "{{Cc-by-3.0-BollywoodHungama}}");
				break;
			case 'PDMARK':
				tb1.value = "{{subst:Flickr-public domain mark/subst}}\n" + tb1.value
					.replace(reFlickr, '')
					.replace(reLR, '{{LicenseReview|site=?}}')
					.replace(reFlickr2, '{{$1}}')
					.replace(reLicenses, '');
				break;
		}
	}
	// Then, adding edit summary
	if (pick) {
		switch (pick) {
			case "NS" :
				summary = '[[Commons:License review|License review]] failed: Source not found';
				break;
			case "PICASA" :
				summary = '[[Commons:Picasa Web Albums files|Picasa review]] not required';
				break;
			case "PANO" :
				summary = '[[Commons:License review|Panoramio review]] not required';
				break;
			case "PDMARK" :
				summary = '[[Commons:License review|License review]]: Provide a specific reason for the public domain status, please.';
				break;
			default :
				summary = '[[Commons:License review|License review]] failed';
		}
	}
	if (userTag) {
		ajaxNotifyUploader(userTag, licenseReviewMaybeSave, [tb1.value, summary, minor, true]);
	} else {
		// Finally, submit
		licenseReviewMaybeSave(tb1.value, summary, minor, true);
	}
},
 
// Change license
LicenseReviewChange: function () {
		$('body').append('<div id="mw-licensereview-changer" style="display:none" title="Pick a license">'
		+		'<label for="mw-licensereviewc-pick">Change to:</label><br>'
		+		'<select id="mw-licensereviewc-pick" name="mw-licensereviewc-pick">'
		+			'<option value="BY2">cc-by-2.0</option>'
		+			'<option value="BY21jp">cc-by-2.1-jp</option>'
		+			'<option value="SA2">cc-by-sa-2.0</option>'
		+			'<option value="PD">No known restrictions (Flickr only)</option>'
		+			'<option value="BY3">cc-by-3.0</option>'
		+			'<option value="SA3">cc-by-sa-3.0</option>'
		+			'<option value="BY4">cc-by-4.0</option>'
		+			'<option value="SA4">cc-by-sa-4.0</option>'
		+		'</select>'
		+'</div>');
		$('#mw-licensereview-changer').dialog({
			buttons: {
				"Ok": function() {
					licenseReviewer.LicenseReview_L( $('#mw-licensereviewc-pick').val() );
					$(this).dialog('close');
				}
			},
			modal:true 
		});
},
 
LicenseReview_L: function (pick) {
	var tb1 = document.editform.wpTextbox1;
	if (pick) {
		var pattern = /({{(C|c)c-by-(sa-|)(2|3|4)\.\d.*?}})|({{(F|f)lickr-no known copyright restrictions}})/g;
		var doReplacement = function(replace, summaryText) {
			tb1.value = "" + tb1.value.replace(pattern, replace);
			document.editform.wpSummary.value = '[[Commons:License review|License review]]: Change to ' + summaryText;
			document.editform.wpMinoredit.checked = false;
		};
		switch (pick) {
			case "BY2" : 
				doReplacement('{{cc-by-2.0}}', 'CC-BY-2.0');
				break;
			case "BY21jp":
				doReplacement('{{cc-by-2.1-jp}}', 'CC-BY-2.1-JP');
				break;
			case "SA2" : 
				doReplacement('{{cc-by-sa-2.0}}', 'CC-BY-SA-2.0');
				break;
			case "PD" : 
				doReplacement('{{Flickr-no known copyright restrictions}}', 'Flickr-no known copyright restrictions');
				break;
			case "BY3" : 
				doReplacement('{{cc-by-3.0}}', 'CC-BY-3.0');
				break;
			case "SA3" : 
				doReplacement('{{cc-by-sa-3.0}}', 'CC-BY-SA-3.0');
				break;
			case "BY4" : 
				doReplacement('{{cc-by-4.0}}', 'CC-BY-4.0');
				break;
			case "SA4" : 
				doReplacement('{{cc-by-sa-4.0}}', 'CC-BY-SA-4.0');
				break;
		}
	}
},

installMig: function($node) {
	var $migDiv = $('<div>'),
		$migIntro = $('<label>', { text: "Migration Review:" }).attr({ 'for': 'lrwMigSel' }).appendTo($migDiv),
		$migSelect = $('<select>').attr({ id: 'lrwMigSel', size: 1, style: 'vertical-align:middle' }).appendTo($migDiv),
		$migOptEmpty = $('<option>', { text: " ", value: '' }).appendTo($migSelect),
		$migOptRelicense = $('<option>', { text: "relicense", value: 'relicense' }).appendTo($migSelect),
		$migOptRedundant = $('<option>', { text: "redundant", value: 'redundant' }).appendTo($migSelect),
		$migOptInelibible = $('<option>', { text: "not eligible", value: 'not-eligible' }).appendTo($migSelect),
		$migOptReviewNeeded = $('<option>', { text: "needs review", value: 'needs-review' }).appendTo($migSelect),
		$migOptOut = $('<option>', { text: "opt-out", value: 'opt-out' }).appendTo($migSelect),
		$migReason = $('<input>').attr({ type: 'text', size: 60, value: "[[Template:License migration|License migration]]: " }).appendTo($migDiv),
		$saveButton = $('<button>', { text: "Save" }).attr({ type: 'button', role: 'button' }).button({ icons: { primary: 'ui-icon-disk' } }).appendTo($migDiv),
		$editButton = $('<button>', { text: "Edit" }).attr({ type: 'button', role: 'button' }).button({ icons: { primary: 'ui-icon-pencil' } }).appendTo($migDiv);
	
	$migSelect.change(function() {
		$migReason.val("[[Template:License migration|License migration]]: " + $migSelect.val());
	});
	var $nodeChild = $node.children('tbody');
	if ($nodeChild.length) {
		$nodeChild.append($('<tr>').append($('<td>').attr({ colspan:3 }).append($migDiv)));
	} else {
		$migDiv.prependTo($node);
	}
	
	var migReplace = function(wikiText, cb) {
		mw.loader.using('ext.gadget.libWikiDOM', function() {
			var nwe = mw.libs.wikiDOM.nowikiEscaper(wikiText),
				nt;
			
			// First try to replace the migration parameter
			nwe.secureReplace(/\|\s*[Mm]igration\s*=\s*(?:needs[\- _]review|review)?\s*([\|\}])/, '|migration=' + $migSelect.val() + '$1');
			nt = nwe.getText();
			if (nt !== wikiText) return cb(nt);

			// If nothing was replaced, then replace templates without params
			nwe.secureReplace(/\{\{\s*(Bild\-GFDL|GFDL|GFDL\-1.3|Gfdl|GNU FDL|Eigenwerk|Gdfl|GFDL\-no\-disclaimers|GNU|ГЛСД\-без\-одрицања|CopyrightGFDL|مجوز گنو|Јд\-јас|ГЛСД|ГЛСД\-без одрицања|GFDL\-lastno|GFDl|GFDL\-Self|GFDL\-user|GFDL\-user\-w|GNU[ _]Free[ _]Documentation[ _]License|GFDL-\D\D\D?|GFDL-user-\D\D\D?|YAM|OsborneFossils)\s*\}\}/i, '{{$1|migration=' + $migSelect.val() + '}}');
			nt = nwe.getText();
			if (nt !== wikiText) return cb(nt);
			
			// If nothing was replaced, try with params
			nwe.secureReplace(/\{\{\s*(Bild\-GFDL|GFDL|GFDL\-1.3|Gfdl|GNU FDL|Eigenwerk|Gdfl|GFDL\-no\-disclaimers|GNU|ГЛСД\-без\-одрицања|CopyrightGFDL|مجوز گنو|Јд\-јас|ГЛСД|ГЛСД\-без одрицања|GFDL\-lastno|GFDl|GFDL\-Self|GFDL\-user|GFDL\-user\-w|GNU[ _]Free[ _]Documentation[ _]License|GFDL-\D\D\D?|GFDL-user-\D\D\D?)\s*(\|[^\}]*)?\}\}/i, '{{$1$2|migration=' + $migSelect.val() + '}}');
			nt = nwe.getText();
			if (nt !== wikiText) return cb(nt);
			
			// If nothing was replaced, try {{self}}
			nwe.secureReplace(/\{\{\s*self2?\s*\|(.*?\|?)(?:GFDL|GNU[ _]FDL|GNU[ _]Free[ _]Documentation[ _]License)(\s*\|.*?)?\}\}/i, '{{self|$1GFDL$2|migration=' + $migSelect.val() + '}}');
			nt = nwe.getText();
			if (nt !== wikiText) return cb(nt);
			
			throw new Error("Could not migrate license because the template for license migration was not detected.");
		});
	};
	
	$editButton.click(function(e) {
		var onMigEdit = function() {
			var $tb1 = $(document.editform.wpTextbox1),
				$sum = $(document.editform.wpSummary);
			
			migReplace($tb1.val(), function(nt) {
				$tb1.val(nt);
				$sum.val($migReason.val());
			});
		};
		mw.loader.load('ext.gadget.libWikiDOM');
		execEdit(onMigEdit);
	});
	
	$saveButton.click(function(e) {
		mw.loader.using(['ext.gadget.AjaxQuickDelete', 'ext.gadget.libWikiDOM'], function() {
			var aqd = AjaxQuickDelete;
			aqd.initialize();
			aqd.addTask('getMoveToken');
			aqd.addTask('lrwTextModifyProxy');
			aqd.addTask('reloadPage');
			aqd.lrwTextModifyProxy = function() {
				migReplace(aqd.pageContent, function(nc) {
					var page = {
						title: conf.wgPageName.replace(/_/g, ' '),
						text:  nc,
						starttimestamp: aqd.starttimestamp,
						timestamp: aqd.timestamp,
						editType: 'text',
						watchlist: 'nochange'
					};
					aqd.showProgress("Changing template parameter to " + $migSelect.val());
					aqd.savePage(page, $migReason.val(), 'nextTask');
				});
			};
			aqd.nextTask();
		});
	});
},

//

installLLinks: function(undef) {
	var $passHref = $(mw.libs.commons.ui.addEditLink('#', 'license +', 'lPlus', "License-review: Pass file.", undef, undef, 'p-cactions')).find('a');
	var $failHref = $(mw.libs.commons.ui.addEditLink('#', 'license -', 'lMinus', "License-review: Review failed.", undef, undef, 'p-cactions')).find('a');

	$passHref.click(function (e) {
		e.preventDefault();
		execEdit(licenseReviewer.LicenseReview_P);
	});
	$failHref.click(function (e) {
		e.preventDefault();
		execEdit(licenseReviewer.LicenseReview_F);
	});
	var $lrNode = $('div.LR');
	if ($lrNode.length) {
		$lrNode.css('text-align', 'center');
		$changeHref = $('<a>', { href: '#', text: 'change license' });
		$changeHref.click(function (e) {
			e.preventDefault();
			execEdit(licenseReviewer.LicenseReviewChange);
		});
		$lrNode.append($('<span>', { id: 'lChange' }).append(' [', $changeHref, '] '));
		$lrNode.append($('<span>', { id: 'lPlus2'  }).append(' [', $passHref.clone(true).removeAttr('id'), '] '));
		$lrNode.append($('<span>', { id: 'lMinus2' }).append(' [', $failHref.clone(true).removeAttr('id'), '] '));
		
		// Sanitizing Google+ Links to PicasaWeb because no license info is displayed on G+
		$('.hproduct').find('a[href^="http"]').each(function(i, el) {
			var $el = $(el),
				href = $el.attr('href');
			$el.attr('href', sanitizeLinks(href));
		});
	}
	if (document.editform && document.editform.wpTextbox1) document.editform.wpTextbox1.value = sanitizeLinks(document.editform.wpTextbox1.value);
	
	// License migration review
	var $migImage = $('img[alt="Licensing update unknown"]'),
		hasMigImage = !!$migImage.length;
	if (hasMigImage) {
		$('span.licensetpl_short').each(function(i, el) {
			var $el = $(el);
			if ($.inArray($el.text(), ['GFDL', 'GFDL 1.3']) > -1 && $('img[alt="Licensing update unknown"]').length) {
				licenseReviewer.installMig($migImage.parents('.licensetpl'));
				return false;
			}
		});
	}
}
}; // End of Object (licenseReviewer)

var execEdit = function(cb) {
	if ($.inArray( conf.wgAction, ['edit', 'submit'] ) === -1) {
		// scroll to top
		$('html,body').animate({scrollTop: 0}, 1000);
		// switch to pseudo-edit-mode
		var gotEditHTML = function(html) {
			$('#bodyContent').replaceWith($(html).find('#bodyContent'));
			document.editform.wpTextbox1.value = sanitizeLinks(document.editform.wpTextbox1.value);
			mw.config.set('wgAction', 'edit');
			document.title = "Editing " + document.title;
			$('#ca-edit').addClass('selected');
			cb();
		};
		$('#bodyContent').prepend($('<h2>', { 'text': 'Loading ...' }));
		$.get(mw.util.wikiScript('index'), { action: 'edit', title: conf.wgPageName.replace(/ /g, '_') }, gotEditHTML);
	} else {
		// execute
		cb();
	}
};

/**
 * Notify the initial uploader about a non-free image upload.
 *
 * @example
 *      ajaxNotifyUploader('{{subst:unfreeflickrnote|%FILE%}}', someFunction, arguments to pass along);
 *
 * @param tag {String} Tag to add to the user's talk page
 * @param callback {Function} Pointer to a callback function on ready or error.
 *
 * @context {window}
 * @return n/d
 */
var ajaxNotifyUploader = function(tag, callback, args) {
	if (!tag) return;
	var errDisplay = function(err) {
		alert(err);
		callback.apply(this, args);
	};
	var didEdit = function(result) {
		try {
			if (result.edit.spamblacklist) {
				throw new Error('Spamblacklisted. Sorry.');
			} else if (result.error) {
				throw new Error('API returned error: ' + result.error.code + '\n' + result.error.info);
			}
			alert('User notified.');
			callback.apply(this, args);
			return;
		} catch (err) {
			errDisplay('Something went wrong while notifying the user.');
			return;
		}
	};
	var doEdit = function(user) {
		if (/(:?^[Bb]ot)|(:?[Bb]ot$)/.test(user)) {
			errDisplay('User who created this page is very likely a bot and is NOT notified.');
			return;
		}
		var page = { action: 'edit'
			,format: 'json'
			,title: conf.wgFormattedNamespaces[3] + ':' + user
			,summary: 'Notification of possible unfree Flickr-file.'
			,appendtext: '\n' + tag.replace('%FILE%', conf.wgPageName.replace(/_/g, ' ')) + ' ~~' + '~~'
			,token: mw.user.tokens.get('csrfToken')
		};
		jQuery.post(mw.util.wikiScript('api'), page, didEdit);
	};
	var gotUser = function(result) {
		try {
			for (var id in result.query.pages) {
				var pg = result.query.pages[id];
				doEdit(pg.revisions[0].user);
			}
		} catch (err) {
			errDisplay('Error notifying user. Do it yourself.');
			return;
		}
	};
	// query first revision (in Lupo-Style :D)
	var query = 
	{   action: 'query'
		,format: 'json'
		,prop: 'revisions'
		,rvprop: 'user'
		,rvdir: 'newer'
		,rvlimit: 1
		,titles: conf.wgPageName.replace(/_/g, ' ')
	};
	$.getJSON(mw.util.wikiScript('api'), query, gotUser);
};

/**
 * Determine whether the flickr-user is a "bad-author".
 *
 * @example
 *      ajaxIsBadAuthor('11121189@N04', someFunction);
 *
 * @param author {String} The flckr-user's ID
 * @param callback {Function} Pointer to a callback function on ready or error. Should take one argument.
 *
 * @context {window}
 * @return n/d
 */
var ajaxIsBadAuthor = function(author, callback) {
	var gotList = function(result, useRx) {
		pendingCalls--;
		if (result) {
			var rx = useRx ? (new RegExp('\\|\\s*' + mw.RegExp.escape(author) + '\\s*\\|', ''))
				: (new RegExp(mw.RegExp.escape(author), ''));
			if ( rx.test(result) ) {
				isBad = isBad || true;
				if (pendingCalls) return;
				if (isBad) alert('Warning! The Flickr-Uploader is blacklisted.');
				callback(isBad);
				return;
			} else {
				if (pendingCalls) return;
				if (isBad) alert('Warning! The Flickr-Uploader is blacklisted.');
				callback(isBad);
				return;
			}
		} else {
			alert('Error retrieving bad-author-list from server.');
		}
	};
	var pendingCalls = 0;
	var isBad = false;
	var doCall = function(page, useRx) {
		pendingCalls++;
		$.ajax({
			url: mw.util.wikiScript('index'),
			data:
			{   title: page
				,action: 'raw'
				,dataType: 'text'
				// Allow caching for 1/4h
				,maxage: 900
				,smaxage: 900
			},
			cache: true,
			type: 'GET',
			success: function (r) {
				gotList(r, useRx);
			},
			error: function() {
				gotList();
			}
		});
	};
	doCall('Commons:Questionable_Flickr_images/Users', true);
	doCall('User:FlickreviewR/bad-authors', false);
};

// Install
mw.loader.using(['jquery.ui', 'ext.gadget.editDropdown'], function() {
	licenseReviewer.installLLinks();
	mw.loader.load( ['mediawiki.user', 'mediawiki.util'] );
});
});
// </nowiki>