Jump to content

User:Jackmcbarn/editProtectedHelper.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Jackmcbarn (talk | contribs) at 22:38, 16 February 2014 (update to reflect changes to templates). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <nowiki>
// only enable this on the latest revision of the page
if(mw.config.get('wgRevisionId') == mw.config.get('wgCurRevisionId')) {
	mw.loader.load('mediawiki.api.edit');
	$(document).ready(function() {
		var templateResponses = [
			[ '', '(No template response)' ],
			[ 'd', 'Done' ],
			[ 'pd', 'Partly done:' ],
			[ 'nd', 'Not done:' ],
			[ 'nfn', 'Not done for now:' ],
			[ 'c', 'Not done: please establish a consensus for this alteration before using the {{edit protected}} template.'] , // TODO make dynamic
			[ 'rs', 'Not done: please provide reliable sources that support the change you want to be made.' ],
			[ '?', 'Not done: please be more specific about what needs to be changed.' ],
			[ 'mis', 'Not done: this is the talk page for discussing improvements to the template {{EP}}. Please make your request at the talk page for the article concerned.'] , // TODO make dynamic
			[ 'sb', 'Not done: please make your requested changes to the template\'s sandbox first; see WP:TESTCASES.' ],
			[ 'tp', 'Not done: this is the talk page for discussing improvements to the template {{EP}}. If possible, please make your request at the talk page for the article concerned. If you cannot edit the article\'s talk page, you can instead make your request at Wikipedia:Requests for page protection#Current requests for edits to a protected page.' ],
			[ 'xy', 'Not done: please make your request in a "change X to Y" format.' ],
			[ 'a', 'Already done' ],
			[ 'hr', 'Not done: According to the page\'s protection level and your user rights, you should currently be able to edit the page yourself. If you still seem to be unable to, please reopen the request with further details.'] ,
			[ 'doc', 'Not done: {{edit protected}} is usually not required for edits to the documentation, categories, or interlanguage links of templates using a documentation subpage. Use the \'edit\' link at the top of the green "Template documentation" box to edit the documentation subpage.' ],
			[ 'drv', 'Not done: requests for recreating deleted pages protected against creation should be made at Wikipedia:Deletion review.' ],
			[ 'r', 'Not done: requests for increases to the page protection level should be made at Wikipedia:Requests for page protection.' ],
			[ 'ru', 'Not done: requests for decreases to the page protection level should be directed to the protecting admin or to Wikipedia:Requests for page protection if the protecting admin is not active or has declined the request.' ],
			[ 'p', 'Not done: this is not the right page to request additional user rights. You may reopen this request with the specific changes to be made and someone will add them for you.'] , // TODO make dynamic
			[ 'm', 'Not done: page move requests should be made at Wikipedia:Requested moves.' ],
			[ 'q', 'Question:' ],
			[ 'n', 'Note:' ],
			[ 'udp', 'Undone: This request (or the completed portion of it) has been undone.' ],
			[ 'ud', 'Undone: This request has been undone.' ]
		];
		var selector = $('.editrequest .mbox-text'), sections, wikitext;
		var selectedLevel = { semi: [' selected="selected"', '', ''], template: ['', ' selected="selected"', ''], full: ['', '', ' selected="selected"'] };
		var templateLevel = { semi: 'semi-', template: 'template-', full: '' };
		var responseLevel = { semi: '{' + '{subst:ESp|', template: '{' + '{subst:ETp|', full: '{' + '{subst:EP|' };
		var sptemplates = /^[Ee]dit semi-protected$/, tptemplates=/^[Ee]dit template-protected$/;
		function parseArgs(str) {
			var argparser = /\|\s*(?:([^\s|=]+)\s*=\s*)?([^|]*)/g;
			var named = [], unnamed = [], arg, n = 0;
			while ((arg = argparser.exec(str)) !== null) {
				if(arg[1] === undefined) {
					unnamed[++n] = arg[2];
				} else if(/\d+/.test(arg[1])) {
					// hack so we only get one big parameter with all the page names
					unnamed[arg[1]] = (/=/.test(arg[2]) ? arg[1] + '=' : '') + arg[2];
				} else {
					named[arg[1]] = arg[2];
				}
			}
			named[''] = unnamed.join('|').replace(/^\|+|\|+$/g, '').replace(/\|+/g, '|');
			return named;
		}
		function isYes(val) {
			return val == 'yes' || val == 'y' || val == 'true' || val == 1;
		}
		function getBanner(level, pagename, answered, demo, force) {
			return '{{edit ' + templateLevel[level] + 'protected|' + (pagename === '' ? '<!-- Page to be edited -->' : pagename) + '|answered=' + (answered ? 'yes' : 'no') + (force ? '|force=yes' : '') + (demo ? '|demo=yes}}' : '}}');
		}
		function getResponse(level, template, free) {
			return "\n:" + (template === '' ? '' : responseLevel[level] + template + '}} ') + (free === '' ? '' : free + ' ') + '~~' + "~~\n";
		}
		function onclickEditProtectedResponseLink(e)
		{
			var match = e.data[0], responseoffset = match.responseoffset, sectiontext = match.sectiontext, newsectiontext, form = e.data[1];
			var response = getResponse(form.level.value, form.responsetemplate.value, form.responsefree.value), banner = getBanner(form.level.value, form.pagetoedit.value, form.answered.checked, match.demo, form.force.checked);
			// prevent empty response
			if(response != "\n:~~" + "~~\n") {
				sectiontext = sectiontext.substr(0, responseoffset).trim() + response + sectiontext.substr(responseoffset);
			}
			// prevent dirty diff
			if(match.banner != banner) {
				sectiontext = sectiontext.replace(match[0], banner);
			}
			if(sectiontext == match.sectiontext) {
				alert('Refusing to make null edit');
				return false;
			}
			e.data[2].text('Processing...');
			this.disabled = true;
			console.log(match.section);
			console.log(sectiontext);
			if(confirm("Really edit the page?")) {
				new mw.Api().get( { action: 'query', prop: 'revisions', rvprop: 'timestamp', revids: mw.config.get('wgRevisionId') }).done(function(data) {
					new mw.Api().postWithEditToken( { action: 'edit', pageid: mw.config.get('wgArticleId'), section: match.section, text: sectiontext, summary: (match.section !== 0 ? '/' + '* ' + sections[match.section - 1].line + ' *' + '/ ' : '') + 'Responded to edit request ([[WP:EPH|EPH]])', notminor: true, nocreate: true, basetimestamp: data.query.pages[mw.config.get('wgArticleId')].revisions[0].timestamp } ).done(function() {
						e.data[2].css('color', 'green').text('Success: Reloading page...');
						location.reload();
					}).fail(function(err) {
						e.data[2].css('color', 'red').text('Error: ' + err);
						console.log.apply(undefined, arguments);
					});
				});
			}
			return false;
		}
		function appendForm(obj, level, pagename, answered, force, match) {
			var form = $('<form class="editProtectedHelper" style="display: none" />');
			form.append('<label>Level: <select name="level"><option value="semi"' + selectedLevel[level][0] + '>Semi-protected</option><option value="template"' + selectedLevel[level][1] + '>Template-protected</option><option value="full"' + selectedLevel[level][2] + '>Fully protected</option></select></label> ');
			if(force) {
				form.append('<label>Disable protection level autodetection (use only if necessary): <input type="checkbox" name="force" checked="checked" /></label> ' );
			} else {
				form.append('<input type="checkbox" name="force" style="display: none" />' ); // if this is off and you want to turn it on, do it with firebug or something. otherwise people will use this when they shouldn't
			}
			var label = $('<label>Page to be edited: </label>');
			label.append($('<input type="text" name="pagetoedit" />').attr('value', pagename !== '<!-- Page to be edited -->' ? pagename : ''));
			form.append(label);
			form.append(' <label>Answered: <input type="checkbox" name="answered"' + (answered ? ' checked="checked"' : '') + ' /></label><br />Response: ');
			var select = $('<select name="responsetemplate" style="width: 100%" />');
			templateResponses.forEach(function(r) {
				select.append($('<option />').attr('value', r[0]).text(r[1]));
			});
			form.append(select);
			form.append('<textarea name="responsefree"></textarea> ~~' + '~~ ')
			var resultObj = $('<span></span>');
			var button = $('<button type="button">Submit</button>').click([match, form[0], resultObj], onclickEditProtectedResponseLink);
			form.append(button);
			form.append(' ');
			form.append(resultObj);
			$(obj).append(form);
			var showform = $('<button type="button">Respond</button>').click(function(){
				$(this).hide();
				$(obj).closest('.editrequest').removeClass('mbox-small');
				form.show();
			});
			$(obj).append(showform);
		}
		function setupFieldsForTemplate(match, n, matches) {
			var section = 1, beginoffset, responseoffset, sectiontext, args = parseArgs(match[2]), level, pagename, answered, demo;
			while(section <= sections.length && sections[section - 1].byteoffset < match.index ) {
				++section;
			}
			--section;
			if(section == 0) {
				beginoffset = 0;
				responseoffset = sections.length ? sections[0].byteoffset : wikitext.length;
				sectiontext = wikitext.slice(beginoffset, responseoffset);
			} else {
				var level = sections[section - 1].level, endSection = section;
				beginoffset = sections[section - 1].byteoffset;
				// respond before a subsection if there is one
				responseoffset = section == sections.length ? wikitext.length : sections[section].byteoffset;
				while(true) {
					// find the next section that's not a subsection
					if(sections.length == endSection) {
						sectiontext = wikitext.substr(beginoffset);
						break;
					} else if(sections[endSection].level <= level) {
						sectiontext = wikitext.slice(beginoffset, sections[endSection].byteoffset);
						break;
					}
					++endSection;
				}
			}
			if(n+1 != matches.length && matches[n+1].index < responseoffset) {
				// if there's another edit request banner in the same section as this one, put our response right before it instead of at the end of the section
				responseoffset = matches[n+1].index;
			}
			responseoffset -= beginoffset;
			level = sptemplates.test(match[1]) ? 'semi' : tptemplates.test(match[1]) ? 'template' : 'full';
			pagename = args[''];
			answered = isYes(args['ans'] || args['answered']);
			demo = isYes(args['demo']);
			force = isYes(args['force']);
			match.section = section;
			match.responseoffset = responseoffset;
			match.sectiontext = sectiontext;
			match.demo = demo;
			match.banner = getBanner(level, pagename, answered, demo, force);
			appendForm(selector[n], level, pagename, answered, force, match);
		}
		function onWikitextAndSectionsReceived(data) {
			var templates = /{{\s*(?:[Tt]emplate\s*:\s*)?([Ee]dit (?:semi-|template-)?protected)\s*(\|[^}]*)?}}/g;
			var matches = [], match;
			sections = data.parse.sections;
			wikitext = data.parse.wikitext['*'];
			while ((match = templates.exec(wikitext)) !== null) {
				matches.push(match);
			}
			if(selector.length != matches.length) {
				console.log('Sanity check failed: Expected to find ' + selector.length + ' edit request templates but instead found ' + matches.length + '. Are some commented out or wrapped in nowiki?');
				return;
			}
			matches.forEach(setupFieldsForTemplate);
		}
		if(selector.length) {
			new mw.Api().get( { action: 'parse', prop: 'sections|wikitext', oldid: mw.config.get('wgRevisionId') } ).done ( onWikitextAndSectionsReceived );
		}
	});
}
// </nowiki>