User:Animum/massdelete.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. |
![]() | Documentation for this user script can be added at User:Animum/massdelete. |
mw.loader.using(['mediawiki.api.edit', 'mediawiki.Title'], function () {
"use strict";
var config = mw.config.get(['wgNamespaceNumber', 'wgTitle', 'wgUserGroups', 'skin']);
function removeBlanks(arr) {
var ret = [];
var i, len;
for (i = 0, len = arr.length; i < len; i++) {
var s = arr[i];
s = s.trim();
if (s) {
ret.push(s);
}
}
return ret;
}
function doMassDelete() {
document.getElementById("wpMassDeleteSubmit").disabled = true;
var articles = document.getElementById("wpMassDeletePages").value.split("\n");
articles = removeBlanks(articles);
if (!articles.length) {
return;
}
var
api = new mw.Api(),
wpMassDeleteReasons = document.getElementById("wpMassDeleteReasons").value,
wpMassDeleteReason = document.getElementById("wpMassDeleteReason").value,
deleted = 0,
failed = [],
error = [],
deferreds = [],
reason = wpMassDeleteReasons == "other" ?
wpMassDeleteReason :
wpMassDeleteReasons + (wpMassDeleteReason ? " (" + wpMassDeleteReason + ")" : ""),
onSuccess = function () {
deleted++;
document.getElementById("wpMassDeleteSubmit").value = "(" + deleted + ")";
};
function makeDeleteFunc(article) {
return function () {
return $.Deferred(function (deferred) {
var promise = api.postWithToken('delete', {
format: 'json',
action: 'delete',
title: article,
reason: reason
});
promise.done(onSuccess);
promise.fail(function (code, obj) {
failed.push(article);
error.push(obj.error.info);
});
promise.always(function () {
deferred.resolve();
});
});
};
}
// Make a chain of deferred objects. We chain them rather than execute them in
// parallel so that we don't make 1000 simultaneous delete requests and bring the
// site down. We use deferred objects rather than the promise objects returned
// from the API request so that the chain continues even if some articles gave
// errors.
var deferred = makeDeleteFunc(articles[0])();
for (var i = 1, len = articles.length; i < len; i++) {
deferred = deferred.then(makeDeleteFunc(articles[i]));
}
// Show the output and do cleanup once all the requests are done.
$.when(deferred).then(function () {
document.getElementById("wpMassDeleteSubmit").value = "Done (" + deleted + ")";
if (failed.length) {
var $failedList = $('<ul>');
for(var x = 0; x < failed.length; x++) {
// Link the titles in the "failed" array
var failedTitle = mw.Title.newFromText(failed[x]);
var $failedItem = $('<li>');
if (failedTitle) {
$failedItem.append( $('<a>')
.attr('href', failedTitle.getUrl())
.text(failed[x])
);
} else {
$failedItem.text(failed[x]);
}
$failedItem.append(document.createTextNode(': ' + error[x]));
$failedList.append($failedItem);
}
$('#wpMassDeleteFailedContainer')
.append($('<br />'))
.append($('<b>')
.text('Failed deletions:')
)
.append($failedList);
}
});
}
function massdeleteform() {
var bodyContent = (config.skin == "cologneblue" ? "article" : "bodyContent");
document.getElementsByTagName("h1")[0].textContent = "Animum's mass-deletion tool";
document.title = "Animum's mass-deletion tool - Wikipedia, the free encyclopedia";
document.getElementById(bodyContent).innerHTML = '<h3 id="siteSub">From Wikipedia, the free encyclopedia</h3><br /><br />' +
'<form id="wpMassDelete" name="wpMassDelete">' +
'<b>If you abuse this tool, it\'s <i>your</i> fault, not mine.</b>' +
'<div id="wpMassDeleteFailedContainer"></div>' +
'<br /><br />' +
'Pages to delete (one on each line, please):<br />' +
'<textarea tabindex="1" accesskey="," name="wpMassDeletePages" id="wpMassDeletePages" rows="10" cols="80"></textarea>' +
'<br /><br /><table style="background-color:transparent">' +
'<tr><td>Common reasons:</td>' +
'<td><select id="wpMassDeleteReasons">' +
'<optgroup label="Other reason">' +
'<option value="other">Other reason</option>' +
'</optgroup>' +
'<optgroup label="Criteria for speedy deletion">' +
'<optgroup label="General criteria">' +
'<option value="[[WP:CSD#G1|G1]]: [[WP:PN|Patent nonsense]], meaningless, or incomprehensible">G1: Patent nonsense</option>' +
'<option value="[[WP:CSD#G2|G2]]: Test page">G2: Test page</option>' +
'<option value="[[WP:CSD#G3|G3]]: [[WP:Vandalism|Vandalism]]">G3: Vandalism</option>' +
'<option value="[[WP:CSD#G4|G4]]: Recreation of a page that was [[WP:DEL|deleted]] per a [[WP:XFD|deletion discussion]]">G4: Repost</option>' +
'<option value="[[WP:CSD#G5|G5]]: Creation by a [[WP:BLOCK|blocked]] or [[WP:BAN|banned]] user in violation of block or ban">G5: Banned</option>' +
'<option value="[[WP:CSD#G6|G6]]: Housekeeping and routine (non-controversial) cleanup">G6: Maintenance</option>' +
'<option value="[[WP:CSD#G7|G7]]: One author who has requested deletion or blanked the page">G7: Author</option>' +
'<option value="[[WP:CSD#G8|G8]]: Page dependent on a deleted or nonexistent page">G8: Orphaned talk page</option>' +
'<option value="[[WP:CSD#G10|G10]]: [[WP:ATP|Attack page]] or negative unsourced [[WP:BLP|BLP]]">G10: Attack page</option>' +
'<option value="[[WP:CSD#G11|G11]]: Unambiguous [[WP:ADS|advertising]] or promotion">G11: Advertising</option>' +
'<option value="[[WP:CSD#G12|G12]]: Unambiguous [[WP:C|copyright infringement]]">G12: Copyvio</option>' +
'</optgroup>' +
'<optgroup label="Articles">' +
'<option value="[[WP:CSD#A1|A1]]: Not enough context to identify article\'s subject">A1: No context</option>' +
'<option value="[[WP:CSD#A2|A2]]: Article in a foreign language that exists on another project">A2: Foreign</option>' +
'<option value="[[WP:CSD#A3|A3]]: Article that has no meaningful, substantive content">A3: No content</option>' +
'<option value="[[WP:CSD#A5|A5]]: Article that has been transwikied to another project">A5: Transwiki</option>' +
'<option value="[[WP:CSD#A7|A7]]: No explanation of the subject\'s significance (real person, animal, organization, or web content)">A7: Non-notable real person, animal, organization, or web content</option>' +
'<option value="[[WP:CSD#A9|A9]]: Music recording by redlinked artist and no indication of importance or significance">A9: Non-notable recording by redlinked artist</option>' +
'<option value="[[WP:CSD#A10|A10]]: Recently created article that duplicates an existing topic">A10: Recently created article that duplicates an existing topic</option>' +
'</optgroup>' +
'<optgroup label="Redirects">' +
'<option value="[[WP:CSD#R2|R2]]: Cross-[[WP:NS|namespace]] [[WP:R|redirect]] from mainspace">R2: Cross-namespace</option>' +
'<option value="[[WP:CSD#R3|R3]]: Recently created, implausible [[WP:R|redirect]]">R3: Implausible redirect</option>' +
'</optgroup>' +
'<optgroup label="Images and other media">' +
'<option value="[[WP:CSD#F1|F1]]: File redundant to another on Wikipedia">F1: Redundant</option>' +
'<option value="[[WP:CSD#F2|F2]]: Corrupt or empty file, or a file description page for a file on Commons">F2: Corrupt, empty. or Commons</option>' +
'<option value="[[WP:CSD#F3|F3]]: File with improper license">F3: File with improper license</option>' +
'<option value="[[WP:CSD#F4|F4]]: Lack of licensing information">F4: Lack of licensing information</option>' +
'<option value="[[WP:CSD#F5|F5]]: Unused non-free media">F5: Unfree and unused</option>' +
'<option value="[[WP:CSD#F6|F6]]: Non-free file without [[WP:RAT|fair-use rationale]]">F6: No rationale</option>' +
'<option value="[[WP:CSD#F7|F7]]: [[WP:NFCC|Invalid]] fair-use claim">F7: Bad fair use rationale</option>' +
'<option value="[[WP:CSD#F8|F8]]: Media file available on Commons">F8: On Commons</option>' +
'<option value="[[WP:CSD#F9|F9]]: File [[WP:COPYVIO|copyright violation]]">F9: File copyvio</option>' +
'<option value="[[WP:CSD#F10|F10]]: Useless media file">F10: Useless media file</option>' +
'<option value="[[WP:CSD#F11|F11]]: No evidence of permission">F11: No permission</option>' +
'</optgroup>' +
'<optgroup label="Categories">' +
'<option value="[[WP:CSD#C1|C1]]: Empty category">C1: Empty</option>' +
'<option value="[[WP:CSD#C2|C2]]: Speedy renaming">C2: Speedy rename</option>' +
'<option value="[[WP:CSD#G8|G8]]: Populated by deleted or retargeted template">G8: Populated by deleted or retargeted template</option>' +
'</optgroup>' +
'<optgroup label="User namespace">' +
'<option value="[[WP:CSD#U1|U1]]: User request to delete page in own userspace">U1: User requests deletion</option>' +
'<option value="[[WP:CSD#U2|U2]]: Userpage or subpage of a nonexistent user">U2: Non-existent user</option>' +
'<option value="[[WP:CSD#U3|U3]]: [[WP:NFC|Non-free]] [[Help:Gallery|gallery]]">U3: Fair use gallery</option>' +
'</optgroup>' +
'<optgroup label="Templates">' +
'<option value="[[WP:CSD#T2|T2]]: Template that unambiguously misrepresents established policy">T2: Blatant misrepresentation</option>' +
'<option value="[[WP:CSD#T3|T3]]: Unused, redundant template">T3: Redundant and unused</option>' +
'<option value="[[WP:CSD#G8|G8]]: Component or documentation of a deleted template">G8: component of deleted template</option>' +
'</optgroup>' +
'<optgroup label="Portals">' +
'<option value="[[WP:CSD#P1|P1]]: [[WP:P|Portal]] page that would be subject to speedy deletion as an article">P1: Deletion as article</option>' +
'<option value="[[WP:CSD#P2|P2]]: [[WP:P|Portal]] without a substantial topic base">P2: Underpopulated</option>' +
'</optgroup>' +
'<optgroup label="Other">' +
'<option value="[[WP:PROD]]: Nominated for seven days with no objection">PRODded for more than 7 days without objection</option>' +
'<option value="[[WP:BLPPROD]]: Nominated for ten days with no sources present in the article">BLPPRODded for more than 10 days without a source</option>' +
'<option value="Listed at [[Wikipedia:Copyright problems]] for over seven days">Listed at Copyright problems for over seven days</option>' +
'</optgroup>' +
'</optgroup>' +
'</select></td></tr>' +
'<tr><td>Other/additional reason:</td>' +
'<td><input type="text" id="wpMassDeleteReason" name="wpMassDeleteReason" maxlength="255" /></td></tr>' +
'<tr><td><input type="button" id="wpMassDeleteSubmit" name="wpMassDeleteSubmit" value="Delete" /></td>' +
'</form>';
document.getElementById("wpMassDeleteReasons").onchange = function() {
var maxlength = (document.getElementById("wpMassDeleteReasons").value == "other" ? 255 : 252-document.getElementById("wpMassDeleteReasons").value.length); //It's 252 because of the three characters (" ()") in addition to the selected summary.
document.getElementById("wpMassDeleteReason").setAttribute("maxlength", maxlength);
};
document.getElementById("wpMassDeleteSubmit").addEventListener("click", function (e) {
doMassDelete();
});
}
if (config.wgNamespaceNumber == -1 &&
config.wgTitle.toLowerCase() == "massdelete" &&
/sysop/.test(config.wgUserGroups)
) {
massdeleteform();
}
});