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. |
/**
*
* 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 {{Old AfD}} 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.
*/
// <nowiki>
/* 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', 'ext.gadget.morebits' ]),
$.ready
).then(function() {
var rfud = {};
window.rfud = rfud;
rfud.advert = ' ([[User:SD0001/RFUD-helper|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 [[mw: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 [[' + permanent_section_link + '|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 = '{{UND|userfy}}';
} else {
$('.UNDtemplateinput').parent().remove(); // remove deleting admin prompt from {{UND|userA7}}
if (form.movetodraft) {
form.movetodraft.disabled = false;
}
if (form.undeletetalk) {
form.undeletetalk.disabled = false;
}
form.template.value = '{{UND|done}}';
}
}
} ]
});
}
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 = '{{UND|draftify}}';
} else {
form.template.value = '{{UND|done}}';
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 {{di-orphaned fair use}}',
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 = '{{UND|f5deferred}}';
} else {
form.template.value = '{{UND|done}}';
}
}
} ]
});
}
} 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",
'{{UND|done}}': "Done",
'{{UND|prod}}': "contested proposed deletion",
'{{UND|soft}}': "contested soft 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",
'{{UND|f5deferred}}': "for files being restored and tagged as {{di-orphaned fair use}}",
'{{UND|userfy}}': "Userfied",
'{{UND|userA7}}': "Userfied A7 article, contact admin before moving back", // has subgroup
'{{UND|draftify}}': "Draftified",
},
decline: {
'': "No template response",
'{{UND|notdone}}': "Not done",
'{{UND|notdone2}}': "Not done and will not be done",
'{{UND|2nd}}': "Was undeleted once, not worked on (soft-decline)",
'{{UND|doesnotexist}}': "No deleted page with this name",
'{{UND|notdonecompany}}': "Company article failing NCORP",
'{{UND|notdoneperson}}': "Biographical article failing NBIO",
'{{UND|inappropriate}}': "Inappropriate topic for Wikipedia",
'{{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;
$('.UNDtemplateinput').parent().remove();
var newInput;
if (template === '{{UND|discussion}}') {
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 === '{{UND|csd}}' || template === '{{UND|userA7}}') {
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 === '{{UND|copyvio}}') {
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 === '{{UND|userfy}}' || template === '{{UND|userA7}}') {
if (e.target.form.userfy.checked === false) {
e.target.form.userfy.click();
e.target.value = template; // the click above will reset select value to {{UND|userfy}}
}
}
if (template === '{{UND|draftify}}') {
if (e.target.form.draftify.checked === false) {
e.target.form.draftify.click();
}
}
if (template === '{{UND|csd}}' || template === '{{UND|userA7}}') {
// 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 === '{{UND|discussion}}') {
// 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(/^\{\{/, '{{subst:');
var parameterText = '';
switch (params.template) {
case '{{UND|discussion}}':
parameterText = '|' + params.discussion + '|' + params.closingadmin;
break;
case '{{UND|csd}}':
parameterText = '|3=' + params.deletingadmin;
break;
case '{{UND|copyvio}}':
parameterText = '|' + params.copyviosource;
break;
case '{{UND|userfy}}':
parameterText = '|' + params['userfy.page'];
break;
case '{{UND|userA7}}':
parameterText = '|' + params['userfy.page'] + '|' + params.deletingadmin;
break;
case '{{UND|draftify}}':
parameterText = '|' + params['draftify.page'];
break;
}
templatetext = templatetext.replace('}}', parameterText + '}}');
var separator = '';
if (params.comments) {
// these templates don't have any text (other than bolded stuff)
if (params.template === '{{UND|done}}' ||
params.template === '{{UND|notdone}}' ||
params.template === '{{UND|notdone2}}') {
separator = ' ';
} else {
separator = '\n\n';
if (!forPreview) {
separator += ':';
}
}
}
var userToPing = params['pinguser.pingusername'] || rfud.requestingUser;
var pingText = (userToPing && !mw.util.isIPAddress(userToPing)) ? ('{{re|' + 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 [[Help:Talk page|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 = $('<input>').attr('type', 'text')[0];
var new_button = $('<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 = $('<input>').attr('type', 'text')[0];
var new_button = $('<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 {{di-orphaned fair use}}');
pageobj.setPrependText('{{subst:di-orphaned fair use}}\n');
pageobj.setEditSummary('Adding {{di-orpaned fair use}}' + 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 {{Old AfD}} 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 = '{{Old AfD|page=' + afdPage;
if (json && json[0] && json[0].query && json[0].query.pages) {
var timestamp = Object.values(json[0].query.pages)[0].revisions[0].timestamp;
var d = new Morebits.date(timestamp);
var date = d.getUTCDate() + ' ' + d.getUTCMonthName() + ' ' + d.getUTCFullYear();
tagtext += '|date=' + date;
}
if (parsedPage) {
var boldedResult = $(parsedPage).find('b')[1].textContent;
tagtext += "|result='''" + boldedResult + "'''";
}
tagtext += '}}\n';
startStatus.unlink();
var talkpage = new mw.Title(pageName).getTalkPage().toText();
var pageobj = new Morebits.wiki.page(talkpage, 'Adding {{Old AfD}} to talk page');
pageobj.setPrependText(tagtext);
pageobj.setEditSummary('Adding {{Old AfD}} 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
'(?:<!--.*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-.*?|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]*?)<!-- 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 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 ||
(['{{UND|g13}}', '{{UND|afc}}', '{{UND|afc-ns}}'].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 url = new URL(rfud.$header_container.find('.mw-editsection a').attr('href'));
sectionNumber = parseInt(url.searchParams.get('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(/</g, '<').replace(/>/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(
' | ',
$('<a>').text('Accept').attr('href', '#')
.addClass('rfud-helper-button')
.addClass('rfud-accept')
.click(rfud.callback)[0],
' | ',
$('<a>').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) {
$('<div>').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(
$('<div>').css('float', 'right').append(
$('<a>').attr('href', '#rfud-helper-deleted-preview').text('[Jump to preview of last revision]')
)
);
});
}
})();
// </nowiki>