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 03:39, 15 February 2014 (improve form). 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: Although this page is protected, your user rights currently allow you to edit it yourself.'] , // TODO make dynamic
			// TODO add s,t,u
			[ 'nlp', 'Not done: This page is no longer protected. Subject to consensus, you should be able to edit it yourself.' ],
			[ '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'), matches = [], sections, wikitext, elemNum = -1;
		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) {
			return '{{edit ' + templateLevel[level] + 'protected|' + (pagename === '' ? '<!-- Page to be edited -->' : pagename) + '|answered=' + (answered ? 'yes' : 'no') + (demo == '1' ? '|demo=yes}}' : '}}');
		}
		function getResponse(level, template, free) {
			return "\n:" + (template === '' ? '' : responseLevel[level] + template + '}} ') + (free === '' ? '' : free + ' ') + '~~' + "~~\n";
		}
		function onclickEditProtectedResponseLink(e)
		{
			var n = e.data;
			this.innerHTML = 'Processing...';
			this.disabled = true;
			var match = matches[n], responseoffset = match.responseoffset, sectiontext = match.sectiontext, newsectiontext, form = document.forms['editProtectedHelper-' + n];
			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);
			// 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;
			}
			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() {
						location.reload();
					}).fail(console.log);
				});
			}
			return false;
		}
		function appendForm(obj, level, pagename, answered) {
			var form = $('<form class="editProtectedHelper" name="editProtectedHelper-' + ++elemNum + '" 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> ');
			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 button = $('<button type="button">Submit</button>').click(elemNum, onclickEditProtectedResponseLink);
			form.append(button);
			$(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) {
			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']);
			appendForm(selector[n], level, pagename, answered);
			matches[n].section = section;
			matches[n].responseoffset = responseoffset;
			matches[n].sectiontext = sectiontext;
			matches[n].demo = demo;
			matches[n].banner = getBanner(level, pagename, answered, demo);
		}
		function onWikitextAndSectionsReceived(data) {
			var templates = /{{\s*(?:[Tt]emplate\s*:\s*)?([Ee]dit (?:semi-|template-)?protected)\s*(\|[^}]*)?}}/g;
			var 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>