User:SD0001/RFUD-helper.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | This user script seems to have a documentation page at User:SD0001/RFUD-helper. |
/**
* ****** STILL UNDER DEVELOPMENT ******
*
* 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
* - If is a WT:AFC subpage, move it to draft namespace
* - Offer to userfy the page instead of restoring to source
*
*/
// <nowiki>
$.when(
mw.loader.using([ 'mediawiki.util', 'mediawiki.api', 'mediawiki.Title', 'jquery.ui.dialog', 'jquery.tipsy' ]),
mw.loader.getScript( 'https://en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-morebits.js&action=raw&ctype=text/javascript' ),
importStylesheet( 'MediaWiki:Gadget-morebits.css' ),
$.ready
).then(function() {
if (mw.config.get('wgPageName') !== 'Wikipedia:Requests_for_undeletion') {
return;
}
// Until the patch to morebits is accepted, see #643
Morebits.wiki.actionCompleted.event = function() {
new Morebits.status( Morebits.wiki.actionCompleted.notice, Morebits.wiki.actionCompleted.postfix, 'info' );
if( Morebits.wiki.actionCompleted.redirect ) {
// if it isn't a URL, make it one. TODO: This breaks on the articles 'http://', 'ftp://', and similar ones.
if( !( (/^\w+:\/\//).test( Morebits.wiki.actionCompleted.redirect ) ) ) {
Morebits.wiki.actionCompleted.redirect = mw.util.getUrl( Morebits.wiki.actionCompleted.redirect );
if( Morebits.wiki.actionCompleted.followRedirect === false ) {
Morebits.wiki.actionCompleted.redirect += "?redirect=no";
}
}
window.setTimeout( function() {
window.location = Morebits.wiki.actionCompleted.redirect;
// force reload if redirect location differs from current location only by the hash
if (Morebits.wiki.actionCompleted.redirect.indexOf(mw.util.getUrl() + '#') === 0) {
window.location.reload(true);
}
}, Morebits.wiki.actionCompleted.timeOut);
}
};
var rfud = {};
window.rfud = rfud;
rfud.config = {
advert: ' ([[User:SD0001/rfud-helper.js|rfud-helper]])',
version: '1.0.0'
};
Morebits.wiki.api.setApiUserAgent('[[w:User:SD0001/rfud-helper.js|rfud-helper]]');
var pageName;
var params = {};
rfud.callback = function(e) {
e.preventDefault();
pageName = e.target.parentElement.firstChild.nextElementSibling.title.slice(17).replace(/_/g,' ');
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')
});
}
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.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'
});
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]]'
});
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 move the page to which the page is to be moved',
value: 'User:USERNAME/' + pageName.replace(/^Draft:/, '')
.replace(/^Wikipedia talk:Articles for creation\//, '')
} ],
event: function(e) {
if (e.target.checked) {
var userfypagefield = form['userfy.page'];
if (userfypagefield.value.includes('USERNAME')) {
userfypagefield.setSelectionRange('User:'.length, 'User:USERNAME'.length);
userfypagefield.focus();
}
if (form.movetodraft) {
form.movetodraft.disabled = true;
} else if (form.undeletetalk) {
form.undeletetalk.disabled = true;
}
} else {
if (form.movetodraft) {
form.movetodraft.disabled = false;
} else if (form.undeletetalk) {
form.undeletetalk.disabled = false;
}
}
}
} ]
});
var title = new mw.Title(pageName);
if (! title.isTalkPage()) {
work_area.append({
type: 'checkbox',
list: [ {
label: 'Undelete talk page if it existed',
name: 'undeletetalk',
value: 'undeletetalk',
checked: true
} ]
});
}
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 (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'
});
var old_area = $("[name=work_area]")[0];
var result = work_area.render();
old_area.replaceWith( result );
};
rfud.template_responses = {
accept: {
'' : "No template response",
'{{UND|done}}' : "Done",
'{{UND|prod}}' : "contested proposed deletion",
'{{UND|g13}}' : "draft deleted under G13",
'{{UND|afc}}' : "for G13s where {{AFC submission}} was used and the draft was submitted and declined",
'{{UND|afc-ns}}' : "for G13s where {{AFC submission}} was used and where the draft was never submitted",
'{{UND|g13-draft}}' : "for G13s of draft namespace pages never part of the AfC process"
},
decline: {
'' : "No template response",
'{{UND|notdone}}' : "Not done",
'{{UND|notdone2}}' : "Not done and will not be done",
'{{UND|doesnotexist}}' : "No deleted page with this name",
'{{UND|notdonecompany}}' : "Company article failing NCORP",
'{{UND|notdoneperson}}' : "Biographical article failing NBIO",
'{{UND|g11}}' : "Blatant advertisement",
'{{UND|discussion}}' : "Article deleted at a discussion", // has subgroup
'{{UND|csd}}' : "Article deleted per CSD criteria", // has subgroup
'{{UND|copyvio}}' : "Copyright violation" // has subgroup
}
};
rfud.responseTemplateChanged = function(e) {
var template = e.target.value;
var newInput;
if (template === '{{UND|discussion}}') {
newInput = new Morebits.quickForm.element({
type: 'input',
label: 'Discussion: ',
name: 'discussion',
size: '70px',
className: 'UNDtemplateinput'
});
newInput.append({
type: 'input',
label: 'Closing admin: ',
name: 'closingadmin',
className: 'UNDtemplateinput'
});
} else if (template === '{{UND|csd}}') {
newInput = new Morebits.quickForm.element({
type: 'input',
label: 'Deleting admin: ',
name: 'deletingadmin',
className: 'UNDtemplateinput'
});
} else if (template === '{{UND|copyvio}}') {
newInput = new Morebits.quickForm.element({
type: 'input',
label: 'Copyvio source: ',
name: 'copyviosource',
size: '70px',
className: 'UNDtemplateinput'
});
}
$('.UNDtemplateinput').remove();
if (newInput) {
$(e.target.form).find('h5').before(newInput.render());
}
};
rfud.getResponseWikitext = function(forPreview) {
var templatetext = params.template.replace(/^\{\{/, '{{subst:');
switch (params.template) {
case '{{UND|discussion}}':
templatetext = templatetext.replace('}}', '|' + params.discussion + '|' + params.closingadmin + '}}');
break;
case '{{UND|csd}}':
templatetext = templatetext.replace('}}', '|' + params.deletingadmin + '}}');
break;
case '{{UND|copyvio}}':
templatetext = templatetext.replace('}}', '|' + params.copyviosource + '}}');
break;
}
if (forPreview) {
var text = (templatetext ? (templatetext + (params.comments ? '\n\n' : '' )) : '') + params.comments + ' ~~~~';
} else {
var text = '\n:' + (templatetext ? (templatetext + (params.comments ? '\n\n:' : '' )) : '') + params.comments + ' ~~~~';
}
return text;
};
rfud.preview = function(result) {
params = {};
$(result).find('input, select, textarea').each(function(i, 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), "API"); // Force wikitext
};
rfud.evaluate = function(e) {
var form = e.target;
params = {};
params.response = form.response.value; // radio input
$(form).find('input, select, textarea').each(function(i, 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'].includes('USERNAME')) {
alert('Please replace "USERNAME" with a valid username');
return;
}
Morebits.simpleWindow.setButtonsEnabled( false );
Morebits.status.init( form );
Morebits.wiki.actionCompleted.redirect = 'Wikipedia:Requests for undeletion#' + pageName;
Morebits.wiki.actionCompleted.timeOut = 1000;
if (params.response === 'accept') {
Morebits.wiki.actionCompleted.notice = "Undeletion";
var p = new Morebits.wiki.page(pageName);
p.setEditSummary(params.logsummary + rfud.config.advert);
p.undeletePage(rfud.doExtras);
} else {
var rfudpage = new Morebits.wiki.page('Wikipedia:Requests for undeletion');
rfudpage.load(rfud.addResponse);
}
};
rfud.doExtras = function(e) {
var pageobj = e.parent;
// UNDELETE TALK PAGE
if (params.undeletetalk) {
// code here is copied off [[Mediawiki:Gadget-Twinklebatchdelete.js]], written by [[User:Amorymeltzer]]
var talkpagename = new mw.Title(pageName).getTalkPage().getPrefixedText();
var query = {
'action': 'query',
'prop': 'deletedrevisions',
'drvprop': 'ids',
'drvlimit': 1,
'titles': talkpagename
};
new Morebits.wiki.api( 'Checking talk page for deleted revisions', query, function talk_undel( apiobj ) {
var xml = apiobj.responseXML;
var exists = $(xml).find('page:not([missing])').length > 0;
var delrevs = $(xml).find('rev').attr('revid');
if( exists || !delrevs ) {
// page exists or has no deleted revisions; forget about it
return;
}
var talkpage = new Morebits.wiki.page(apiobj.query.titles, "Undeleting talk page of " + pageName);
talkpage.setEditSummary('Undeleting [[Help:Talk page|talk page]] of "' + pageName + '"' + rfud.config.advert);
talkpage.undeletePage();
} ).post();
}
// USERFY
if (params.userfy) {
Morebits.status.info(pageName, 'Userfying to ' + params['userfy.page']);
params.newPageName = params['userfy.page'];
pageobj.setMoveDestination(params.newPageName);
pageobj.setEditSummary('Userfying' + rfud.config.advert);
pageobj.move(rfud.removeDeletionTags);
}
// MOVE WT:AFC PAGES TO DRAFT: SPACE
if (params.movetodraft) {
Morebits.status.info(pageName, 'Moving page to draft namespace');
params.newPageName = pageName.replace('Wikipedia talk:Articles for creation/', 'Draft:');
pageobj.setMoveDestination(params.newPageName);
pageobj.setEditSummary('Moving to new location for drafts' + rfud.config.advert);
pageobj.move(rfud.removeDeletionTags);
}
// REMOVE DELETION TAGS
if (!params.userfy && !params.movetodraft) {
rfud.removeDeletionTags();
}
// ADD RESPONSE AT WP:RFUD
var rfudpage = new Morebits.wiki.page('Wikipedia:Requests for undeletion');
rfudpage.load(rfud.addResponse);
};
rfud.removeDeletionTags = function() {
var pageobj = new Morebits.wiki.page(params.newPageName ? params.newPageName : pageName,
'Removing deletion tags from page if any');
pageobj.load(function(pageobj) {
var pageText = pageobj.getPageText();
var newPageText = pageText.replace(
// Regex adapted from [[Mediawiki:Gadget-friendlytag.js]]
new RegExp(
// leading whitespace
'^\\s*' +
// capture template(s)
'(?:((?:\\s*' +
// AfD
'(?:<!--.*AfD.*\\n\\{\\{(?:Article for deletion\\/dated|AfDM).*\\}\\}\\n<!--.*(?:\\n<!--.*)?AfD.*(?:\\s*\\n))?|' + // trailing whitespace/newline needed since this subst's a newline
// CFD
'<!-- BEGIN CFD TEMPLATE -->[\\s\\S]*?<!-- END CFD TEMPLATE -->|' +
// begin template format
'\\{\\{\\s*(?:' +
// CSD
'db|delete|db-.*?|speedy deletion-.*?|' +
// 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]*?)<!-- Don.*?-->\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 from undeleted page' + rfud.config.advert);
pageobj.save();
}
});
};
rfud.addResponse = function rfudAddResponse() {
var sectionName = pageName;
var sectionNumber;
$('.toctext').each(function(i,e) {
if ( Morebits.string.toUpperCaseFirstChar(e.textContent) === sectionName ) {
sectionNumber = e.previousElementSibling.textContent;
return false; // break
}
});
var editsummary = '/* ' + sectionName + ' */ ' + Morebits.string.toUpperCaseFirstChar(params.response) + 'ing request' + rfud.config.advert;
new Morebits.wiki.api('Adding response to request', {
action: 'edit',
section: sectionNumber,
appendtext: rfud.getResponseWikitext(),
title: 'Wikipedia:Requests for undeletion',
summary: editsummary,
token: mw.user.tokens.get('editToken')
}).post();
};
// Add Accept/Decline button
$('h2').next().find('li .sysop-show a').each(function(i,e) {
var rfudhelperlink_accept = Morebits.htmlNode('a', 'Accept');
rfudhelperlink_accept.href = '#';
rfudhelperlink_accept.className = 'rfud-helper-button rfud-accept';
var rfudhelperlink_decline = Morebits.htmlNode('a', 'Decline');
rfudhelperlink_decline.href = '#';
rfudhelperlink_decline.className = 'rfud-helper-button rfud-decline';
e.after(document.createTextNode(' | '), rfudhelperlink_accept,
document.createTextNode(' | '), rfudhelperlink_decline);
});
// Attach click event handler
$('.rfud-helper-button').click(rfud.callback);
});
// </nowiki>