Jump to content

User:TheTVExpert/rmCloser.js: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Support non-default section headers
No edit summary
Line 151: Line 151:
var parsedDate;
var parsedDate;
var rmSection;
var rmSection;
var nextSection = "";
var nextSection = false;
var textToFind = text.split('\n');
var textToFind = text.split('\n');
for (var i = 0; i < textToFind.length; i++) {
for (var i = 0; i < textToFind.length; i++) {
Line 162: Line 162:
} else if(templateFound == true){
} else if(templateFound == true){
if (/ \(UTC\)/.test(line)){
if (/ \(UTC\)/.test(line)){
line = line.substring(line.indexOf("This is a contested technical request"));
parsedDate = line.match(/, ([0-9]{1,2} (January|February|March|April|May|June|July|August|September|October|November|December) [0-9]{4}) \(UTC\)/)[1];
parsedDate = line.match(/, ([0-9]{1,2} (January|February|March|April|May|June|July|August|September|October|November|December) [0-9]{4}) \(UTC\)/)[1];
break;
break;
Line 181: Line 182:
line = textToFind[i];
line = textToFind[i];
if (line.match(/^(==)[^=].+\1/)) {
if (line.match(/^(==)[^=].+\1/)) {
nextSection = line.match(/^(==)[^=].+\1/)[0];
nextSection = true;
var escapedLine = line.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
var regex = new RegExp('(' + escapedLine + ')(?![\s\S]*(' + escapedLine + '))', 'm');
text = text.replace(regex, '{{subst:RM bottom}}\n\n' + line);
break;
break;
}
}
Line 196: Line 200:
text = text.replace(/{{[Rr]equested move\/dated\|.*\n?[^\[]*}}/, "{{subst:RM top|'''" + result + ".'''" + closingComment + userGroupText +"}}");
text = text.replace(/{{[Rr]equested move\/dated\|.*\n?[^\[]*}}/, "{{subst:RM top|'''" + result + ".'''" + closingComment + userGroupText +"}}");


if (nextSection.length == 0) {
if (!nextSection) {
text += '\n{{subst:RM bottom}}';
text += '\n{{subst:RM bottom}}';
} else {
text = text.replace(nextSection, '{{subst:RM bottom}}\n\n' + nextSection);
}
}
Line 508: Line 510:
if(relistingComment != ''){
if(relistingComment != ''){
var nextSection = "";
var nextSection = false;
for (var i = templateIndex+1; i < textToFind.length; i++) {
for (var i = templateIndex+1; i < textToFind.length; i++) {
line = textToFind[i];
line = textToFind[i];
if (line.match(/^(==)[^=].+\1/)) {
if (line.match(/^(==)[^=].+\1/)) {
nextSection = line.match(/^(==)[^=].+\1/)[0];
nextSection = true;
var escapedLine = line.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
var regex = new RegExp('(' + escapedLine + ')(?![\s\S]*(' + escapedLine + '))', 'm');
text = text.replace(regex, ':<small>\'\'\'Relisting comment\'\'\': ' + relistingComment + ' ~~~~</small>\n\n' + line);
break;
break;
}
}
}
}


if (nextSection.length == 0) {
if (!nextSection) {
text += '\n:<small>\'\'\'Relisting comment\'\'\': ' + relistingComment + ' ~~~~</small>';
text += '\n:<small>\'\'\'Relisting comment\'\'\': ' + relistingComment + ' ~~~~</small>';
} else {
text = text.replace(nextSection, ':<small>\'\'\'Relisting comment\'\'\': ' + relistingComment + ' ~~~~</small>\n\n' + nextSection);
}
}
}
}
Line 709: Line 712:
var templateFound = false;
var templateFound = false;
var line;
var line;
var nextSection = "";
var nextSection = false;
var textToFind = discussionPageText.split('\n');
var textToFind = discussionPageText.split('\n');
for (var i = 0; i < textToFind.length; i++) {
for (var i = 0; i < textToFind.length; i++) {
Line 719: Line 722:
} else if(templateFound == true){
} else if(templateFound == true){
if (line.match(/^(==)[^=].+\1/)) {
if (line.match(/^(==)[^=].+\1/)) {
nextSection = line.match(/^(==)[^=].+\1/)[0];
nextSection = true;
var escapedLine = line.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
var regex = new RegExp('(' + escapedLine + ')(?![\s\S]*(' + escapedLine + '))', 'm');
if (wikiProjectsNotified.length == 1) {
var wikiProjectToNotify = wikiProjectsNotified[0];
discussionPageText = discussionPageText.replace(regex, ':<small>Note: [[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']] has been notified of this discussion. ~~~~</small>\n\n' + line);
} else {
var textToInsert = ':<small>Note: ';
for (var j=0; j<wikiProjectsNotified.length; j++) {
var wikiProjectToNotify = wikiProjectsNotified[j];
textToInsert += '[[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']]';
if (j == wikiProjectsNotified.length-2) {
if (wikiProjectsNotified.length == 2) {
textToInsert += ' and ';
} else {
textToInsert += ', and ';
}
} else if (j != wikiProjectsNotified.length-1) {
textToInsert += ', ';
}
}
textToInsert += ' have been notified of this discussion. ~~~~</small>\n\n';
discussionPageText = discussionPageText.replace(regex, textToInsert + line);
}
break;
break;
}
}
Line 725: Line 751:
}
}


if (nextSection.length == 0) {
if (!nextSection) {
if (wikiProjectsNotified.length == 1) {
if (wikiProjectsNotified.length == 1) {
var wikiProjectToNotify = wikiProjectsNotified[0];
var wikiProjectToNotify = wikiProjectsNotified[0];
Line 745: Line 771:
}
}
discussionPageText += ' have been notified of this discussion. ~~~~</small>';
discussionPageText += ' have been notified of this discussion. ~~~~</small>';
}
} else {
if (wikiProjectsNotified.length == 1) {
var wikiProjectToNotify = wikiProjectsNotified[0];
discussionPageText = discussionPageText.replace(nextSection, ':<small>Note: [[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']] has been notified of this discussion. ~~~~</small>\n\n' + nextSection);
} else {
var textToInsert = '\n:<small>Note: ';
for (var j=0; j<wikiProjectsNotified.length; j++) {
var wikiProjectToNotify = wikiProjectsNotified[j];
textToInsert += '[[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']]';
if (j == wikiProjectsNotified.length-2) {
if (wikiProjectsNotified.length == 2) {
textToInsert += ' and ';
} else {
textToInsert += ', and ';
}
} else if (j != wikiProjectsNotified.length-1) {
textToInsert += ', ';
}
}
textToInsert += ' have been notified of this discussion. ~~~~</small>\n\n';
discussionPageText = discussionPageText.replace(nextSection, textToInsert + nextSection);
}
}
}
}

Revision as of 22:51, 21 March 2024

//rmCloser
//<nowiki>
var rmCloser = {};
window.rmCloser = rmCloser;

$.when(
	mw.loader.using([ 'mediawiki.api', 'ext.gadget.morebits' ]),
	$.ready
).then(function() {
	if (document.getElementById("requestedmovetag") !== null && Morebits.pageNameNorm.indexOf("alk:") !== -1 && mw.config.get('wgCategories').includes('Requested moves') && !document.getElementById("wikiPreview") && mw.config.get('wgDiffOldId') == null) {
		document.getElementById("requestedmovetag").innerHTML = "<button id='rmCloserClose'>Close</button><button id='rmCloserRelist'>Relist</button><button id='rmCloserNotify'>Notify WikiProjects</button><span id='rmCloserRelistOptions' style='display:none'><input id='rmCloserRelistComment' placeholder='Relisting comment' oninput='if(this.value.length>20){this.size=this.value.length} else{this.size=20}'/><br><button id='rmCloserConfirm'>Confirm relist</button><button id='rmCloserCancel'>Cancel relist</button></span>";
		$('#rmCloserClose').click(rmCloser.callback);
		$('#rmCloserRelist').click(rmCloser.confirmRelist);
		$('#rmCloserConfirm').click(rmCloser.relist);
		$('#rmCloserCancel').click(rmCloser.cancelRelist);
		$('#rmCloserNotify').click(rmCloser.notify);
	}
});

rmCloser.confirmRelist = function rmCloserConfirmRelist(e) {
	if (e) e.preventDefault();
	document.getElementById("rmCloserRelistOptions").style.display = "inline";
	document.getElementById("rmCloserClose").style.display = "none";
	document.getElementById("rmCloserRelist").style.display = "none";
	document.getElementById("rmCloserNotify").style.display = "none";
};

rmCloser.cancelRelist = function rmCloserCancelRelist(e) {
	if (e) e.preventDefault();
	document.getElementById("rmCloserRelistOptions").style.display = "none";
	document.getElementById("rmCloserClose").style.display = "inline";
	document.getElementById("rmCloserRelist").style.display = "inline";
	document.getElementById("rmCloserNotify").style.display = "inline";
};

rmCloser.advert = ' using [[User:TheTVExpert/rmCloser|rmCloser]]';

rmCloser.callback = function rmCloserCallback(e) {
	if (e) e.preventDefault();

	rmCloser.Window = new Morebits.simpleWindow(600, 450);
	rmCloser.Window.setTitle( "Close requested move" );
	rmCloser.Window.setScriptName('rmCloser');
	rmCloser.Window.addFooterLink('RM Closing instruction', 'WP:RMCI');
	rmCloser.Window.addFooterLink('Script documentation', 'User:TheTVExpert/rmCloser');
	rmCloser.Window.addFooterLink('Give feedback', 'User talk:TheTVExpert/rmCloser');

	var form = new Morebits.quickForm(rmCloser.evaluate);
	
	var resultField = form.append({
		type: 'field',
		label: 'Result'
	});

	resultField.append({
		type: 'radio',
		name: 'result',
		list: [
			{
				label: 'Moved',
				value: 'moved',
				event: function() {
					document.getElementsByName('customResult')[0].style.display = 'none';
					document.getElementsByName('customResult')[0].required = false;
				}
			},
			{
				label: 'Not moved',
				value: 'not moved',
				event: function() {
					document.getElementsByName('customResult')[0].style.display = 'none';
					document.getElementsByName('customResult')[0].required = false;
				}
			},
			{
				label: 'No consensus',
				value: 'no consensus',
				event: function() {
					document.getElementsByName('customResult')[0].style.display = 'none';
					document.getElementsByName('customResult')[0].required = false;
				}
			},
			{
				label: 'Custom',
				value: 'custom',
				event: function() {
					document.getElementsByName('customResult')[0].style.display = 'inline';
					document.getElementsByName('customResult')[0].required = true;
				}
			}
		]
	});
	
	resultField.append({
		type: 'input',
		name: 'customResult'
	});

	var closingCommentField = form.append({
		type: 'field',
		label: 'Closing comment'
	});
	
	closingCommentField.append({
		type: 'textarea',
		name: 'closingComment'
	});
	
	form.append({ type: 'submit', label: 'Submit' });

	var formResult = form.render();
	rmCloser.Window.setContent(formResult);
	rmCloser.Window.display();
	
	document.getElementsByName('customResult')[0].style.display = 'none';
	document.getElementsByName('result')[0].required = true;
};

rmCloser.evaluate = function(e) {
	var form = e.target;
	rmCloser.params = Morebits.quickForm.getInputData(form);

	Morebits.simpleWindow.setButtonsEnabled(false);
	Morebits.status.init(form);

	var title_obj = mw.Title.newFromText(Morebits.pageNameNorm);
	rmCloser.title = title_obj.getSubjectPage().toText();
	rmCloser.talktitle = title_obj.getTalkPage().toText();
	
	var result = rmCloser.params.result;
	if(result == 'custom'){
		result = rmCloser.params.customResult;
	}
	
	var closingComment = rmCloser.params.closingComment;
	if(closingComment != ""){
		closingComment = ' ' + closingComment;
		closingComment = closingComment.replace(/\|/g, "{{!}}");
		closingComment = closingComment.replace(/=/g, "{{=}}");
	}

	var talkpage = new Morebits.wiki.page(rmCloser.talktitle, 'Closing move.');
	talkpage.load(function(talkpage) {
		var text = talkpage.getPageText();
		var template = text.match(/{{[Rr]equested move\/dated\|.*\n?[^\[]*}}/)[0];

		var templateFound = false;
		var numberOfMoves = 0;
		var line;
		var templateIndex = -1;
		var parsedDate;
		var rmSection;
		var nextSection = false;
		var textToFind = text.split('\n');
		for (var i = 0; i < textToFind.length; i++) {	
			line = textToFind[i];
			if(templateFound == false){
				if(/{{[Rr]equested move\/dated/.test(line)){
					templateFound = true;
					templateIndex = i;
				}
			} else if(templateFound == true){
				if (/ \(UTC\)/.test(line)){
					line = line.substring(line.indexOf("This is a contested technical request"));
					parsedDate = line.match(/, ([0-9]{1,2} (January|February|March|April|May|June|July|August|September|October|November|December) [0-9]{4}) \(UTC\)/)[1];
					break;
				} else if(/→/.test(line)){
					numberOfMoves++;
				}
			}
		}

		for (var i = templateIndex; i >= 0; i--) {
			line = textToFind[i];
			if (line.match(/^(==)[^=].+\1/)) {
				rmSection = line.match(/^(==)[^=](.+)\1/)[2].trim();
				break;
			}
		}

		for (var i = templateIndex+1; i < textToFind.length; i++) {
			line = textToFind[i];
			if (line.match(/^(==)[^=].+\1/)) {
				nextSection = true;
				var escapedLine = line.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
				var regex = new RegExp('(' + escapedLine + ')(?![\s\S]*(' + escapedLine + '))', 'm');
				text = text.replace(regex, '{{subst:RM bottom}}\n\n' + line);
				break;
			}
		}
		
		var userGroupText = "";
		if(Morebits.userIsInGroup('sysop')){
			userGroupText = "";
		} else if(Morebits.userIsInGroup('extendedmover')){
			userGroupText = "|pmc=y";
		} else{
			userGroupText = "|nac=y";
		}
		text = text.replace(/{{[Rr]equested move\/dated\|.*\n?[^\[]*}}/, "{{subst:RM top|'''" + result + ".'''" + closingComment + userGroupText +"}}");

		if (!nextSection) {
			text += '\n{{subst:RM bottom}}';
		}
		
		var multiMove = false;
		var moveSectionPlain = rmSection;
		
		var date = '|date=' + parsedDate;
		var from = '';
		if(result == "moved"){
			from = '|from=' + rmCloser.title;
		}
		var destination = template.match(/\|new1=(.*)\|current2=/);
		if(destination != null){
			multiMove = true;
			destination = destination[1];
		} else{
			destination = template.match(/\|(.*?)(?:\|.*)?}}/);
			if(destination != null){
				destination = destination[1];
			}
		}
		if(destination == "?"){
			destination = "";
		}
		
		var link = '|link=Special:Permalink/' + talkpage.getCurrentID() + '#' + moveSectionPlain;
		
		var archives = text.match(/{{[Aa]rchives/);
		if(archives == null){
			archives = text.match(/{{[Aa]rchive box/);
			if(archives == null){
				archives = text.match(/{{[Aa]rchivebox/);
				if(archives == null){
					archives = text.match(/==.*==/);
				}
			}
		}
		text = text.replace(archives[0], '{{old move'+ date + from + '|destination=' + destination + '|result=' + result + link +'}}\n\n' + archives[0]);
	
		talkpage.setPageText(text);
		talkpage.setEditSummary('Closing requested move; ' + result + rmCloser.advert);
		talkpage.save(Morebits.status.actionCompleted('Moved closed.'));
		
		if(multiMove == true){
			var otherDestinations = [];
			var otherPages = [];
			for(i=2; i<(numberOfMoves+1); i++){
				var text1 = "\\|current" + i + "=(.*)\\|new" + i;
				var reg1 = new RegExp(text1);
				var curr = template.match(reg1);
				var dest;
				if(i != numberOfMoves){
					var nextNum = i+1;
					var text2 = "\\|new" + i + "=(.*)\\|current" + nextNum;
					var reg2 = new RegExp(text2);
					dest = template.match(reg2);
				} else{
					var text3 = "\\|new" + i + "=(.*)\\|}}";
					var reg3 = new RegExp(text3);
					dest = template.match(reg3);
				}
				
				if(curr != null && dest != null){
					otherPages.push(curr[1].trim());
					otherDestinations.push(dest[1].trim());
				}
			}
			
			var pagesLeft = otherPages.length;
			for(var j=0; j<otherPages.length; j++){
				var otherTitle_obj = mw.Title.newFromText(otherPages[j]);
				rmCloser.otherTalktitle = otherTitle_obj.getTalkPage().toText();
				var otherPage = new Morebits.wiki.page(rmCloser.otherTalktitle, 'Adding {{old move}} to ' + rmCloser.otherTalktitle + '.');
				otherPage.load(function(otherPage) {
					var otherText = otherPage.getPageText();
					var title = mw.Title.newFromText(otherPage.getPageName()).getSubjectPage().toText();
					var OMcurr = otherPages[otherPages.indexOf(title)];
					var OMdest = otherDestinations[otherPages.indexOf(title)];
					var otherFrom = '';
					if(result == "moved"){
						otherFrom = '|from=' + OMcurr;
					}
					if(OMdest == "?"){
						OMdest == "";
					}
					var otherDestination = '|destination=' + OMdest;
					var otherArchives = otherText.match(/{{[Aa]rchives/);
					if(otherArchives == null){
						otherArchives = otherText.match(/{{[Aa]rchive box/);
						if(otherArchives == null){
							otherArchives = otherText.match(/{{[Aa]rchivebox/);
							if(otherArchives == null){
								otherArchives = otherText.match(/==.*==/);
							}
						}
					}
					otherText = otherText.replace(otherArchives[0], '{{old move'+ date + otherFrom + otherDestination + '|result=' + result + link +'}}\n\n' + otherArchives[0]);

					otherPage.setPageText(otherText);
					otherPage.setEditSummary('Closing requested move; ' + result + rmCloser.advert);
					otherPage.save(Morebits.status.actionCompleted('Moved closed.'));
					pagesLeft--;
				});
			}
			
			if(result == "moved"){
				var waitInterval = setInterval(function(){
					if(pagesLeft == 0){
						rmCloser.movePages(rmCloser.title,destination,otherPages,otherDestinations,moveSectionPlain);
						clearInterval(waitInterval);
					}
				}, 500);
			} else{
				setTimeout(function(){ location.reload() }, 2000);
			}
		} else if(result == "moved"){
			var emptyArray = [];
			rmCloser.movePages(rmCloser.title,destination,emptyArray,emptyArray,moveSectionPlain);
		} else{
			setTimeout(function(){ location.reload() }, 2000);	
		}
	});
};

rmCloser.movePages = function rmCloserMovePages(curr1,dest1,currList,destList,sectionTitle){
	var numberToRemove = currList.length+1;
	
	rmCloser.talktitle = mw.Title.newFromText(Morebits.pageNameNorm).getTalkPage().toText();
	var pageAndSection = rmCloser.talktitle + "#" + sectionTitle;
	var moveSummary = 'Moved per [[' + pageAndSection + ']]';
	var rmtrReason = 'Per [[' + pageAndSection + ']].';
	
	var form = new Morebits.quickForm();
	
	form.append({
		type: 'header',
		label: 'Move pages'
	});

	form.append({
		type: 'div',
		className: 'rmCloserMovePages' + curr1,
		label: curr1 + ' → ' + dest1
	});
	
	form.append({
		type: 'button',
		className: 'rmCloserMovePages' + curr1,
		label: 'Move directly',
		event: function() {
			rmCloser.directMove(curr1,dest1,false,moveSummary);
			for(var i=0; i<document.getElementsByClassName('rmCloserMovePages' + curr1).length; i++){
				document.getElementsByClassName('rmCloserMovePages' + curr1)[i].style.display = 'none';
			}
			numberToRemove--;
		}
	});
	
	if(!Morebits.userIsInGroup('sysop') && !Morebits.userIsInGroup('extendedmover')){
		form.append({
			type: 'button',
			className: 'rmCloserMovePages' + curr1,
			label: 'Submit technical request',
			event: function() {
				rmCloser.submitRMTR(curr1,dest1,rmtrReason);
				for(var i=0; i<document.getElementsByClassName('rmCloserMovePages' + curr1).length; i++){
					document.getElementsByClassName('rmCloserMovePages' + curr1)[i].style.display = 'none';
				}
				numberToRemove--;
			}
		});
	} else{
		form.append({
			type: 'button',
			className: 'rmCloserMovePages' + curr1,
			label: 'Move directly without leaving a redirect',
			event: function() {
				rmCloser.directMove(curr1,dest1,true,moveSummary);
				for(var i=0; i<document.getElementsByClassName('rmCloserMovePages' + curr1).length; i++){
					document.getElementsByClassName('rmCloserMovePages' + curr1)[i].style.display = 'none';
				}
				numberToRemove--;
			}
		});
	}
	
	for(var i=0; i<currList.length; i++){
		form.append({
			type: 'div',
			className: 'rmCloserMovePages' + currList[i],
			label: currList[i] + ' → ' + destList[i]
		});
		form.append({
			type: 'button',
			className: 'rmCloserMovePages' + currList[i],
			name: currList[i],
			extra: destList[i],
			label: 'Move directly',
			event: function() {
				rmCloser.directMove(this.name,this.extra,false,moveSummary);
				for(var j=0; j<document.getElementsByClassName('rmCloserMovePages' + this.name).length; j++){
					document.getElementsByClassName('rmCloserMovePages' + this.name)[j].style.display = 'none';
				}
				numberToRemove--;
			}
		});
		if(!Morebits.userIsInGroup('sysop') && !Morebits.userIsInGroup('extendedmover')){
			form.append({
				type: 'button',
				className: 'rmCloserMovePages' + currList[i],
				name: currList[i],
				extra: destList[i],
				label: 'Submit technical request',
				event: function() {
					rmCloser.submitRMTR(this.name,this.extra,rmtrReason);
					for(var j=0; j<document.getElementsByClassName('rmCloserMovePages' + this.name).length; j++){
						document.getElementsByClassName('rmCloserMovePages' + this.name)[j].style.display = 'none';
					}
					numberToRemove--;
				}
			});
		} else{
			form.append({
				type: 'button',
				className: 'rmCloserMovePages' + currList[i],
				name: currList[i],
				extra: destList[i],
				label: 'Move directly without leaving a redirect',
				event: function() {
					rmCloser.directMove(this.name,this.extra,true,moveSummary);
					for(var j=0; j<document.getElementsByClassName('rmCloserMovePages' + this.name).length; j++){
						document.getElementsByClassName('rmCloserMovePages' + this.name)[j].style.display = 'none';
					}
					numberToRemove--;
				}
			});
		}
	}

	var formResult = form.render();
	rmCloser.Window.setContent(formResult);
	rmCloser.Window.display();
	
	var moveInterval = setInterval(function(){
		if(numberToRemove == 0){
			rmCloser.Window.close();
			clearInterval(moveInterval);
			setTimeout(function(){ location.reload() }, 2000);
		}
	}, 500);
};

rmCloser.directMove = function rmCloserDirectMove(curr,dest,suppressRedirect,editSummary) {
	var pageToMove = new Morebits.wiki.page(curr, 'Moving ' + curr + ' to ' + dest + '.');
	pageToMove.setMoveDestination(dest);
	pageToMove.setMoveSubpages(true);
	pageToMove.setMoveTalkPage(true);
	pageToMove.setMoveSuppressRedirect(suppressRedirect);
	pageToMove.setEditSummary(editSummary + rmCloser.advert);
	pageToMove.move(Morebits.status.actionCompleted('Moved.'));
};

rmCloser.submitRMTR = function rmCloserSubmitRMTR(curr,dest,reason) {
	var rmtr = new Morebits.wiki.page('Wikipedia:Requested moves/Technical requests', 'Submitting request at WP:RM/TR');
	rmtr.load(function(page) {
		var text = rmtr.getPageText();
		var textToFind = /\n{1,}(==== ?Requests to revert undiscussed moves ?====)/i;
		var rmtrText = '{{subst:RMassist|1=' + curr + '|2=' + dest + '|reason=' + reason + '}}';
		text = text.replace(textToFind, '\n' + rmtrText + '\n\n$1');
		rmtr.setPageText(text);
		rmtr.setEditSummary('Add request' + rmCloser.advert);
		rmtr.save(Morebits.status.actionCompleted('Requested.'));
	});
};

rmCloser.relist = function rmCloserRelist(e) {
	if (e) e.preventDefault();
	var title_obj = mw.Title.newFromText(Morebits.pageNameNorm);
	rmCloser.talktitle = title_obj.getTalkPage().toText();
	var talkpage = new Morebits.wiki.page(rmCloser.talktitle, 'Relisting.');
	
	var relistingComment = document.getElementById('rmCloserRelistComment').value;
	
	talkpage.load(function(talkpage) {
		var text = talkpage.getPageText();

		var templateFound = false;
		var sig;
		var line;
		var templateIndex = -1;
		var textToFind = text.split('\n');
		for (var i = 0; i < textToFind.length; i++) {	
			line = textToFind[i];
			if(templateFound == false){
				if(/{{[Rr]equested move\/dated/.test(line)){
					templateFound = true;
					templateIndex = i;
				}
			} else if(templateFound == true){
				if (/ \(UTC\)/.test(line)){
					sig = line;
					break;
				}
			}
		}
		
		text = text.replace(sig, sig + " {{subst:RM relist}}");
		
		if(relistingComment != ''){
			var nextSection = false;
			for (var i = templateIndex+1; i < textToFind.length; i++) {
				line = textToFind[i];
				if (line.match(/^(==)[^=].+\1/)) {
					nextSection = true;
					var escapedLine = line.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
					var regex = new RegExp('(' + escapedLine + ')(?![\s\S]*(' + escapedLine + '))', 'm');
					text = text.replace(regex, ':<small>\'\'\'Relisting comment\'\'\': ' + relistingComment + ' ~~~~</small>\n\n' + line);
					break;
				}
			}

			if (!nextSection) {
				text += '\n:<small>\'\'\'Relisting comment\'\'\': ' + relistingComment + ' ~~~~</small>';
			}
		}
		
		talkpage.setPageText(text);
		talkpage.setEditSummary('Relisted requested move' + rmCloser.advert);
		talkpage.save(Morebits.status.actionCompleted('Relisted.'));
		document.getElementById("requestedmovetag").innerHTML = "";
		setTimeout(function(){ location.reload() }, 2000);
	});
};

rmCloser.notify = function rmCloserNotify(e) {
	if (e) e.preventDefault();
	var wikiProjectTemplates = document.getElementsByClassName("wpb-project_link");
	var wikiProjectNames = [];
	var wikiProjects = [];
	for(var i=0; i<wikiProjectTemplates.length; i++){
		var wikiProjectName = wikiProjectTemplates[i].innerHTML;
		var wikiProjectTalk = mw.Title.newFromText(wikiProjectTemplates[i].innerHTML).getTalkPage().toText();
		if (!wikiProjectNames.includes(wikiProjectName)) {
			wikiProjectNames.push(wikiProjectName);
			wikiProjects.push(wikiProjectTalk);
		}
	}

	var wikiProjectBannerShellHeaders = document.getElementsByClassName("wpb-header-combined");
	for (var i=0; i<wikiProjectBannerShellHeaders.length; i++) {
		var subprojectList = wikiProjectBannerShellHeaders[i];
		if (subprojectList.hasChildNodes() && subprojectList.children.length > 2) {
			subprojectList = subprojectList.children[2];
			if (subprojectList.hasChildNodes() && subprojectList.children.length > 0) {
				subprojectList = subprojectList.children;
				for (var j=0; j<subprojectList.length; j++) {
					var wikiProjectName = subprojectList[j].title;
					var wikiProjectTalk = mw.Title.newFromText(subprojectList[j].title).getTalkPage().toText();
					if (!wikiProjectNames.includes(wikiProjectName)) {
						wikiProjectNames.push(wikiProjectName);
						wikiProjects.push(wikiProjectTalk);
					}
				}
			}
		}
	}
	
	if(wikiProjects.length == 0){
		mw.notify('No WikiProject banners found on this page');
	} else{
		var Window = new Morebits.simpleWindow(600, 450);
		Window.setTitle( "Notify WikiProjects about requested move" );
		Window.setScriptName('rmCloser');
		Window.addFooterLink('Script documentation', 'User:TheTVExpert/rmCloser');
		Window.addFooterLink('Give feedback', 'User talk:TheTVExpert/rmCloser');

		var form = new Morebits.quickForm(rmCloser.notifyCheck);

		form.append({
			type: 'div',
			label: 'WikiProjects with banners on this page:'
		});

		form.append({
			type: 'checkbox',
			name: 'wikiProject',
			list: wikiProjects.map(function (wp) {
				var wplabel = wikiProjectNames[wikiProjects.indexOf(wp)];
				return { type: 'option', label: wplabel, value: wp };
			})
		});

		if(wikiProjects[0] != 'none'){
			form.append({ type: 'submit', label: 'Notify selected WikiProject(s)' });
		}

		var formResult = form.render();
		Window.setContent(formResult);
		Window.display();
	}
};

rmCloser.notifyCheck = function(e) {
	var form = e.target;
	rmCloser.params = Morebits.quickForm.getInputData(form);

	Morebits.simpleWindow.setButtonsEnabled(false);
	Morebits.status.init(form);
	
	var wikiProjectsToNotify = rmCloser.params.wikiProject;

	if (wikiProjectsToNotify.length == 0) {
		Morebits.status.error('Error', 'No WikiProjects selected');
	} else {
		var uniqueWikiProjects = [];
		var wikiProjectCount = 0;
		for (var i=0; i<wikiProjectsToNotify.length; i++) {
			var talkpage = new Morebits.wiki.page(wikiProjectsToNotify[i], 'Checking ' + wikiProjectsToNotify[i] + '.');
			talkpage.setFollowRedirect(true);
			talkpage.load(function(talkpage) {
				var wikiProjectToNotify = talkpage.getPageName();
				if (!uniqueWikiProjects.includes(wikiProjectToNotify)) {
					uniqueWikiProjects.push(wikiProjectToNotify);
				}
				wikiProjectCount++;
				if (wikiProjectCount == wikiProjectsToNotify.length && uniqueWikiProjects.length > 0) {
					rmCloser.notifyGetSection(uniqueWikiProjects);
				}
			});
		}
	}
};

rmCloser.notifyGetSection = function(wikiProjectsToNotify) {
	var title_obj = mw.Title.newFromText(Morebits.pageNameNorm);
	rmCloser.talktitle = title_obj.getTalkPage().toText();
	var talkpage = new Morebits.wiki.page(rmCloser.talktitle, 'Getting section.');
	
	talkpage.load(function(talkpage) {
		var text = talkpage.getPageText();
		var line;
		var templateIndex = -1;
		var rmSection;
		var textToFind = text.split('\n');
		for (var i = 0; i < textToFind.length; i++) {	
			line = textToFind[i];
			if(/{{[Rr]equested move\/dated/.test(line)){
				templateIndex = i;
				break;
			}
		}

		for (var i = templateIndex; i >= 0; i--) {
			line = textToFind[i];
			if (line.match(/^(==)[^=].+\1/)) {
				rmSection = line.match(/^(==)[^=](.+)\1/)[2].trim();
				break;
			}
		}

		rmCloser.notifyEvaluate(wikiProjectsToNotify, rmSection);
	});
};

rmCloser.notifyEvaluate = function(wikiProjectsToNotify, moveSection) {
	var wikiProjectsNotified = [];
	var wikiProjectCount = 0;
	for (var j=0; j<wikiProjectsToNotify.length; j++) {
		var talkpage = new Morebits.wiki.page(wikiProjectsToNotify[j], 'Notifying ' + wikiProjectsToNotify[j] + '.');
		talkpage.setFollowRedirect(true);
		talkpage.load(function(talkpage) {
			var wikiProjectToNotify = talkpage.getPageName();
			var text = talkpage.getPageText();
	
			rmCloser.talktitle = mw.Title.newFromText(Morebits.pageNameNorm).getTalkPage().toText();
			var pageAndSection = rmCloser.talktitle + "#" + moveSection;
			
			var notified;
			
			if(confirm("\"" + wikiProjectToNotify + "\" may have already been notified of the discussion. Do you wish to proceed?")){
				text += "\n\n== Requested move at [[" + pageAndSection + "]] ==\n[[File:Information.svg|30px|left]] There is a requested move discussion at [[" + pageAndSection + "]] that may be of interest to members of this WikiProject. ~~~~";

				talkpage.setPageText(text);
				talkpage.setEditSummary('Notifying of [[' + pageAndSection + '\|requested move]]' + rmCloser.advert);
				talkpage.save(Morebits.status.actionCompleted('Notified.'));
				notified = true;
			} else{
				var cancelNotify = new Morebits.status('Error', 'Notification canceled', 'error');
				notified = false;
			}
			
			if(notified){
				wikiProjectsNotified.push(wikiProjectToNotify);
			}
			
			wikiProjectCount++;

			if (wikiProjectCount == wikiProjectsToNotify.length && wikiProjectsNotified.length > 0) {
				rmCloser.notifyListOnTalkPage(wikiProjectsNotified);
			}
		});
	}
};

rmCloser.notifyListOnTalkPage = function(wikiProjectsNotified) {
	var discussionPage = new Morebits.wiki.page(rmCloser.talktitle, 'Adding note about notification to requested move');
	discussionPage.load(function(discussionPage) {
		var discussionPageText = discussionPage.getPageText();
		
		var templateFound = false;
		var line;
		var nextSection = false;
		var textToFind = discussionPageText.split('\n');
		for (var i = 0; i < textToFind.length; i++) {	
			line = textToFind[i];
			if(templateFound == false){
				if(/{{[Rr]equested move\/dated/.test(line)){
					templateFound = true;
				}
			} else if(templateFound == true){
				if (line.match(/^(==)[^=].+\1/)) {
					nextSection = true;
					var escapedLine = line.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
					var regex = new RegExp('(' + escapedLine + ')(?![\s\S]*(' + escapedLine + '))', 'm');
					if (wikiProjectsNotified.length == 1) {
						var wikiProjectToNotify = wikiProjectsNotified[0];
						discussionPageText = discussionPageText.replace(regex, ':<small>Note: [[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']] has been notified of this discussion. ~~~~</small>\n\n' + line);
					} else {
						var textToInsert = ':<small>Note: ';
						for (var j=0; j<wikiProjectsNotified.length; j++) {
							var wikiProjectToNotify = wikiProjectsNotified[j];
							textToInsert += '[[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']]';
							if (j == wikiProjectsNotified.length-2) {
								if (wikiProjectsNotified.length == 2) {
									textToInsert += ' and ';
								} else {
									textToInsert += ', and ';
								}
							} else if (j != wikiProjectsNotified.length-1) {
								textToInsert += ', ';
							}
						}
						textToInsert += ' have been notified of this discussion. ~~~~</small>\n\n';
						discussionPageText = discussionPageText.replace(regex, textToInsert + line);
					}
					break;
				}
			}
		}

		if (!nextSection) {
			if (wikiProjectsNotified.length == 1) {
				var wikiProjectToNotify = wikiProjectsNotified[0];
				discussionPageText+='\n:<small>Note: [[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']] has been notified of this discussion. ~~~~</small>';
			} else {
				discussionPageText += '\n:<small>Note: ';
				for (var j=0; j<wikiProjectsNotified.length; j++) {
					var wikiProjectToNotify = wikiProjectsNotified[j];
					discussionPageText += '[[' + wikiProjectToNotify + '|' + wikiProjectToNotify.slice(15) + ']]';
					if (j == wikiProjectsNotified.length-2) {
						if (wikiProjectsNotified.length == 2) {
							discussionPageText += ' and ';
						} else {
							discussionPageText += ', and ';
						}
					} else if (j != wikiProjectsNotified.length-1) {
						discussionPageText += ', ';
					}
				}
				discussionPageText += ' have been notified of this discussion. ~~~~</small>';
			}
		}

		discussionPage.setPageText(discussionPageText);
		discussionPage.setEditSummary('Added note about notifying WikiProject about requested move' + rmCloser.advert);
		discussionPage.save(Morebits.status.actionCompleted('Note added.'));
		setTimeout(function(){ location.reload() }, 2000);
	});
};
//</nowiki>