User:Terasail/Edit Request Tool.js: Difference between revisions

Content deleted Content added
Update after template change
Update
Line 1:
//<nowiki>
/*jshint esversion: 6*/
var rOS = 9; //Reply options start
var replyERT = {
semi: ["Semi", "semi", "1/1b/", "ESp|"],
extended: ["Extended", "extended", "8/8c/", "EEp|"],
template: ["Template", "template", "5/53/", "ETp|"],
full: ["Full", "fully", "4/44/", "EP|"],
"interface": ["Interface", "interface", "2/28/", "EIp|"],
"Close": ["", "Close", "Closed edit request"],
"Change": ["", "Close", "Changed level of protected edit request"],
"ChangeTarget": ["", "Close", "Changed target of protected edit request"],
"Remove": ["", "Remove", "Removed edit request"],
"Comment (No template)": ["", "speechBubbleAdd", "Comment"],
"Done": ["d", "checkAll", "Done"],
"Partly done:": ["pd", "check", "Partly done"],
"Already Done": ["a", "clock", "Already Done"],
"In progress: An editor is implementing the requested edit.": ["prog", "clock", "In progress"],
"Note:": ["note", "ellipsis", "Note"],
"Question:": ["q", "helpNotice", "Question"],
"Not done:": ["n", "notice", "Not done"],
"Not done for now:": ["nfn", "notice", "Not done for now"],
"Not done: it's not clear what changes you want to be made. Please mention the specific changes in a 'change X to Y' format and provide a reliable source if appropriate.": ["xy", "helpNotice", "Not done - Unclear request"],
"Not done: please provide reliable sources that support the change you want to be made.": ["rs", "link", "Not done - Needs reliable sources"],
"Not done for now: This is actually a controversial edit, so you'll need to discuss first with other editors. Please open a new section here and start a discussion.": ["c", "userGroup", "Not done for now - Requires consensus"],
"Not done: please make your requested changes to the template's sandbox first; see WP:TESTCASES.": ["sb", "linkExternal", "Not done - Use sandbox first"],
"Not done: this is the talk page for the page. Please make your request at the talk page for the article concerned.": ["mis", "ongoingConversation", "Not done - Misplaced"],
"Not done: this is the talk page for discussing improvements to the page. If possible, please make your request at the talk page for the article concerned.": ["tp", "ongoingConversation", "Not done - Misplaced"],
"Not done: According to the page's protection level you should be able to edit the page yourself. If you seem to be unable to, please reopen the request with further details.": ["hr", "unLock", "Not done - User can edit page"],
"Not done: The page's protection level has changed since this request was placed. You should now be able to edit the page yourself...": ["nlp", "unLock", "Not done - Page protection has changed"],
"Not done: {{Edit protected}} is usually not required for edits to the documentation or categories of templates using a documentation subpage.": ["doc", "code", "Not done"],
"Not done: requests for increases to the page protection level should be made at Wikipedia:Requests for page protection.": ["r", "editLock", "Not done - Use [[WP:RPP]]"],
"Not done: requests for decreases to the page protection level should be directed to the protecting admin or to Wikipedia:Requests for page protection.": ["ru", "editLock", "Not done - Use [[WP:RPP]]"],
"Not done: requests for recreating deleted pages protected against creation should be made at Wikipedia:Deletion review.": ["drv", "articleAdd", "Not done - Use [[WP:DRV]]"],
"Not done: page move requests should be made at Wikipedia:Requested moves.": ["m", "tableMoveColumnAfter", "Not done - Use [[WP:RM]]"],
"Not done: Please make your request for a new image to be uploaded to Files For Upload. Once the file has been properly uploaded, feel free to reactivate this request.": ["ffu", "imageLayoutFrameless", "Not done - Use [[WP:FFU]]"],
"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.": ["p", "userAdd", "Not done - Use [[WP:RFPERM]]"],
"Partially undone: This request has been partially undone.": ["pud","undo", "Partly undone"],
"Undone: This request has been undone.": ["ud", "undo", "Undone"]
};
 
function postEdit(wikitext, editSummary, pageName, secIndx) {
let api = new mw.Api();
Line 53 ⟶ 15:
}
 
function execute(currentBoxresponseTable, dataERT, replyOption, inputText, answered, boxType, targets) {//currentBox
OO.ui.confirm("Confirm in order to reply to this edit request.").done(function(confirmed) {
if (confirmed) {
//Change buttons toCreate label box +& loadingremove baraction buttons
let firstRow = responseTable.children[1].children[0];
let leftOOUI = currentBox.getElementsByClassName('mbox-image')[0].getElementsByClassName('oo-ui-widget');
firstRow.innerHTML = "";
if (leftOOUI.length > 1) {
leftOOUIresponseTable.children[5].children[0].remove();
}
leftOOUI[0].remove();
currentBox.children[2].remove();
let infoBox = new OO.ui.MessageWidget( {
icon: 'pageSettings',
Line 68 ⟶ 27:
label: 'Processing request — Edit request starting, getting section data to edit.'
});
infoBox.$element[0].style = "margin:5px 0; max-width:50em";
let firstRow = currentBox.getElementsByTagName('tr')[1].children[0];
$(firstRow).style = "padding-bottom:10px"append(infoBox.$element);
//Create loading bar
firstRow.innerHTML = "";
let progressBar = new OO.ui.ProgressBarWidget( {
progress: false
});
$(firstRow).append(progressBar.$element);
//Set preview for output
$(firstRow).append(infoBox.$element);
if (replyOption[0] != "") {//Don't preview a non-response
progressBar.$element[0].style = "margin:auto";
showOutput(inputText, replyOption, responseTable.children[4].children[0], dataERT, boxType);
infoBox.$element[0].style = "margin:10px auto 0px; max-width:50em";
}
//Find header
let header = "";
let curElement = currentBoxresponseTable.parentNode;
do {
curElement = curElement.previousElementSibling;
Line 96 ⟶ 56:
}).done(function(data) {
infoBox.setLabel("Processing request — Making changes to the edit request");
boxTypelet editTemplate = replyERT["{{Edit " + boxType] + "-protected";
let editTemplate = "{{Edit " + boxType[1] + "-protected";
if (answered) { answered = "yes"; } else { answered = "no"; }
for (let c3 = 0; c3 < targets.length; c3++) {
Line 128 ⟶ 87:
wikitext += ":";
}
if (replyOption[0] != "") { wikitext += "{{subst:" + dataERT.protections[boxType][31] + replyOption[0] + "}} "; }
if (inputText != "") { wikitext += inputText.replaceAll(/\s*~~~~\s*/g, "") + " "; }
wikitext += "~~~~";
Line 137 ⟶ 96:
}
infoBox.setType("success");
infoBox.setLabel("Processing '" + replyOption[2] + "' request — Saving changes to the talk page.");
secIndx = parseInt(secIndx.index);
if (newRev == mw.config.values.wgRevisionId) {
Line 151 ⟶ 110:
}
 
function addButtons(currentBox, dataERT, replyButton) {
let boxType = currentBox.parentElement.dataset.origlevel;
let replyListtableElem = ObjectcurrentBox.entries(replyERT)parentElement;
$('<table style="border:1px solid #A2A9B1; border-radius:2px; padding:12px 16px; margin:auto; max-width:55em; clear:both;"><tr><td style="color:#808080">Quick options:</td></tr><tr style="display: flex; justify-content: center;"><td></td></tr><tr><td style="color:#808080">Custom response:</td></tr><tr style="text-align:center;"><td></td></tr><tr style="background:#F6F6F6;"><td style="display:none;"><div style="color:#808080">Preview:</div><div></div></td></tr><tr style="margin-top:5px; display: flex; justify-content: right;"><td></td></tr></table>').insertAfter(tableElem);
let mainResponse = [[replyList[rOS + 9][1], "Unclear: X-Y", "Unclear request"], [replyList[rOS + 10][1], "WP:Reliable", "Needs reliable sources"], [replyList[rOS + 11][1], "Controversial", "This is a controversial change and requires consensus"]];
let responseTable = tableElem.nextElementSibling.children[0];
$(currentBox).append('<tr><td colspan="2"><div style="display: flex; justify-content: center;"></div></td></tr><tr style="display:none;"><td colspan=2 style="padding-bottom:10px; text-align:center"><div style="display: flex; justify-content: center;"></div></td></tr>');
let firstRow = currentBoxresponseTable.children[1].children[0].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
{data:"semi", label:"Semi protected edit request"},
{data:"extended", label:"Extended confirmed protected edit request"},
{data:"template", label:"Template protected edit request"},
{data:"full", label:"Fully protected edit request"},
{data:"interface", label:"Interface protected edit request"}
]
});
typeChange.$element[0].style = "text-align:left; margin:auto";
$(currentBox.children[2].children[0]secondRow).append(typeChange.$element);
//Create target page list
let boxLinks = currentBox.getElementsByClassName("mbox-text")[0].getElementsByClassName("external text");
Line 193 ⟶ 157:
selected: pageLinks
});
targetPages.$element[0].style = "text-align:left; margin:5px auto 5px auto";
$(currentBox.children[2].children[0]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 = 90; count < replyListresponses.length; count++) {
let newOption = new OO.ui.MenuOptionWidget({
label: replyListresponses[count][0],
icon: replyListresponses[count][1][1]
});
dropMenu.menu.addItems([newOption]);
}
responses = dataERT.response;
dropMenu.$element[0].style = "text-align:left; margin:0px";
$(currentBox.children[2].children[0]secondRow).append(dropMenu.$element);
dropMenu.on("labelChange", function() {
showOutput(inputText, responses[dropMenu.getLabel()], thirdRow, dataERT, typeChange.value);
});
//Create input box
let inputText = new OO.ui.MultilineTextInputWidget({autosize: true, rows:4, label: "AutomaticallyAdditional signedtext"});
inputText.$element[0].style = "margin:5px auto";
$(currentBox.children[2].children[0]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();
//Done
let doneB = new OO.ui.ButtonWidget( {
icon: "checkAll",
label: "Done",
flags: ["primary", "progressive"],
title: "Mark as done"
});
doneB.on("click", function() {
if (doneB.getLabel() == "Submit") {
if (typeof(replyERT[dropMenu.getLabel()]) != "undefined") {
execute(currentBox, replyERT[dropMenu.getLabel()], inputText.value, toggleAns.selected, typeChange.value, targetPages.getValue());
} else if (typeChange.value != typeChange.defaultValue) {
execute(currentBox, replyERT.Change, "", toggleAns.selected, typeChange.value, targetPages.getValue());
}
let newTargets = false;
let targets = targetPages.items;
if (targets.length == pageLinks.length) {
for(let item = 0; item < targets.length; item++) {
if (targets[item].data != pageLinks[item]) { newTargets = true; }
}
} else {
newTargets = true;
}
if (newTargets) {
execute(currentBox, replyERT.ChangeTarget, "", toggleAns.selected, typeChange.value, targetPages.getValue());
}
} else {
execute(currentBox, replyERT.Done, "", toggleAns.selected, typeChange.defaultValue, targetPages.getValue());
}
});
hzLayoutT.addItems([doneB]);
mainResponse.forEach(function(item) {
item[3] = new OO.ui.ButtonWidget({
label: item[1],
title: item[2]
});
item[3].on("click", function() {
execute(currentBox, item[0], "", toggleAns.selected, typeChange.defaultValue, targetPages.getValue());
});
hzLayoutT.addItems([item[3]]);
});
//Respond
let respondB = new OO.ui.ButtonWidget( {
icon: "add",
label: "More",
title: "Extra response options"
});
respondB.on("click", function() {
if (respondB.getIcon() == "add") {
currentBox.children[2].style = "";
doneB.setLabel("Submit");
doneB.setTitle("Submit response");
respondB.setIcon("subtract");
respondB.setLabel("Less");
} else {
currentBox.children[2].style = "display:none";
inputText = "";
doneB.setLabel("Done");
doneB.setTitle("Mark as done");
respondB.setIcon("add");
respondB.setLabel("More");
}
});
hzLayoutT.addItems([respondB]);
//Toggle answer button
let toggleAns = new OO.ui.CheckboxInputWidget({selected: true});
hzLayoutT.addItems([toggleAns, new OO.ui.LabelWidget({label: "Answered"})]);
//Create firstrow fieldset
let fieldsetT = new OO.ui.FieldsetLayout();
fieldsetT.addItems([new OO.ui.FieldLayout(new OO.ui.Widget({content:[hzLayoutT]}))]);
// Add an horizontal field layout
fieldsetT.addItems( [ new OO.ui.FieldLayout( new OO.ui.Widget( { content: [hzLayoutT] } ) ) ] );
$(firstRow).append(fieldsetT.$element);
//CloseRemove requestbutton
let 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, replyERT.Close, "", true, typeChange.defaultValue, targetPages.getValue());
});
if (currentBox.parentElement.attributes[2].localName != "data-origlevel") {
$(currentBox.children[0].children[0]).append(closeB.$element);
}
//Remove request
let remove = new OO.ui.ButtonWidget( {
icon: "trash",
Line 307 ⟶ 197:
title: "Delete entire section!"
});
remove.$element[0].style = "margin:10px";
remove.on("click", function() {
execute(currentBoxresponseTable, replyERTdataERT, nonResponses.Remove, "", null, typeChange.defaultValue, targetPages.getValue());
});
hzLayoutT.addItems([remove]);
$(currentBox.children[0].children[0]).append(remove.$element);
//Open & Close button
}
if (currentBox.parentElement.attributes[2].localName != "data-origlevel") {
 
let closeB = new OO.ui.ButtonWidget( {
function addRButton(currentBox) {
icon: "unFlag",
let boxType = replyERT[currentBox.parentElement.dataset.origlevel];
invisibleLabel: true,
let openB = new OO.ui.ButtonWidget( {
icon title: "editMark as answered",
});
flags: "progressive",
closeB.on("click", function() {
invisibleLabel: true,
execute(responseTable, dataERT, nonResponses.Close, "", true, typeChange.defaultValue, targetPages.getValue());
title: "Add response / reopen"
});
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());
});
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());
});
hzLayoutT.addItems([newButton]);
}
//Toggle answer button
let toggleAns = new OO.ui.CheckboxInputWidget({selected: true});
hzLayoutT.addItems([toggleAns, new OO.ui.LabelWidget({label: "Answered"})]);
//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() {
openB.$element[0].style = "margin-top:2px";
replyButton.setDisabled(false);
openB.on("click", function() {
openBresponseTable.$elementparentElement.remove();
});
currentBox.parentElement.className = "plainlinks tmbox tmbox-notice editrequest";
$(fourthRow).append(cancelB.$element);
let imgSrc = boxType[0] + "-protection-shackle.svg";
//Submit response button
let origImg = currentBox.getElementsByTagName("img")[0];
let submitB = new OO.ui.ButtonWidget( {
let img = origImg.outerHTML.slice(0, origImg.outerHTML.match(/\d\//).index);
icon: "checkAll",
img += boxType[2] + imgSrc + "/60px-" + imgSrc + '.png" height="60" width="60" style="margin-top:5px">';
flags: ["primary", "progressive"],
origImg.outerHTML = img;
label: "Submit",
let mboxText = currentBox.children[0].children[1];
title: "Submit the response"
mboxText.style = "font-size:120%; text-align:center;";
});
mboxText.innerHTML = mboxText.innerHTML.replace(/ Set.*\/b>/i, '<br/>Uncheck the "answered" checkbox and use a reply option');
submitB.on("click", function() {
addButtons(currentBox);
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;
if (typeof(newResponse) != "undefined") {
execute(responseTable, dataERT, newResponse, newText, isAns, newType, newTargets);
} else if (typeChange.value != typeChange.defaultValue) {
execute(responseTable, dataERT, nonResponses.ChangeLevel, "", isAns, newType, newTargets);
}
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);
}
});
$(currentBox.children[0].children[0]fourthRow).append(openBsubmitB.$element);
}
 
function showOutput(inputText, replyOption, tableRow, dataERT, template) {
var restTransform = "https://en.wikipedia.org/api/rest_v1/transform/wikitext/to/html";
let preview = "";
let newText = inputText.value;
if (typeof(inputText) == 'string') {
newText = inputText;
}
template = dataERT.protections[template][1];
if (typeof(replyOption) != "undefined") {
preview += "{{" + template + replyOption[0] + "}} ";
}
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 = " [[User:" + nickname + "|" + nickname + "]] ([[User talk:" + nickname + "|talk]])";
}
let timeNow = new Date();
timeNow = timeNow.toLocaleDateString('en-GB', { year: 'numeric', month: 'long', day: 'numeric', hour:'2-digit', minute: '2-digit'}).split(" at ");
preview += nickname + " " + timeNow[1] + ", " + timeNow[0] + " (UTC)";
$.post(restTransform, 'wikitext=' + 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;";
}
}
 
var editRequestBoxes = document.getElementsByClassName("plainlinks tmbox tmbox-notice editrequest");
if (editRequestBoxes.length != 0) {
var jsonERTURL = "https://en.wikipedia.org/w/index.php?title=User:Terasail/Edit_Request_Test.json&action=raw&ctype=text/json";
mw.loader.using(["oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows"]).done(function() {
$.getJSON(jsonERTURL, function(dataERT) {
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"]);
mw.loader.using(["oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows"]).done(function() {
for (let i = 0; i < editRequestBoxes.length; i++) {
mw.loader.load(["oojs-ui.styles.icons-layout", "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"]);
let currentBox = editRequestBoxes[i].children[0]; //The tbody tag for the box
for (let i = 0; i < editRequestBoxes.length; i++) {
if (editRequestBoxes[i].id != "") {
let currentBox = editRequestBoxes[i].children[0]; //The tbody tag for the box
addButtons(currentBox);
let isSmall = false;
} else if (currentBox.getElementsByTagName("code").length == 2) { //Check that it is a closed protected edit request
if (editRequestBoxes[i].id == "") {
addRButton(currentBox);
isSmall = true;
}
let replyButton = new OO.ui.ButtonWidget( {
icon: "recentChanges",
flags: ["progressive"],
label: "Respond",
invisibleLabel: isSmall,
title: "Respond to the edit request."
});
replyButton.on("click", function() {
addButtons(currentBox, dataERT, replyButton);
replyButton.setDisabled(true);
});
replyButton.$element[0].style = "margin:2px 0";
if (isSmall) {
$(currentBox.children[0].children[0]).append(replyButton.$element);
} else {
$(currentBox).append('<tr><td colspan=2><div style="display: flex; justify-content: center;"></div></td></tr>');
$(currentBox.children[1].children[0].children[0]).append(replyButton.$element);
}
}
});
});
}