User:GKFX/Edit Request Tool.js

From Wikipedia, the free encyclopedia
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>
var responseOptions = [
["ntmp", "speechBubbleAdd", "Comment", "Comment (No template)"],
["d", "checkAll", "Done", "Done"],
["pd", "check", "Partly done", "Partly done:"],
["a", "clock", "Already Done", "Already Done"],
["q", "helpNotice", "Question", "Question:"],
["note", "ellipsis", "Note", "Note:"],
["n", "notice", "Not done", "Not done:"],
["nfn", "notice", "Not done for now", "Not done for now:"],
["c", "userGroup", "Not done - Needs consensus", "Not done for now: please establish a consensus for this alteration before using the edit protected template."],
["rs", "link", "Not done - Needs reliable sources", "ND: please provide reliable sources that support the change you want to be made."],
["xy", "helpNotice", "Not done - Unclear request", "ND: it's not clear what changes you want to be made. Please mention the specific changes in a 'change X to Y' format."],
["sb", "linkExternal", "Not done - Use sandbox first", "ND: please make your requested changes to the template's sandbox first; see WP:TESTCASES."],
["mis", "ongoingConversation", "Not done", "ND: this is the talk page for the template ESp. Make your request at the article talk page."],
["tp", "ongoingConversation", "Not done", "ND: this is the talk page for the template ESp. (More info - Talk page protected)"],
["hr", "unLock", "Not done", "ND: According to the page's protection level you should be able to edit the page."],
["nlp", "unLock", "Not done", "ND: The page's protection level has changed since this request was placed."],
["doc", "code", "Not done", "ND: requests are usually not required for edits to the documentation or categories of templates."],
["drv", "articleAdd", "Not done", "ND: requests for recreating deleted pages protected against creation should be made at 'WP:DRV'."],
["r", "editLock", "Not done", "ND: requests for increases to the page protection level should be made at 'WP:RPP'."],
["ru", "editLock", "Not done", "ND: requests for decreases to the page protection level should be directed to 'WP:RPP'."],
["ffu", "imageLayoutFrameless", "Not done", "ND: Please make your request for a new image to be uploaded to Files For Upload."],
["p", "userAdd", "Not done", "ND: this is not the right page to request additional user rights."],
["m", "tableMoveColumnAfter", "Not done", "ND: page move requests should be made at Wikipedia:Requested moves."],
["udp","undo", "Partly undone", "Undone: This request has been partially undone."], 
["ud", "undo", "Undone", "Undone: This request has been undone."]];

function execute(currentBox, selectedReply, inputText, boxType, answered) {
	if (confirm("Confirm in order to reply to this edit request.")) {
		//Change buttons to label box + loading bar
		var leftOOUI = currentBox.getElementsByClassName('mbox-image')[0].getElementsByClassName('oo-ui-widget');
		if (leftOOUI.length > 1) {
			leftOOUI[0].remove();
		}
		leftOOUI[0].remove();
		currentBox.children[2].remove();
		var infoBox = new OO.ui.MessageWidget( {
			icon: 'pageSettings',
			type: 'notice',
			label: 'Processing request — Edit request starting, getting section data to edit.'
		});
		var firstRow = currentBox.getElementsByTagName('tr')[1].children[0];
		firstRow.innerHTML = "";
		var progressBar = new OO.ui.ProgressBarWidget( {
			progress: false
		});
		$(firstRow).append(progressBar.$element);
		$(firstRow).append(infoBox.$element);
		progressBar.$element[0].style = "margin:auto";
		infoBox.$element[0].style = "margin:10px auto 0px; max-width:50em";
		//Find header
		var header = "";
		var curElement = currentBox.parentNode;
		do {
			curElement = curElement.previousElementSibling;
			if (curElement.getElementsByClassName("mw-headline").length == 1) {
				header = curElement.getElementsByClassName("mw-headline")[0].id;
			}
		}
		while (header == "");
		var api = new mw.Api();
		api.get( {
			action: "parse",
			page: mw.config.values.wgPageName,
			prop: "sections",
		}).done(function(data) {
			infoBox.setLabel("Processing request — Making changes to the edit request");
			var sections = data.parse.sections;
			var sectionNum = -1;
			var offset = 0;
			for (var j = 0; j < sections.length; j++) {
				if (sections[j].anchor == header) {
					sectionNum = j + 1;
					sectionNum -= offset;
				}
				if (sections[j].fromtitle != mw.config.values.wgPageName) {
					offset++;
				}
			}
			infoBox.setLabel("Processing request — Getting information from section: " + sectionNum + ".");
			api.get( {
				action: "parse",
				page: mw.config.values.wgPageName,
				prop: "wikitext",
				section: sectionNum
			}).done( function(data) {
				infoBox.setLabel("Processing request — Making changes to the edit request.");
				var wikitext = data.parse.wikitext["*"];
				if (answered) {
					if (wikitext.search("answered=") > 0) {
						wikitext = wikitext.replace("answered=no", "answered=yes");
					} else {
						wikitext = wikitext.replace("}}", "|answered=yes}}");
					}
				} else {
					wikitext = wikitext.replace("answered=yes", "answered=no");
				}
				var editSummary = "/* " + header.replaceAll("_", " ") + " */ ";
				if (selectedReply == "REMOVE") {
					wikitext = "";
					editSummary = "Removed edit request";
					selectedReply = -1;
				} else if (selectedReply == "CLOSEREQ") {
					editSummary += "Closed edit request";
					selectedReply = -1;
				} else {
					if (selectedReply == 0) { //Do not add response template
						wikitext += "\n:" + inputText.value;
					} else {
						wikitext += "\n:{{subst:";
						wikitext += boxType[3] + responseOptions[selectedReply][0] + "}}";
						if (inputText != "") {
							wikitext += " " + inputText.value;
						}
					}
					wikitext += " ~~~~";
					editSummary += responseOptions[selectedReply][2];
				}
				editSummary += " ([[User:Terasail/Edit_Request_Tool|Edit Request Tool]])";
				infoBox.setType("success");
				if (selectedReply != -1) {
					infoBox.setLabel("Processing '" + responseOptions[selectedReply][2] + "' request — Saving changes to the talk page.");
				}
				api.postWithEditToken({
					action: 'edit',
					title: mw.config.values.wgPageName,
					text: wikitext,
					section: sectionNum,
					summary: editSummary
				}).done(function(result) {
					window.location = "https" + "://en.wikipedia.org/w/index.php?title=" + mw.config.values.wgPageName + "&type=revision&diff=cur&oldid=prev";
				});
			});
		});
	}
}

function addButtons(currentBox, boxType) {
	var mainResponse = [[10, "Unclear: X-Y", ""], [9, "WP:Reliable", ""], [8, "WP:Consensus", ""]];
	currentBox.insertAdjacentHTML('beforeend', '<tr><td colspan=2 style="padding-bottom:10px"><div style="display: flex; flex-wrap:wrap;justify-content: center;"></div></td></tr><tr style="display:none;"><td colspan=2 style="padding-bottom:10px; text-align:center"></td></tr>');
	var firstRow = currentBox.children[1].children[0].children[0];
	//Create dropdown menu
	var dropMenu = new OO.ui.DropdownWidget( {
		label: "Select reply option -  Add additional text below",
		menu: {items: []}
	});
	responseOptions.forEach(function(item) {
		var newOption = new OO.ui.MenuOptionWidget({
			label: item[3],
			icon: item[1]
		});
		dropMenu.menu.addItems(newOption);
	});
	dropMenu.$element[0].style = "text-align:left; margin:0px";
	$(currentBox.children[2].children[0]).append(dropMenu.$element);
	//Create input box
	var inputText = new OO.ui.MultilineTextInputWidget({autosize: true, label: "'~~" + "~~" + "' is automatically added"});
	inputText.$element[0].style = "margin:auto";
	$(currentBox.children[2].children[0]).append(inputText.$element);
	//Done
	var dB = new OO.ui.ButtonWidget( {
		icon: "checkAll",
		label: "Done",
		flags: ["primary", "progressive"],
		title: "Mark as done"
	});
	dB.on("click", function() {
		if (dB.getLabel() == "Submit") {
			var dropMenuAns = dropMenu.getLabel();
			for (var k = 0; k < responseOptions.length; k++) {
				if (responseOptions[k][3] == dropMenuAns) {
					execute(currentBox, k, inputText, boxType, toggleAns.isSelected());
				}
			}
		} else {
			execute(currentBox, 1, inputText, boxType, toggleAns.isSelected());
		}
	});
	$(firstRow).append(dB.$element);
	mainResponse.forEach(function(item) {
		item[2] = new OO.ui.ButtonWidget({
			label: item[1]
		});
		item[2].on("click", function() {
			execute(currentBox, item[0], "", boxType, toggleAns.isSelected());
		});
		$(firstRow).append(item[2].$element);
	});
	//Respond
	var respondB = new OO.ui.ButtonWidget( {
		icon: "add",
		label: "Other"
	});
	respondB.on("click", function() {
		if (respondB.getIcon() == "add") {
			currentBox.children[2].style = "";
			dB.setLabel("Submit");
			respondB.setIcon("subtract");
		} else {
			inputText = "";
			dB.setLabel("Done");
			respondB.setIcon("add");
			currentBox.children[2].style = "display:none";
		}
		mainResponse.forEach(function(item) {
			item[2].disabled = !item[2].disabled;
			item[2].updateDisabled();
		});
	});
	$(firstRow).append(respondB.$element);
	//Toggle answer button
	var toggleAns = new OO.ui.CheckboxInputWidget({selected: true});
	toggleAns.on("toggle", function() {
		toggleAns.setIcon(toggleAns.isSelected() ? "check" : "close");
	});
	var toggleAnsWrapper = (new OO.ui.FieldLayout(toggleAns,
		{label: "Close", title: "Close when responding", align: "inline"})).$element;
	toggleAnsWrapper[0].style.margin = "auto 0";
	$(firstRow).append(toggleAnsWrapper);
	//Close request
	var closeB = new OO.ui.ButtonWidget( { 
		icon: "unFlag",
		invisibleLabel: true,
		title: "Mark as closed"
	});
	closeB.$element[0].style = "margin:10px 10px 0px";
	closeB.on("click", function() {
		execute(currentBox, "CLOSEREQ", "", boxType, true);
	});
	if (currentBox.parentElement.attributes[2].localName != "data-origlevel") {
		$(currentBox.children[0].children[0]).append(closeB.$element);
	}
	//Remove request
	var remove = new OO.ui.ButtonWidget( { 
		icon: "trash",
		flags: ["primary", "destructive"],
		invisibleLabel: true,
		title: "Delete whole section (e.g. spam)"
	});
	remove.$element[0].style = "margin:10px";
	remove.on("click", function() {
		execute(currentBox, "REMOVE", "", boxType, null);
	});
	$(currentBox.children[0].children[0]).append(remove.$element);
}

function addRButton(currentBox, boxType) {
	var openB = new OO.ui.ButtonWidget( { 
		icon: "edit",
		flags: ["progressive"], 
		invisibleLabel: true,
		title: "Re-open request interface"
	});
	openB.$element[0].style = "margin-top:2px";
	openB.on("click", function() {
		openB.$element.remove();
		currentBox.parentElement.className = "plainlinks tmbox tmbox-notice editrequest";
		var img = currentBox.getElementsByTagName("img")[0];
		img.src = img.src.replace("1/1d/Information_icon4.svg/30px-Information_icon4", boxType[2] + boxType[0] + "-protection-shackle.svg/60px-" + boxType[0] + "-protection-shackle");
		img.srcset = img.src.replaceAll("1/1d/Information_icon4.svg/30px-Information_icon4", boxType[2] + boxType[0] + "-protection-shackle.svg/60px-" + boxType[0] + "-protection-shackle");
		img.height = 60;
		img.width = 60;
		img.style = "margin:5px";
		currentBox.children[0].children[1].style = "font-size:100%";
		currentBox.children[0].children[1].innerHTML = '<div style="text-align:center; font-weight:700">Add a reply to this edit request by using the reply buttons.</div><div>This template must be followed by a complete and specific description of the request, that is, specify what text should be removed and a verbatim copy of the text that should replace it. "Please change X" is not acceptable and will be rejected; the request must be of the form "please change X to Y".</div>';
		addButtons(currentBox, boxType);
	});
	$(currentBox.children[0].children[0]).append(openB.$element);
}

var editRequestBoxes = document.getElementsByClassName("plainlinks tmbox tmbox-notice editrequest");
if (editRequestBoxes.length != 0) {
	mw.loader.using(["oojs-ui-core", "oojs-ui-widgets"]).done(function() {
		mw.loader.load(["oojs-ui.styles.icons-alerts", "oojs-ui.styles.icons-interactions", "oojs-ui.styles.icons-moderation", "oojs-ui.styles.icons-user", "oojs-ui.styles.icons-content", "oojs-ui.styles.icons-editing-core", "oojs-ui.styles.icons-editing-advanced"]);
		for (var i = 0; i < editRequestBoxes.length; i++) {
			var pLevel = [["Semi", "SPER", "1/1b/", "ESp|"], ["Extended", "EPER", "8/8c/", "EEp|"], ["Template", "TPER", "5/53/", "ETp|"], ["Full", "FPER", "4/44/", "EP|"], ["Interface", "IPER", "2/28/", "EIp|"]];
			var currentBox = editRequestBoxes[i].children[0]; //The tbody tag for the box
			var boxType = editRequestBoxes[i].dataset.origlevel;
			pLevel.forEach(function(item) {
				if (boxType == item[0].toLowerCase()) {
					boxType = item;
				}
			});
			if (editRequestBoxes[i].id != "") {
				addButtons(currentBox, boxType);
			} else if (currentBox.getElementsByTagName("code").length == 2) { //Check that it is a closed protected edit request
				addRButton(currentBox, boxType);
			}
		}
	});
}
//</nowiki>