User:SD0001/RFUD-helper.js

/** * * Script to easily respond to requests made at Wp:Requests for undeletion * (WP:RFUD). When accepting a request, the script would do the following: * - Post a response below the request * - Undelete the page * - Remove any deletion tags from the page * - Undelete the talk page if it existed * - Offer to userfy the page instead of restoring to source * - Offer to draftify the page instead of restoring to source * - Adds to talk page if undoing an AfD soft deletion * - If is a WT:AFC subpage, move it to draft namespace * * In addition, a preview of the deleted page's last version is shown below * Special:Undelete, and when you follow the red link. */

//

/* jshint maxerr: 999 */ /* globals Morebits */

(function {

if ((!mw.config.get('wgCurRevisionId') && $('.mw-undelete-subtitle').length) ||	(mw.config.get('wgCanonicalSpecialPageName') === 'Undelete' && $('.mw-undelete-revlist').length) ) { mw.loader.using('mediawiki.api').then(showDeletedPagePreview); return; }

if (mw.config.get('wgPageName') !== 'Wikipedia:Requests_for_undeletion') { return; }

$.when(	mw.loader.using([ 'mediawiki.util', 'mediawiki.api', 'mediawiki.Title', 'mediawiki.Uri', 'ext.gadget.morebits' ]),	$.ready ).then(function {

var rfud = {}; window.rfud = rfud;

rfud.advert = ' (rfud-helper)'; Morebits.wiki.api.setApiUserAgent('w:en:User:SD0001/RFUD-helper.js');

var pageName;

var params = {}; rfud.params = params;

rfud.callback = function(e) { e.preventDefault; pageName = e.target.parentElement.childNodes[1].title.slice(17).replace(/_/g, ' ');

var $template_element = $(e.target).parent.parent.parent; var $header_div = $template_element.prev; while (!$header_div.hasClass('mw-heading')) { $header_div = $header_div.prev; if ($header_div.length === 0) { // Avoid an infinite loop, fail gracefully mw.notify("Failed to identify section heading", {title: 'RFUD-helper', type: 'error'}); return; }	}	rfud.$header_container = $header_div; var $header_element = $header_div.find('h2'); var $heading_element = $header_element.children(".mw-headline").length ? $header_element.children(".mw-headline") : // Following Heading_HTML_changes, and in Parsoid $header_element; rfud.sectionName = $heading_element[0].id.replace(/_/g, ' '); // Detect requesting user var sig_span = $header_div.nextUntil('.mw-heading').find('.ext-discussiontools-init-replylink-buttons').get(0); var mw_thread_id = $(sig_span).data('mw-thread-id'); if (mw_thread_id) { var userMatch = /c-(.+?)-20/g.exec(mw_thread_id); if (userMatch) { rfud.requestingUser = userMatch[1].replace(/_/g, ' '); } else { rfud.requestingUser = null; }	} else { rfud.requestingUser = null; }	var buttonResponse = e.target.classList[1].slice('rfud-'.length);

var Window = new Morebits.simpleWindow(700, 500); Window.setTitle("Respond to undeletion request of " + pageName); Window.setScriptName("RFUD helper"); Window.addFooterLink("Administrator instructions", "Wikipedia:Requests for undeletion/Administrator instructions"); // Window.addFooterLink( "Script documentation", "WP:RFUDHELPER" );

var form = new Morebits.quickForm(rfud.evaluate);

if (pageName === 'Page name goes here') { form.append({			type: 'div',			label: Morebits.htmlNode('div', 'Caution: Accepting this will undelete "Page name goes here", please fix the template usage before proceeding.', 'red')		}); }	// pageName will never have underscores as it part of the mediawiki-generated link title // rfud.sectionName could have underscores if user entered them, hence normalize while comparing else if (pageName !== rfud.sectionName.replace(/_/g, ' ')) { form.append({			type: 'div',			label: Morebits.htmlNode('div', 'Note: page name used in template is different from the section name', '#d7280e')		}); }

var field = form.append({		type: 'field',		label: 'Response'	});

field.append({		type: 'radio',		name: 'response',		list: [			{				label: 'Accept',				value: 'accept',				checked: buttonResponse === 'accept'			},			{				label: 'Decline',				value: 'decline',				checked: buttonResponse === 'decline'			}		],		event: rfud.toggleResponse	});

form.append({		type: 'field',		label: 'Work area',		name: 'work_area'	});

var previewlink = document.createElement('a'); previewlink.addEventListener('click', function {		rfud.preview(result); // `result` is defined below	});

previewlink.style.cursor = "pointer"; previewlink.textContent = 'Preview'; form.append({ type: 'div', id: 'rfudpreview', label: [ previewlink ] }); form.append({ type: 'div', id: 'rfud-previewbox', style: 'display: none' });

form.append({ type: 'submit' });

var result = form.render; Window.setContent(result); Window.display; $(result).find('textarea').css('font-size', '130%');

result.previewer = new Morebits.wiki.preview(document.getElementById('rfud-previewbox'));

// Init the controls var evt = document.createEvent("Event"); evt.initEvent('change', true, true); result.response[buttonResponse === 'accept' ? 0 : 1].dispatchEvent(evt);

};

rfud.toggleResponse = function(e) { var form = e.target.form; var work_area;

if (e.target.value === 'accept') {

work_area = new Morebits.quickForm.element({			type: 'field',			label: 'Accept request',			name: 'work_area'		});

var permanent_section_link = 'Special:Permalink/' + mw.config.get('wgRevisionId') + '#' + rfud.sectionName; work_area.append({			type: 'input',			label: 'Undeletion summary',			name: 'logsummary',			tooltip: 'Summary for the deletion log',			size: '66px',			value: 'Undelete per request at WP:RFUD'		}); var titleObj = mw.Title.newFromText(pageName);

if (titleObj && titleObj.namespace !== 2 && titleObj.namespace !== 6) { work_area.append({				type: 'checkbox',				list: [ {					label: 'Userfy this page',					name: 'userfy',					value: 'userfy',					checked: false,					subgroup: [ {						type: 'input',						label: 'Userfy to: ',						name: 'page',						size: '60px',						tooltip: 'User page to which the page is to be moved',						value: 'User:' + (rfud.requestingUser || 'USERNAME') + '/' + pageName.replace(/^Draft:/, )								.replace(/^Wikipedia talk:Articles for creation\//, )					}, {						type: 'checkbox',						list: [ {							label: 'Suppress redirect',							name: 'sredr',							checked: true						} ]					} ],					event: function(e) {						if (e.target.checked) {							var userfypagefield = form['userfy.page'];							if (userfypagefield.value.indexOf('USERNAME') !== -1) {								userfypagefield.setSelectionRange('User:'.length, 'User:USERNAME'.length);								userfypagefield.focus;							}							if (form.movetodraft) { form.movetodraft.checked = false; form.movetodraft.disabled = true; }							if (form.draftify && form.draftify.checked) { form.draftify.click; // need to trigger the event listener as well }							if (form.undeletetalk) { form.undeletetalk.checked = false; form.undeletetalk.disabled = true; }							form.template.value = ''; } else { $('.UNDtemplateinput').parent.remove; // remove deleting admin prompt from if (form.movetodraft) { form.movetodraft.disabled = false; }							if (form.undeletetalk) { form.undeletetalk.disabled = false; }							form.template.value = ''; }					}				} ]			});			}		if (pageName.startsWith('Wikipedia talk:Articles for creation/')) {			work_area.append({ type: 'checkbox', list: [ { label: 'Move to draft namespace', name: 'movetodraft', value: 'movetodraft', checked: true } ]			});

} else if (titleObj && titleObj.namespace !== 118 && titleObj.namespace !== 6) { work_area.append({				type: 'checkbox',				list: [ {					label: 'Draftify this page',					name: 'draftify',					value: 'draftify',					checked: false, 					subgroup: [ {						type: 'input',						label: 'To: ',						name: 'page',						size: '60px',						tooltip: 'Draft page to which the page is to be moved',						value: 'Draft:' + pageName					}, {						type: 'checkbox',						list: [ {							label: 'Suppress redirect',							name: 'draftifysredr',							checked: true						} ]					} ],					event: function (e) {						if (e.target.checked) {							if (form.userfy && form.userfy.checked) {								form.userfy.click; // need to trigger the event listener as well							}							if (form.undeletetalk) { // TODO: undelete and move the talk page too								form.undeletetalk.checked = false;								form.undeletetalk.disabled = true;							}							form.template.value = ;						} else {							form.template.value = ; if (form.undeletetalk) { form.undeletetalk.disabled = false; }						}					}				} ]			});			} 		if (titleObj && !titleObj.isTalkPage) {			work_area.append({ type: 'checkbox', list: [ { label: 'Undelete talk page if it existed', name: 'undeletetalk', value: 'undeletetalk', checked: true } ]			});		}

if (titleObj.namespace === 6) { work_area.append({				type: 'checkbox',				list: [ {					label: 'Add ',					name: 'addF5',					value: 'addF5',					checked: false,					tooltip: 'While restoring files deleted under CSD F5, tick this option unless the file has already been de-orphaned or you plan to do it after restoring it',					event: function(e) {						if (e.target.checked) {							form.template.value = ;						} else {							form.template.value = ;						}					}				} ]			}); }

} else if (e.target.value === 'decline') {

work_area = new Morebits.quickForm.element({			type: 'field',			label: 'Decline request',			name: 'work_area'		});

}

var template_responses = work_area.append({		type: 'select',		label: 'Select a template response: ',		name: 'template',		event: rfud.responseTemplateChanged	});

$.each(rfud.template_responses[e.target.value], function(i, el) {		template_responses.append({ type: 'option', value: i, label: (i ? i + ': ' : '') + el, selected: /^(Done|Not done)$/.test(el) });	});

work_area.append({		type: 'textarea',		label: 'Comments',		tooltip: 'Any comments in addition to the template response',		name: 'comments'	}); work_area.append({		type: 'checkbox',		list: [ {			label: 'Ping requesting user',			name: 'pinguser',			value: 'pinguser',			checked: true,			subgroup: rfud.requestingUser ? [] : [ {				type: 'input',				label: 'User: ',				name: 'pingusername',				size: '50px',				tooltip: 'Name of requesting user could not be auto-detected, you can fill this in manually'			} ]		} ]	});

var old_area = form.work_area; var result = work_area.render; old_area.replaceWith(result);

};

rfud.template_responses = { accept: { '': "No template response", '': "Done", '': "contested proposed deletion", '': "contested soft deletion", '': "draft deleted under G13", '': "for G13s where was used and the draft was submitted and declined", '': "for G13s where was used and where the draft was never submitted", '': "for G13s of draft namespace pages never part of the AfC process", '': "for files being restored and tagged as ", '': "Userfied", '': "Userfied A7 article, contact admin before moving back", // has subgroup '': "Draftified",

},	decline: { '': "No template response", '': "Not done", '': "Not done and will not be done", '': "Was undeleted once, not worked on (soft-decline)", '': "No deleted page with this name", '': "Company article failing NCORP", '': "Biographical article failing NBIO", '': "Inappropriate topic for Wikipedia", '': "Blatant advertisement", '': "Article deleted at a discussion", // has subgroup '': "Article deleted per CSD criteria", // has subgroup '': "Copyright violation", // has subgroup

} };

rfud.responseTemplateChanged = function(e) { var template = e.target.value; $('.UNDtemplateinput').parent.remove;

var newInput; if (template === '') { var newInput1 = new Morebits.quickForm.element({			type: 'input',			label: 'Discussion: ',			name: 'discussion',			size: '70px',			className: 'UNDtemplateinput',			value: 'Autofilling...'		}); var newInput2 = new Morebits.quickForm.element({			type: 'input',			label: 'Closing admin: ',			name: 'closingadmin',			className: 'UNDtemplateinput',			value: 'Autofilling...'		}); $(e.target.form).find('h5').before(newInput1.render, newInput2.render); } else if (template ===  || template === ) { newInput = new Morebits.quickForm.element({			type: 'input',			label: 'Deleting admin: ',			name: 'deletingadmin',			className: 'UNDtemplateinput',			value: 'Autofilling...'		}); $(e.target.form).find('h5').before(newInput.render); } else if (template === '') { newInput = new Morebits.quickForm.element({			type: 'input',			label: 'Copyvio source: ',			name: 'copyviosource',			size: '70px',			className: 'UNDtemplateinput'		}); $(e.target.form).find('h5').before(newInput.render); }

if (template ===  || template === ) { if (e.target.form.userfy.checked === false) { e.target.form.userfy.click; e.target.value = template; // the click above will reset select value to 		} }	if (template === '') { if (e.target.form.draftify.checked === false) { e.target.form.draftify.click; }	}

if (template ===  || template === ) { // Auto-fill the name of deleting admin by parsing the deletion log var admininputbox = $('input.UNDtemplateinput[name=deletingadmin]')[0]; rfud.getDeletionLog.done(function(html) {			var userlink = $(html).find('.mw-logline-delete .mw-userlink')[0];			if (userlink) {				admininputbox.value = userlink.textContent;			} else {				admininputbox.value = '';			}		}) .fail(function {			admininputbox.value = '';		}); } else if (template === '') { // Auto-fill parameters by parsing the deletion log var xfdinputbox = $('input.UNDtemplateinput[name=discussion]')[0]; var closingadmininputbox = $('input.UNDtemplateinput[name=closingadmin]')[0]; rfud.getDeletionLog.done(function(html) {			var xfd, closingadmin;			$(html).find('.mw-logline-delete .comment a').each(function { if (/^Wikipedia:(?:Articles|Redirects|Templates|Categories|Files|Miscellany) for (?:deletion|discussion)/.test(this.title)) { xfd = this.title; closingadmin = $(this).parent.parent.find('.mw-userlink')[0].textContent; return false; // break }			});			xfdinputbox.value = xfd || ;			closingadmininputbox.value = closingadmin || ;		}) .fail(function {			xfdinputbox.value = ;			closingadmininputbox.value = ;		}); } };

rfud.getResponseWikitext = function(forPreview) { var templatetext = params.template.replace(/^\{\{/,  + params.discussion + , parameterText + '}}');

var separator = ''; if (params.comments) { // these templates don't have any text (other than bolded stuff) if (params.template ===  ||			params.template ===  ||			params.template === '') { separator = ' '; } else { separator = '\n\n'; if (!forPreview) { separator += ':'; }		}	}

var userToPing = params['pinguser.pingusername'] || rfud.requestingUser; var pingText = (userToPing && !mw.util.isIPAddress(userToPing)) ? (' ') : ;	var text = (forPreview ?  : '\n:') + (params.pinguser ? pingText : ) + (templatetext ? templatetext + separator : ) + params.comments + ' ~'; return text; };

rfud.preview = function(result) { params = {}; $(result).find('input, select, textarea').each(function(_, e) {		params[e.name] = e.type === 'checkbox' ? e.checked : e.value;	}); // params is not set fully correctly, but this is ok as the incorrectly set fields are not required in preview result.previewer.beginRender(rfud.getResponseWikitext(true), "Wikipedia:Requests for undeletion"); };

rfud.evaluate = function(e) {

var form = e.target;

params = {}; params.response = form.response.value; // radio input $(form).find('input, select, textarea').each(function(_, e) {		if (e.type === 'radio') { return true; }		if (e.disabled) { return true; }		params[e.name] = e.type === 'checkbox' ? e.checked : e.value;	});

if (!params.template && !params.comments) { alert('Please select a template response or add a comment'); return; }

if (params['userfy.page'] && params['userfy.page'].indexOf('USERNAME') !== -1) { alert('Please replace "USERNAME" with a valid username'); return; }

// disable submit of this form only, leaving any other open morebits forms untouched $(form).parent.parent.find('.morebits-dialog-buttons button').prop('disabled', true); Morebits.status.init(form);

// Never getting called for some reason, window doesn't autoclose // TODO: remove this, autoclose isn't really desirable Morebits.wiki.actionCompleted.event = function { // removed };

if (params.response === 'accept') { var p = new Morebits.wiki.page(pageName, 'Undeleting ' + pageName); p.setEditSummary(params.logsummary + rfud.advert); p.undeletePage(function onUndeleteSuccess(e) {			e.getStatusElement.info('Done');			rfud.doExtras(e.parent); // e = apiobj, e.parent = pagobj		}, function onUndeleteFailure(e) {			// XXX: show this error only when the api tells so, will need morebits pull merged first			e.getStatusElement.warn("Page already exists or was already undeleted");			rfud.doExtras(e); // e = pageobj		}); } else { rfud.addResponse; }

};

rfud.doExtras = function(pageobj) {

// UNDELETE TALK PAGE if (params.undeletetalk) { // code adapted from Mediawiki:Gadget-Twinklebatchdelete.js var talkpagename = new mw.Title(pageName).getTalkPage.toText; var statelem = new Morebits.status('Talk page'); var query = { 'action': 'query', 'prop': 'deletedrevisions', 'drvprop': 'ids', 'drvlimit': 1, 'titles': talkpagename };		new Morebits.wiki.api('Checking for deleted revisions', query, function talk_page(apiobj) {			var xml = apiobj.responseXML;			var exists = $(xml).find('page:not([missing])').length > 0;			var delrevs = $(xml).find('rev').attr('revid');

if (!delrevs) { statelem.info('No deleted revisions found'); rfud.addOldAfd;  // XXX: this is pathetic, find some better way of organising code return; }			if (exists) { statelem.update('Already exists'); rfud.addOldAfd; return; }

statelem.unlink; var talkpage = new Morebits.wiki.page(apiobj.query.titles, "Talk page"); talkpage.setEditSummary('Undeleting talk page of "' + pageName + '"' + rfud.advert); talkpage.undeletePage(function onUndeleteTalkSuccess {				talkpage.getStatusElement.info('Undeleted');				rfud.addOldAfd;			}); }, statelem).post;	}

// USERFY if (params.userfy) { pageobj = new Morebits.wiki.page(pageName, 'Userfying to ' + params['userfy.page']); pageobj.setMoveDestination(params['userfy.page']); pageobj.setMoveSuppressRedirect(params.sredr); pageobj.setEditSummary('Userfying' + rfud.advert); pageobj.move(function onUserfySuccess {			pageobj.getStatusElement.info('Done');			rfud.removeDeletionTags(params['userfy.page']);		}, function onUserfyFailure(e) {			var statelem = pageobj.getStatusElement;			if (e.errorCode === 'articleexists') {				Morebits.wiki.numberOfActionsLeft++; // hold dialog from closing //

var skip_button = Morebits.htmlNode('button', 'Skip move'); skip_button.addEventListener('click', function {					Morebits.wiki.numberOfActionsLeft--; // allow dialog to close //					statelem.warn('skipped following name conflict');				});

var newUserfy = $(' ').attr('type', 'text')[0]; var new_button = $(' ').text('OK').click(function {					Morebits.wiki.numberOfActionsLeft--;					var newTitle = newUserfy.value;					pageobj.setMoveDestination(newTitle);					pageobj.setMoveSuppressRedirect(params.sredr);					pageobj.move(function { statelem.info(['userfied to ' + newTitle + ' instead. ',							Morebits.htmlNode('span', 'Please update your response to reflect the new page name', 'red')]); rfud.removeDeletionTags(newTitle); });				});				statelem.warn([ 'A user page of that name already exists, enter new user page name or skip ',					newUserfy, new_button[0], skip_button ]); }		});	}

// MOVE WT:AFC PAGES TO DRAFT: SPACE if (params.movetodraft) { pageobj = new Morebits.wiki.page(pageName, 'Moving page to draft namespace'); pageobj.setMoveDestination(pageName.replace('Wikipedia talk:Articles for creation/', 'Draft:')); pageobj.setEditSummary('Moving to new location for drafts' + rfud.advert); pageobj.move(function onAfcMoveSuccess {			pageobj.getStatusElement.info('Done');			rfud.removeDeletionTags(pageName.replace('Wikipedia talk:Articles for creation/', 'Draft:'));		}, function onAfcMoveFailure(e) {			if (e.errorCode === 'articleexists') {				pageobj.getStatusElement.warn('A draft page of that name already exists, skipping...');				Morebits.wiki.numberOfActionsLeft++; // prevent dialog from closing //				rfud.removeDeletionTags(pageName);			}		}); }	// DRAFTIFY if (params.draftify) { pageobj = new Morebits.wiki.page(pageName, 'Draftifying to ' + params['draftify.page']); pageobj.setMoveDestination(params['draftify.page']); pageobj.setMoveSuppressRedirect(params.draftifysredr); pageobj.setEditSummary('Draftifying following undeletion' + rfud.advert); pageobj.move(function onDraftifySuccess(e) {			pageobj.getStatusElement.info('Done');			rfud.removeDeletionTags(params['draftify.page']);		}, function onDraftifyFailure(e) {			var statelem = pageobj.getStatusElement;			if (e.errorCode === 'articleexists') {				Morebits.wiki.numberOfActionsLeft++; // hold dialog from closing //

var skip_button = Morebits.htmlNode('button', 'Skip move'); skip_button.addEventListener('click', function {					Morebits.wiki.numberOfActionsLeft--; // allow dialog to close //					statelem.warn('skipped following name conflict');				});

var newDraftify = $(' ').attr('type', 'text')[0]; var new_button = $(' ').text('OK').click(function {					Morebits.wiki.numberOfActionsLeft--;					var newTitle = newDraftify.value;					pageobj.setMoveDestination(newTitle);					pageobj.setMoveSuppressRedirect(params.draftifysredr);					pageobj.move(function { statelem.info(['moved to ' + newTitle + ' instead. ',							Morebits.htmlNode('span', 'Please update your response to reflect the new page name', 'red')]); rfud.removeDeletionTags(newTitle); });				});				statelem.warn([ 'A draft of that name already exists, enter new draft page name or skip ',					newDraftify, new_button[0], skip_button ]); }		});	}

// REMOVE DELETION TAGS if (!params.userfy && !params.movetodraft && !params.draftify) { rfud.removeDeletionTags(pageName); }

// ADD RESPONSE AT WP:RFUD rfud.addResponse;

// ADD OLD XFD TO TALK PAGE IF PREVIOUSLY DELETED AT AFD if (!params.undeletetalk) { rfud.addOldAfd; }

};

// Called after rfud.removeDeletionTags rfud.addF5tag = function { if (!params.addF5) { return; }	var pageobj = new Morebits.wiki.page(pageName, 'Adding '); pageobj.setPrependText('\n'); pageobj.setEditSummary('Adding ' + rfud.advert); pageobj.setCreateOption('nocreate'); pageobj.prepend; };

rfud.getDeletionLog = function getDeletionLog { // TODO: convert to use API return $.ajax(mw.util.getUrl('Special:Log', { type: 'delete', subtype: 'delete', page: pageName })); };

rfud.addOldAfd = function addOldAfd { rfud.getDeletionLog.then(function(html) {		var afdLink = $(html).find('#mw-content-text ul .mw-logline-delete .comment a[href^="/wiki/Wikipedia:Articles_for_deletion"]')[0];		if (!afdLink) {			return;		}

var afdPage = afdLink.title; var startStatus = new Morebits.status('Adding to talk page', 'Getting data', 'status');

var resultPromise = new mw.Api.parse(new mw.Title(afdPage)); var datePromise = new mw.Api.get({			action: 'query',			prop: 'revisions',			titles: afdPage,			rvprop: 'timestamp',			rvlimit: '1',			rvdir: 'newer'		});

$.when(datePromise, resultPromise).then(function(json, parsedPage) {			var tagtext = '\n';

startStatus.unlink; var talkpage = new mw.Title(pageName).getTalkPage.toText; var pageobj = new Morebits.wiki.page(talkpage, 'Adding to talk page'); pageobj.setPrependText(tagtext); pageobj.setEditSummary('Adding after undeletion' + rfud.advert); pageobj.prepend;

});	}); };

rfud.removeDeletionTags = function removeDeletionTags(currentPageName) { var pageobj = new Morebits.wiki.page(currentPageName, 'Removing deletion tags from page if any');

pageobj.load(function(pageobj) {		var pageText = pageobj.getPageText;		var statelem = pageobj.getStatusElement;

var newPageText = pageText.replace(			// Regex adapted from Mediawiki:Gadget-friendlytag.js			new RegExp( // leading whitespace '^\\s*' + // capture template(s) '(?:((?:\\s*' +				// AfD				'(?:[\\s\\S]*?|' + // begin template format '\\{\\{\\s*(?:' +					// CSD					'db|delete|db-.*?|speedy deletion-.*?|di-.*?|' +					// PROD					'(proposed deletion|prod blp|book-prod)\\/dated(?:\\s+\\|(?:concern|user|timestamp|help).*)+|' +					// sometimes under a CSD or AfD					'|salt|proposed deletion endorsed' +					// MFD/FFD					'|mfd|ffd' +				// end main template name				')\\s*' + // template parameters '(\\|(?:\\{\\{[^{}]*\\}\\}|[^{}])*)?' +				// end template format '\\}\\})+' +				// end capture				'(?:\\s*\\n)?)' + // trailing whitespace '\\s*)?',			'i'), '' );

var changed = false;

// RFD if (/#invoke:RfD/.test(newPageText)) { newPageText = newPageText.replace(/\{\{.*?#invoke:RfD[\s\S]*?\|content=\n([\s\S]*?)\n?\}\}/, '$1'); changed = true; }

// TFD else if (/Template for discussion\/dated/.test(newPageText)) { newPageText = newPageText.replace(/\{\{Template for discussion\/dated.*?(\{\{#invoke:Noinclude.*?\}\})?\}\}/, ''); changed = true; }

if (changed || newPageText !== pageText) { pageobj.setPageText(newPageText); pageobj.setEditSummary('Removing deletion tags after undeletion' + rfud.advert); pageobj.save(function {				rfud.addF5tag;			}); } else { statelem.info('None found'); rfud.addF5tag; rfud.makeDummyEdit(currentPageName); }

}); };

rfud.makeDummyEdit = function(currentPageName) { if (mw.Title.newFromText(currentPageName).namespace === 118 ||		([, , ''].indexOf(params.template) !== -1)	) { var pageobj = new Morebits.wiki.page(currentPageName, 'Making dummy edit to reset G13 clock'); pageobj.load(function(pageobj) {			var currenttext = pageobj.getPageText;			var newtext = currenttext.replace('\n', ' \n');			if (newtext.replace(/\s*$/, '') === currenttext) { // XXX: Morebits doesn't offer a way to detect success "nochange" response returned by the API				pageobj.getStatusElement.warn('Failed to save dummy edit. Please edit the page manually to reset the G13 clock');				return;			}			pageobj.setPageText(newtext);			pageobj.setEditSummary('Dummy edit to reset G13 clock after undeletion' + rfud.advert);			pageobj.save;		}); } };

rfud.addResponse = function rfudAddResponse {

var sectionNumber; try { var uri = new mw.Uri(rfud.$header_container.find('.mw-editsection a').attr('href')); sectionNumber = parseInt(uri.query.section); } catch (e) {} if (!sectionNumber || isNaN(sectionNumber)) { new Morebits.status('Saving response').warn('Unable to find section.'); Morebits.status.printUserText(rfud.getResponseWikitext(true), "Your response is provided below, which you may save manually:"); Morebits.wiki.numberOfActionsLeft++; // prevent dialog from closing // return; }

var appendtext = rfud.getResponseWikitext; var editsummary = '/* ' + rfud.sectionName + ' */ ' + (params.response === 'accept' ? 'Accepting' : 'Declining') + ' request' + rfud.advert;

var rfudpage = new Morebits.wiki.page('Wikipedia:Requests for undeletion', 'Saving response'); rfudpage.setPageSection(sectionNumber); rfudpage.setAppendText(appendtext); rfudpage.setEditSummary(editsummary); rfudpage.setMaxConflictRetries(4); // Account for admins responding to multiple requests simultaneously rfudpage.append(function onAppendSuccess(pageobj) {		// Reload the section html		var statelem = pageobj.getStatusElement;		var reloadApi = new Morebits.wiki.api('Done, reloading section', { action: 'parse', page: 'Wikipedia:Requests for undeletion', section: sectionNumber }, function onReloadSuccess(apiobj) { var html = $(apiobj.responseXML).find('text').text.replace(/&lt;/g, '<').replace(/&gt;/g, '>'); rfud.$header_container.nextUntil('.mw-heading.mw-heading2').remove; rfud.$header_container.replaceWith($(html)); statelem.info('Done, section reloaded'); }, statelem);		reloadApi.post;	}); };

// Add Accept/Decline button $('li .sysop-show a').each(function(_, el) {

el.after(		' | ',		$('').text('Accept').attr('href', '#')			.addClass('rfud-helper-button')			.addClass('rfud-accept')			.click(rfud.callback)[0],		' | ',		$('').text('Decline').attr('href', '#')			.addClass('rfud-helper-button')			.addClass('rfud-decline')			.click(rfud.callback)[0]	);

});

});

function showDeletedPagePreview { var pagetitle = mw.config.get('wgRelevantPageName'); var API = new mw.Api({		ajax: { headers: { 'Api-User-Agent': 'w:en:User:SD0001/RFUD-helper.js' } },		parameters: { formatversion: '2' }	}); API.get({		"action": "query",		"prop": "deletedrevisions",		"titles": pagetitle,		"drvprop": "content",		"drvlimit": "1"	}).then(function(json) {		var wikitext = json.query.pages[0].deletedrevisions[0].content;		wikitext = '=Last deleted version=\n' + wikitext;		return API.post({ "action": "parse", "title": pagetitle, "text": wikitext, "disableeditsection": "1", "prop": "text|categorieshtml" });	}).then(function(json) {		$(' ').attr('id', 'rfud-helper-deleted-preview').html( json.parse.text + json.parse.categorieshtml ).appendTo('#mw-content-text');

var $anchor = $('.mw-undelete-pagetitle').length ? $('.mw-undelete-pagetitle') : $('.mw-undelete-subtitle'); $anchor.append(			$(' ').css('float', 'right').append( $('').attr('href', '#rfud-helper-deleted-preview').text('[Jump to preview of last revision]') )		);	}); }

});

//