User:Terasail/Edit Request Test.js

// /*jshint esversion: 6*/ var editRequestBoxes = document.getElementsByClassName("plainlinks tmbox tmbox-notice editrequest"); var pageWatchers = "There are currently "; var watchStatus; var dataERT; var commentERT; var api = new mw.Api; var pageNameERT = mw.config.values.wgPageName; var encodePageName = encodeURIComponent(pageNameERT);

function postEdit(wikitext, editSummary, secIndx, changeWatch, watchlist) { let apiParams = { action: 'edit', title: pageNameERT, text: wikitext, section: secIndx, summary: editSummary, watchlist: changeWatch };	let reloadURL = "/w/index.php?title=" + encodePageName + "&type=revision&diff=cur&oldid=prev"; if (changeWatch == "watch") { apiParams.watchlistexpiry = watchlist; }	if (wikitext == "") { if (typeof(commentERT) != 'undefined' && commentERT.search(/-(?=[0-9]{14}","type)/) != -1) { OO.ui.confirm("Do you want to add an empty edit request notice to the users talk page?").done(function(confirmed) {				if (confirmed) {					let commenter = commentERT.slice(commentERT.indexOf('"name"') + 10, commentERT.search(/-(?=[0-9]{14}","type)/));					let talkParams = dataERT.emptyNotice;					talkParams.title = "User talk:" + commenter;					talkParams.sectiontitle += pageNameERT;					talkParams.text = talkParams.text.replace("```", pageNameERT);					talkParams.summary = talkParams.summary.replace("```", pageNameERT);					api.postWithEditToken(talkParams).done(function(result) { //Do something here? });				}				api.postWithEditToken(apiParams).done(function(result) { window.location = reloadURL; });			}); }	} else { api.postWithEditToken(apiParams).done(function(result) { window.location = reloadURL; }); } }

function execute(responseTable, dataERT, replyOption, inputText, answered, boxType, targets, changeWatch, watchlist) { OO.ui.confirm("Confirm in order to reply to this edit request.").done(function(confirmed) {		if (confirmed) {			//Create label box & remove action buttons			let firstRow = responseTable.children[1].children[0];			firstRow.innerHTML = "";			responseTable.children[5].children[0].remove;			let infoBox = new OO.ui.MessageWidget( { icon: 'pageSettings', type: 'notice', label: 'Processing request — Edit request starting, getting section data to edit.' });			infoBox.$element[0].style = "margin:5px 0; max-width:50em";			$(firstRow).append(infoBox.$element);			//Create loading bar			let progressBar = new OO.ui.ProgressBarWidget( { progress: false });			$(firstRow).append(progressBar.$element);			//Set preview for output			if (replyOption[0] != "") {//Don't preview a non-response				showOutput(inputText, replyOption, responseTable.children[4].children[0], dataERT, boxType);			}			//Find header			let header = "";			let curElement = responseTable.parentNode;			do {				curElement = curElement.previousElementSibling;				if (curElement.getElementsByClassName("mw-headline").length == 1) {					header = curElement.getElementsByClassName("mw-headline")[0].id;				}			}			while (header == "");			api.get( { action: "parse", page: pageNameERT, prop: "sections" }).done(function(data) { infoBox.setLabel("Processing request — Making changes to the edit request"); let editTemplate = "{{Edit " + boxType + "-protected"; if (answered) { answered = "yes"; } else { answered = "no"; } for (let c3 = 0; c3 < targets.length; c3++) { editTemplate += "|" + targets[c3]; }				editTemplate += "|answered=" + answered; let sections = data.parse.sections; let secIndx = sections[0]; for (let j = 0; j < sections.length; j++) { if (sections[j].anchor == header) { secIndx = parseInt(sections[j].index); }				}				api.get( {					action: "parse",					page: pageNameERT,					section: secIndx,					prop: "wikitext|revid"				}).done(function(data) {					let wikitext = data.parse.wikitext["*"];					let newRev = data.parse.revid;					wikitext = wikitext.replace(/{{ *([SETFI]PER|Edit([ -]?[A-Z]+[ -]?|[- ])Protected)\s*[^}}]*/i, editTemplate);					let editSummary = "/* " + header.replaceAll("_", " ") + " */ " + replyOption[2] + " (Edit Request Tool)";					if (replyOption[1] != "Close") {						wikitext = wikitext.trim + "\n:";						if (replyOption[0] != "") { wikitext += "{{subst:" + dataERT.protections[boxType][1] + replyOption[0] + "}} "; }						if (inputText != "") { wikitext += inputText.replaceAll(/\s*~\s*/g, "") + " "; }						wikitext += "~";						if (replyOption[1] == "Remove") {							commentERT = document.getElementById(header).dataset.mwComment; wikitext = ""; editSummary = editSummary.replace(/[^]+\*\/ /, ""); }					}					infoBox.setType("success"); infoBox.setLabel("Processing request — Saving changes to the talk page."); if (newRev == mw.config.values.wgRevisionId) { postEdit(wikitext, editSummary, secIndx, changeWatch, watchlist); } else { OO.ui.confirm("There has been a new revision to the page, do you wish to continue?").done(function(revCon) {							if (revCon) { postEdit(wikitext, editSummary, secIndx, changeWatch, watchlist); }						}); }				});			});		}	}); }

function addButtons(currentBox, replyButton) { let boxType = currentBox.parentElement.dataset.origlevel; boxType = boxType.replace("full", "fully"); let tableElem = currentBox.parentElement; $(' ').insertAfter(tableElem); let responseTable = tableElem.nextElementSibling.children[0]; let firstRow = responseTable.children[1].children[0]; let secondRow = responseTable.children[3].children[0]; let thirdRow = responseTable.children[4].children[0]; let fourthRow = responseTable.children[5].children[0]; let protections = Object.entries(dataERT.protections); let responses = Object.entries(dataERT.response); let quickResponses = Object.entries(dataERT.quickResponse); let nonResponses = dataERT.nonResponse; //Create type change dropdown let tcOptions = []; for (let i = 0; i < protections.length; i++) { tcOptions.push({data: protections[i][0], label: protections[i][1][0]}); }	let typeChange = new OO.ui.DropdownInputWidget( {		value: boxType,		options: tcOptions	}); typeChange.on("change", function {		submitB.setDisabled(false);	}); typeChange.$element[0].style = "text-align:left; margin:auto"; $(secondRow).append(typeChange.$element); //Create target page list let boxLinks = currentBox.getElementsByClassName("mbox-text")[0].getElementsByClassName("external text"); let pageLinks = []; if (boxLinks.length > 0) {//Open request for(let c1 = 0; c1 < boxLinks.length; c1++) { if (boxLinks[c1].parentElement.tagName == "LI" || boxLinks[c1].parentElement.tagName == "B") { pageLinks[pageLinks.length] = boxLinks[c1].innerHTML; }		}	} else {//Closed request boxLinks = currentBox.getElementsByClassName("mbox-text")[0].getElementsByTagName("A"); for(let c2 = 1; c2 < boxLinks.length; c2++) { pageLinks[pageLinks.length] = boxLinks[c2].title; }		if (pageLinks.length == 0) { pageLinks = pageNameERT.replace(/(_talk|Talk:)/, "").replaceAll("_", " "); }	}	let targetPages = new OO.ui.TagMultiselectWidget( {		placeholder: 'Target Pages',		allowArbitrary: true,		selected: pageLinks	}); targetPages.on("change", function {		submitB.setDisabled(false);	}); targetPages.$element[0].style = "text-align:left; margin:5px auto"; $(secondRow).append(targetPages.$element); //Create dropdown menu let dropMenu = new OO.ui.DropdownWidget( {		label: "Select reply option - Add additional text below",		menu: {items: []}	}); for (let count = 0; count < responses.length; count++) { let newOption = new OO.ui.MenuOptionWidget({			label: responses[count][0],			icon: responses[count][1][1]		}); dropMenu.menu.addItems([newOption]); }	responses = dataERT.response; dropMenu.$element[0].style = "text-align:left; margin:0px"; $(secondRow).append(dropMenu.$element); dropMenu.on("labelChange", function {		submitB.setDisabled(false);		showOutput(inputText, responses[dropMenu.getLabel], thirdRow, dataERT, typeChange.value);	}); //Create input box let inputText = new OO.ui.MultilineTextInputWidget({autosize: true, rows:4, label: "Additional text"}); inputText.$element[0].style = "margin:5px auto"; $(secondRow).append(inputText.$element); inputText.on("change", function(newText) {		showOutput(inputText, responses[dropMenu.getLabel], thirdRow, dataERT, typeChange.value);	}); //Create top horizontal layout let hzLayoutT = new OO.ui.HorizontalLayout; //Create firstrow fieldset let fieldsetT = new OO.ui.FieldsetLayout; fieldsetT.addItems([new OO.ui.FieldLayout(new OO.ui.Widget({content:[hzLayoutT]}), {align: 'top' })]); $(firstRow).append(fieldsetT.$element); //Remove button let remove = new OO.ui.ButtonWidget( { 		icon: "trash",		flags: ["primary", "destructive"],		invisibleLabel: true,		title: "Delete entire section!"	}); remove.on("click", function {		execute(responseTable, dataERT, nonResponses.Remove, "", null, typeChange.defaultValue, targetPages.getValue, "nochange", "");	}); hzLayoutT.addItems([remove]); //Open & Close button if (currentBox.parentElement.attributes[2].localName != "data-origlevel") { let closeB = new OO.ui.ButtonWidget( { 			icon: "unFlag",			invisibleLabel: true,			title: "Mark as answered"		}); closeB.on("click", function {			execute(responseTable, dataERT, nonResponses.Close, "", true, typeChange.defaultValue, targetPages.getValue, "nochange", "");		}); hzLayoutT.addItems([closeB]); } else { let openB = new OO.ui.ButtonWidget( { 			icon: "flag",			invisibleLabel: true,			title: "Mark as unanswered"		}); openB.on("click", function {			execute(responseTable, dataERT, nonResponses.Open, "", false, typeChange.defaultValue, targetPages.getValue, "nochange", "");		}); hzLayoutT.addItems([openB]); }	//Create quick response buttons for (let i = 0; i < quickResponses.length; i++) { let newButton = new OO.ui.ButtonWidget({			label: quickResponses[i][1][0],			flags: quickResponses[i][1][1],			title: quickResponses[i][1][2]		}); newButton.on("click", function {			execute(responseTable, dataERT, responses[quickResponses[i][0]], "", toggleAns.selected, typeChange.defaultValue, targetPages.getValue, "nochange", "");		}); hzLayoutT.addItems([newButton]); }	//Toggle answer button let toggleAns = new OO.ui.CheckboxInputWidget({selected: true}); hzLayoutT.addItems([toggleAns, new OO.ui.LabelWidget({label: "Answered"})]); //Create lastrow horizontal layout let hzLayoutB = new OO.ui.HorizontalLayout; //hzLayoutB.$element[0].style = "display: flex;"; //Create lastrow fieldset let fieldsetB = new OO.ui.FieldsetLayout; fieldsetB.addItems([new OO.ui.FieldLayout(new OO.ui.Widget({content:[hzLayoutB]}), {align: 'top' })]); $(fourthRow).append(fieldsetB.$element); //Cancel response button let cancelB = new OO.ui.ButtonWidget( { 		icon: "cancel",		flags: ["destructive"],		label: "Cancel",		framed: false,		title: "Cancel the response & close menu"	}); cancelB.on("click", function {		replyButton.setDisabled(false);		responseTable.parentElement.remove;	}); hzLayoutB.addItems([cancelB]); let isWatched = (typeof(watchStatus[0]) != "undefined"); //Watch list//Toggle answer button let toggleWL = new OO.ui.CheckboxInputWidget({selected: isWatched}); let toggleWLLable = new OO.ui.LabelWidget({label: "Watch this page"}); toggleWL.on("change", function(newStatus) {		watchDropdown.setDisabled(!newStatus);	}); toggleWLLable.$element[0].style = "white-space: nowrap;"; hzLayoutB.addItems([toggleWL, toggleWLLable]); let watchValue = "never"; let watchOptions = [{data: "never", label: "Permanent"}, {data: "1 day", label: "1 day"}, {data: "3 days", label: "3 days"}, {data: "1 week", label: "1 week"}, {data: "1 month", label: "1 month"}]; let wlExpiry = watchStatus[1]; if (typeof(wlExpiry) != "undefined") { let daysDif = Math.ceil((new Date(wlExpiry).getTime - Date.now)/1000/60/60/24); watchOptions.unshift({data: "nochange", label: daysDif + " days"}); watchValue = wlExpiry; }	//Create WLDropdown horizontal layout let hzLayoutWLD = new OO.ui.HorizontalLayout; hzLayoutB.addItems([hzLayoutWLD]); //Watchlist dropdown let watchDropdown = new OO.ui.DropdownInputWidget( {		value: watchValue,		options: watchOptions,		disabled: !isWatched	}); hzLayoutWLD.addItems([watchDropdown]); //Submit response button let submitB = new OO.ui.ButtonWidget( { 		icon: "checkAll",		flags: ["primary", "progressive"],		label: "Submit",		title: "Submit the response",		disabled: true	}); submitB.on("click", function {		let newResponse = responses[dropMenu.getLabel];		let newText = inputText.value;		let isAns = toggleAns.selected;		let newType = typeChange.value;		let newTargets = targetPages.getValue;		let targets = targetPages.items;		let targetChange = false;		let wlChange = toggleWL.selected;		let wlVals = watchDropdown.value;		if (wlChange) {			wlChange = "watch";			if (wlVals == "nochange") {				wlChange = "nochange";			}		} else {			wlChange = "unwatch";		}		if (typeof(newResponse) != "undefined") {			execute(responseTable, dataERT, newResponse, newText, isAns, newType, newTargets, wlChange, wlVals);		} else if (typeChange.value != typeChange.defaultValue) {			execute(responseTable, dataERT, nonResponses.ChangeLevel, "", isAns, newType, newTargets, wlChange, wlVals);		}		if (targets.length == pageLinks.length) {			for(let item = 0; item < targets.length; item++) { if (targets[item].data != pageLinks[item]) { targetChange = true; } }		} else { targetChange = true; }		if (targetChange) { execute(responseTable, dataERT, nonResponses.ChangeTarget, "", isAns, newType, newTargets, wlChange, wlVals); }	});	hzLayoutB.addItems([submitB]); }

function showOutput(inputText, replyOption, tableRow, dataERT, template) { var restTransform = "https://en.wikipedia.org/api/rest_v1/transform/wikitext/to/html/" + encodePageName; let preview = ""; let newText = inputText.value; if (typeof(inputText) == 'string') { newText = inputText; }	template = dataERT.protections[template][1]; if (typeof(replyOption) != "undefined") { preview += " "; }	if (newText != "" && typeof(newText) != "undefined") { preview += newText + " "; } if (preview != "") { let nickname = " " + mw.user.options.values.nickname; if (nickname == " ") {//Create default signature if no nickname nickname = mw.user.getName; nickname = " " + nickname + " (talk)"; }		let dateObj = new Date; let dateNow = dateObj.toLocaleDateString('en-GB', { timeZone: 'UTC', year: 'numeric', month: 'long', day: 'numeric'}); let timeNow = dateObj.toLocaleTimeString('en-GB', { timeZone: 'UTC', hour: '2-digit', minute: '2-digit' }); preview += nickname + " " + timeNow + ", " + dateNow + " (UTC)"; preview = preview.replaceAll(/{{subst:/gi, "{{"); $.post(restTransform, 'wikitext=' + encodeURIComponent(preview) + '&body_only=true',			function(html) {				if (inputText.value != "" || typeof(replyOption) != "undefined") {//Stops preview appearing with empty input box					tableRow.style = "padding:8px 1em 2px;";					tableRow.children[1].innerHTML = html;				}			}		); } else { tableRow.style = "display:none;"; } }

if (editRequestBoxes.length != 0) { let pageID = mw.config.values.wgArticleId; api.get({		action: "query",		prop: "info",		pageids: pageID,		inprop: "watchers|visitingwatchers|watched",		format: "json"	}).done(function(data) {		data = data.query.pages[pageID];		let watchers = data.watchers;		let visiting = data.visitingwatchers;		watchStatus = [data.watched, data.watchlistexpiry];		if (typeof(watchers) == "undefined") {			pageWatchers += "less than 30";		} else {			pageWatchers += watchers;		}		pageWatchers += " users watching this page ("; if (typeof(visiting) == "undefined") { pageWatchers += "0"; } else { pageWatchers += visiting; }		pageWatchers += " have viewed recent edits).";	}); var jsonERTURL = "https://en.wikipedia.org/w/index.php?title=User:Terasail/Edit_Request_Test.json&action=raw&ctype=text/json"; $.getJSON(jsonERTURL, function(newData) {		dataERT = newData;		mw.loader.load(["oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows"]);		mw.loader.load(["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 (let i = 0; i < editRequestBoxes.length; i++) { let currentBox = editRequestBoxes[i].children[0]; //The tbody tag for the box if (typeof(currentBox.parentElement.dataset.origlevel) != "undefined") { let isSmall = false; if (editRequestBoxes[i].id == "") { isSmall = true; }			let replyButton = new OO.ui.ButtonWidget( { 				icon: "edit",				flags: ["progressive"],				label: "Respond",				invisibleLabel: isSmall,				title: "Respond to the edit request."			}); replyButton.on("click", function {				addButtons(currentBox, replyButton);				replyButton.setDisabled(true);			}); replyButton.$element[0].style = "margin:2px 0"; if (isSmall) { $(currentBox.children[0].children[0]).append(replyButton.$element); } else { $(currentBox).append('  '); $(currentBox.children[1].children[0].children[0]).append(replyButton.$element); }		}	} } //