function wpMassRevDelCheckRev(event) {
var textarea = document.getElementById('wpMassRevDelPages'),
lines = textarea.value.split('\n').filter(line => line.trim() !== '');
if (event.target.checked) {
if (!lines.includes(event.target.value)) {
lines.push(event.target.value);
}
} else {
var i = lines.indexOf(event.target.value);
if (i !== -1) {
lines.splice(i, 1);
}
}
textarea.value = lines.join('\n');
}
mw.loader.using(['mediawiki.api', 'mediawiki.Title'], function () {
"use strict";
var config = mw.config.get(['wgNamespaceNumber', 'wgCanonicalSpecialPageName', 'wgTitle', 'wgUserGroups', 'skin']);
const chunkSize = 50;
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 doMassRevDel() {
document.getElementById("wpMassRevDelSubmit").disabled = true;
var ids = document.getElementById("wpMassRevDelPages").value.split("\n");
ids = removeBlanks(ids);
if (!ids.length) {
return;
}
var
api = new mw.Api(),
wpMassRevDelReasons = document.getElementById("wpMassRevDelReasons").value,
wpMassRevDelReason = document.getElementById("wpMassRevDelReason").value,
wpMassRevDelItems = document.querySelectorAll('#wpMassRevDel input[type="checkbox"]:checked'),
hide = Array.from(wpMassRevDelItems).map(checkbox => checkbox.value).join('|'),
deleted = 0,
failed = [],
error = [],
deferreds = [],
reason = wpMassRevDelReasons == "other" ?
wpMassRevDelReason :
wpMassRevDelReasons + (wpMassRevDelReason ? " (" + wpMassRevDelReason + ")" : ""),
onSuccess = function (data) {
//console.log(data);
deleted += (data?.revisiondelete?.items.length || 0);
document.getElementById("wpMassRevDelSubmit").value = "(" + deleted + ")";
};
function makeDeleteFunc(idString) {
return function () {
return $.Deferred(function (deferred) {
var query = {
format: 'json',
action: 'revisiondelete',
type: 'revision',
ids: idString,
hide: hide,
reason: reason
};
//console.log(query);
var promise = api.postWithToken('csrf', query);
promise.done(onSuccess);
promise.fail(function (code, obj) {
failed.push(idString);//console.error(idString);
error.push(obj.error.info);//console.error(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 ids gave
// errors.
var deferred = makeDeleteFunc(ids[0])();
for (var i = 1, len = ids.length; i < len; i++) {
deferred = deferred.then(makeDeleteFunc(ids[i]));
}
// Show the output and do cleanup once all the requests are done.
$.when(deferred).then(function () {
document.getElementById("wpMassRevDelSubmit").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);
}
$('#wpMassRevDelFailedContainer')
.append($('<br />'))
.append($('<b>')
.text('Failed deletions:')
)
.append($failedList);
}
});
}
function MassRevDelform() {
var bodyContent;
switch (mw.config.get('skin')) {
case 'modern':
bodyContent = 'mw_contentholder';
break;
case 'cologneblue':
bodyContent = 'article';
break;
case 'monobook':
case 'vector':
default:
bodyContent = 'bodyContent';
break;
}
var pageHtml =
'<p>Ahecht\'s mass-revision-deletion tool based on <a href="https://demo.azizisearch.com/lite/wikipedia/page/User:Animum/massdelete.js">Animum\'s mass-deletion tool</a>.</p>' +
'<form id="wpMassRevDel" name="wpMassRevDel">' +
'<b>If you abuse this tool, it\'s <i>your</i> fault, not mine.</b>' +
'<div id="wpMassRevDelFailedContainer"></div>' +
'<br /><br />' +
'Revisions to delete (one on each line, please):<br />' +
'<textarea tabindex="1" accesskey="," name="wpMassRevDelPages" id="wpMassRevDelPages" rows="10" cols="80"></textarea>' +
'<br /><br /><table style="background-color:transparent">' +
'<tr><td>Common reasons:</td>' +
'<td colspan="3"><select id="wpMassRevDelReasons">' +
'<optgroup label="Other reason">' +
'<option value="other">Other reason</option>' +
'</optgroup>' +
'<optgroup label="Criteria for revision deletion">' +
'<option value="[[WP:RD1|RD1]]: Blatant violations of the [[WP:C|copyright policy]].">RD1: Blatant violations of the copyright policy</option>' +
'<option value="[[WP:RD2|RD2]]: Grossly insulting, degrading, or offensive material.">RD2: Grossly insulting, degrading, or offensive material</option>' +
'<option value="[[WP:RD2|RD2]]: Serious [[WP:BLP|BLP]] violations.">RD2: Serious BLP violations</option>' +
'<option value="[[WP:RD3|RD3]]: Purely [[WP:DE|disruptive]] material.">RD3: Purely disruptive material</option>' +
'<option value="[[WP:RD5|RD5]]: Other valid deletion under [[WP:DEL#REASON|deletion policy]].">RD5: Other valid deletion</option>' +
'<option value="[[WP:RD6|RD6]]: Non-contentious housekeeping, RevDel corrections, notes, conversion.">RD6: Non-contentious housekeeping</option>' +
'<option value="[[WP:F5|F5]]: Orphaned non-free file(s)."></option>' +
'</optgroup>' +
'</select></td>' +
'</tr><tr><td>Other/additional reason:</td>' +
'<td colspan="3"><input type="text" id="wpMassRevDelReason" name="wpMassRevDelReason" maxlength="255" style="box-sizing:border-box;width:100%"/></td>' +
'</tr><tr><td>Items to delete:</td>' +
'<td><input type="checkbox" id="wpMassRevDelSummary" name="wpMassRevDelSummary" value="comment"><label for "wpMassRevDelSummary>Edit summary</label></td>' +
'<td><input type="checkbox" id="wpMassRevDelText" name="wpMassRevDelText" value="content"><label for "wpMassRevDelText>Revision text</label></td>' +
'<td><input type="checkbox" id="wpMassRevDelUser" name="wpMassRevDelUser" value="content"><label for "wpMassRevDelUser>Username/IP address</label></td>' +
'</tr><tr><td><input type="button" id="wpMassRevDelSubmit" name="wpMassRevDelSubmit" value="Delete" /></td></tr>' +
'</table>' +
'</form>';
if (config.wgCanonicalSpecialPageName) {
document.querySelector('style').sheet.insertRule(".mw-pager-body [type='checkbox'] {vertical-align: middle;margin: 0 4px");
document.querySelector('.mw-pager-body').insertAdjacentHTML('afterbegin',
'<div class="mw-checkbox-toggle-controls">Select: <a class="mw-checkbox-all" role="button" onclick="' +
"$( 'li input[type="checkbox"]' ).prop( 'checked', true ).trigger( 'change' );" +
'">All</a>, <a class="mw-checkbox-none" role="button" onclick="' +
"$( 'li input[type="checkbox"]' ).prop( 'checked', false ).trigger( 'change' );" +
'">None</a>, <a class="mw-checkbox-invert" role="button" onclick="' +
"$( 'li input[type="checkbox"]' ).prop( 'checked', function ( i, val ) {return !val} ).trigger( 'change' );" +
'">Invert</a></div>'
);
document.querySelectorAll('.mw-revdelundel-link').forEach(span => {
const idsValue = new URLSearchParams(span.querySelector('a').search).get('ids');
if (idsValue) {
span.insertAdjacentHTML(
'afterend',
`<input type="checkbox" name="wpMassRevDelId" value="${idsValue}" onchange="wpMassRevDelCheckRev(event)">`
);
}
});
document.getElementById(bodyContent).innerHTML += pageHtml;
} else {
document.title = "Ahecht's mass-revision-deletion tool - Wikipedia, the free encyclopedia";
document.getElementsByTagName("h1")[0].textContent = "Ahecht's mass-revision-deletion tool";
document.getElementById(bodyContent).innerHTML = pageHtml;
}
document.getElementById("wpMassRevDelReasons").onchange = function() {
var maxlength = (document.getElementById("wpMassRevDelReasons").value == "other" ? 255 : 252-document.getElementById("wpMassRevDelReasons").value.length); //It's 252 because of the three characters (" ()") in addition to the selected summary.
document.getElementById("wpMassRevDelReason").setAttribute("maxlength", maxlength);
};
document.getElementById("wpMassRevDelSubmit").addEventListener("click", function (e) {
doMassRevDel();
});
}
if (config.wgNamespaceNumber == -1 &&
(
config.wgTitle.toLowerCase() == "massrevdel" ||
config.wgCanonicalSpecialPageName == "Contributions"
) &&
/sysop/.test(config.wgUserGroups)
) {
MassRevDelform();
}
});