מדיה ויקי:סקריפטים/107.js
הערה: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.
- פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
- גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
- אינטרנט אקספלורר / אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
- אופרה: ללחוץ על Ctrl-F5.
/**
*
* סקריפט זה מקל על הטיפול בטרולים ובמשחיתים.
* הוא מאפשר לשחזר את כל העריכות שביצע משתמש מסוים, למחוק את כל הדפים שיצר,
* לחסום אותו ולהסתיר את כל עריכותיו בלחיצת כפתור.
* למידע נוסף ולהוראות שימוש ראו:
* [[ויקיפדיה:סקריפטים/107.js/מידע]]
*
* This tool allows you to handle vandalism more easily.
* It adds a button on "Contribution" pages, that lets you
* rollback all edits made by the relevant user/IP,
* as well as delete all pages created by him/her, block him/her
* and hide all his/her edits – all in one single operation.
*
* Written by: [[User:Guycn2]] @ he.wikipedia.org
*
* If you export this script to your wiki, please include the above lines.
*
*/
if (
mw.config.get("wgCanonicalSpecialPageName") === "Contributions" &&
mw.config.get("wgRelevantUserName") !== mw.config.get("wgUserName")
) {
mw.loader.load(
"//he.wikipedia.org/w/index.php?title=מדיה_ויקי:סקריפטים/107.css" +
"&action=raw&ctype=text/css", "text/css"
);
$.when(mw.loader.using(["mediawiki.util", "mediawiki.api"]), $.ready).done(function() {
"use strict";
var relevantUser = mw.config.get("wgRelevantUserName"),
api = new mw.Api(),
currentUserRights = [],
relevantUserGender = "",
interfaceMessages = {},
isRelevantUserAnon = mw.util.isIPAddress(relevantUser),
contribsPeriod = 0,
queryLimit = 0,
latestEdits = [],
totalEdits = 0,
createdPages = [],
totalPages = 0,
revIDs = [],
totalIDs = 0,
tagExists = true,
$dialog = {},
isRollbackChecked = false,
isDeleteChecked = false,
isBlockChecked = false,
isRevDeleteChecked = false,
isHideSummariesChecked = false,
cleanerSummary = "",
blockDuration = "",
totalTasks = 0,
currentTask = 0,
failedBlock = false,
editNumber = 0,
rollbackPercent = 0,
failedRollbacks = false,
pageNumber = 0,
deletePercent = 0,
failedDeletions = false,
idNumber = 0,
revDeletePercent = 0,
failedRevDeletions = false;
api.get({
list: "users",
usprop: "rights|gender",
ususers: relevantUser + "|" + mw.config.get("wgUserName")
}).done(function(data) {
var relevantUserRights = data.query.users[0].rights;
currentUserRights = data.query.users[1].rights;
relevantUserGender = data.query.users[0].gender;
if (
isRelevantUserAnon ||
(
typeof relevantUserRights !== "undefined" &&
relevantUserRights.indexOf("autopatrol") < 0
)
) {
$.getScript(
"//he.wikipedia.org/w/index.php?title=מדיה_ויקי:סקריפטים/107.js/config.js" +
"&action=raw&ctype=text/javascript",
function() {
interfaceMessages =
window.vandalCleanerConfig.messages[mw.config.get("wgUserLanguage")] ||
window.vandalCleanerConfig.messages.en;
contribsPeriod = window.vandalCleanerConfig.contribsPeriod;
queryLimit = window.vandalCleanerConfig.queryLimit;
$("#contentSub").after(
$("<button>", {
type: "button",
"class": "mw-ui-button mw-ui-destructive",
id: "vandal-cleaner-button",
title: i18n("contribsLinkTooltip"),
text: i18n("contribsLinkText")
}).on("click", function() {
initializeTool(setOldestContribsDate());
})
);
}
);
}
});
function i18n(key) {
key = interfaceMessages[key] || key;
var isAnonPattern = /<<ISANON\|(.*?)\|(.*?)(>>)/g,
genderPattern = /<<GENDER\|(.*?)\|(.*?)(>>)/g,
extendedGenderPattern = /<<GENDER\|(.*?)\|(.*?)\|(.*?)(>>)/g;
key = key
.replace(isAnonPattern, isRelevantUserAnon ? "$1" : "$2")
.replace(
extendedGenderPattern,
relevantUserGender === "female" ? "$2" : (relevantUserGender === "male" ? "$1" : "$3")
)
.replace(genderPattern, relevantUserGender === "female" ? "$2" : "$1")
.replace(/\$RELEVANTUSER/g, relevantUser)
.replace(/\$CONTRIBSPERIOD/g, contribsPeriod)
.replace(/\$QUERYLIMIT/g, queryLimit)
.replace(/(<<|>>)/g, "");
return key;
}
function initializeTool(oldestContribsDate) {
if ($("#vandal-cleaner-interface-dialog").length) {
console.log("Vandal Cleaner dialog is already open.");
return;
}
mw.util.$content.append(
$("<div>", {
"class": "vandal-cleaner-dark-cover"
}).append(
$("<img>", {
id: "vandal-cleaner-loading-image",
src: "//upload.wikimedia.org/wikipedia/commons/1/14/Ajax-loader_bert2_blue-white.gif",
alt: i18n("loadingInterface")
})
)
);
var $loadingCover = $(".vandal-cleaner-dark-cover").fadeTo("_default", 1);
api.get({
list: "usercontribs",
ucuser: relevantUser,
ucprop: "title",
ucshow: "top|!new",
uclimit: queryLimit,
ucend: oldestContribsDate
}).done(function(editsQuery) {
latestEdits = editsQuery.query.usercontribs;
totalEdits = latestEdits.length;
api.get({
list: "usercontribs",
ucuser: relevantUser,
ucprop: "title",
ucshow: "new",
uclimit: queryLimit,
ucend: oldestContribsDate
}).done(function(pagesQuery) {
createdPages = pagesQuery.query.usercontribs;
totalPages = createdPages.length;
api.get({
list: "usercontribs",
ucuser: relevantUser,
ucprop: "ids",
ucshow: "!new",
uclimit: queryLimit,
ucend: oldestContribsDate
}).done(function(idsQuery) {
revIDs = idsQuery.query.usercontribs;
totalIDs = revIDs.length;
// Check if [[MediaWiki:Tag-VandalCleaner]] exists to determine
// whether or not actions made using this script should be tagged.
api.get({
titles: "MediaWiki:Tag-VandalCleaner"
}).done(function(tagQuery) {
if (tagQuery.query.pages[-1]) {
// If [[MediaWiki:Tag-VandalCleaner]] does not exist, then the actual
// "VandalCleaner" tag is also not likely to exist. In this case,
// all actions made using this script must not use that tag; otherwise
// they will fail with the "tags-apply-not-allowed-one" error.
tagExists = false;
}
$.when(mw.loader.using("jquery.ui", createDialog)).done(function() {
$loadingCover.fadeOut("fast", function() {
$(this).remove();
});
});
});
});
});
});
}
function setOldestContribsDate() {
var date = new Date();
date.setTime(date.getTime() - (contribsPeriod * 24 * 60 * 60 * 1000));
var year = date.getUTCFullYear(),
month = date.getUTCMonth() + 1,
day = date.getUTCDate(),
hours = date.getUTCHours(),
minutes = date.getUTCMinutes(),
seconds = date.getUTCSeconds();
return year + "-" +
(month < 10 ? "0" + month : month) + "-" +
(day < 10 ? "0" + day : day) + "T" +
(hours < 10 ? "0" + hours : hours) + ":" +
(minutes < 10 ? "0" + minutes : minutes) + ":" +
(seconds < 10 ? "0" + seconds : seconds) + "Z";
}
function createDialog() {
$dialog = $("<div>", {
id: "vandal-cleaner-interface-dialog",
"data-state": "selection"
});
var $para1 = $("<p>", {
text: i18n("para1")
}),
$para2 = $("<p>", {
text: i18n("para2")
}),
$para3 = $("<p>", {
text: i18n("para3")
}),
$rollbackField = $("<div>", {
"class": "vandal-cleaner-field"
}),
$deleteField = $("<div>", {
"class": "vandal-cleaner-field"
}),
$blockField = $("<div>", {
"class": "vandal-cleaner-field"
}),
$revDeleteField = $("<div>", {
"class": "vandal-cleaner-field"
}),
$summary = $("<div>", {
id: "vandal-cleaner-edit-summary"
});
$rollbackField.append(
$("<input>", {
type: "checkbox",
"class": "vandal-cleaner-field-tog",
id: "vandal-cleaner-rollback-tog"
}),
$("<label>", {
"class": "vandal-cleaner-field-label",
"for": "vandal-cleaner-rollback-tog",
text: i18n("rollbackLabel")
}),
$("<div>", {
"class": "vandal-cleaner-field-info-wrapper"
}).append(
$("<p>", {
"class": "vandal-cleaner-field-description",
text: i18n("rollbackDesc")
}),
$("<p>", {
"class": "vandal-cleaner-field-attention",
id: "vandal-cleaner-rollback-no-permission",
text: i18n("cannotRollback")
}),
$("<p>", {
"class": "vandal-cleaner-field-attention",
id: "vandal-cleaner-rollback-too-many",
text: i18n("tooManyEdits")
})
)
);
$deleteField.append(
$("<input>", {
type: "checkbox",
"class": "vandal-cleaner-field-tog",
id: "vandal-cleaner-delete-tog"
}),
$("<label>", {
"class": "vandal-cleaner-field-label",
"for": "vandal-cleaner-delete-tog",
text: i18n("deleteLabel")
}),
$("<div>", {
"class": "vandal-cleaner-field-info-wrapper"
}).append(
$("<p>", {
"class": "vandal-cleaner-field-description",
text: i18n("deleteDesc")
}),
$("<p>", {
"class": "vandal-cleaner-field-attention",
id: "vandal-cleaner-delete-no-permission",
text: i18n("cannotDelete")
}),
$("<p>", {
"class": "vandal-cleaner-field-attention",
id: "vandal-cleaner-delete-too-many",
text: i18n("tooManyPages")
})
)
);
$blockField.append(
$("<input>", {
type: "checkbox",
"class": "vandal-cleaner-field-tog",
id: "vandal-cleaner-block-tog"
}),
$("<label>", {
"class": "vandal-cleaner-field-label",
"for": "vandal-cleaner-block-tog",
text: i18n("blockLabel")
}),
$("<div>", {
"class": "vandal-cleaner-field-info-wrapper"
}).append(
$("<p>", {
"class": "vandal-cleaner-field-description",
text: i18n("blockDesc")
}),
$("<p>", {
id: "vandal-cleaner-block-duration-container"
}).append(
$("<label>", {
"for": "vandal-cleaner-block-duration-dropdown",
text: i18n("blockDuration")
}),
" ",
$("<span>", {
id: "vandal-cleaner-block-duration-current"
}),
" ",
$("<span>", {
id: "vandal-cleaner-block-duration-change-container"
}).append(
$("<span>", {
text: "("
}),
$("<a>", {
id: "vandal-cleaner-block-duration-change",
role: "button",
href: "#",
text: i18n("changeBlockDuration")
}),
$("<span>", {
text: ")"
})
),
$("<select>", {
id: "vandal-cleaner-block-duration-dropdown"
})
),
$("<p>", {
"class": "vandal-cleaner-field-attention",
id: "vandal-cleaner-block-no-permission",
text: i18n("cannotBlock")
})
)
);
$revDeleteField.append(
$("<input>", {
type: "checkbox",
"class": "vandal-cleaner-field-tog",
id: "vandal-cleaner-revdelete-tog"
}),
$("<label>", {
"class": "vandal-cleaner-field-label",
"for": "vandal-cleaner-revdelete-tog",
text: i18n("revDeleteLabel")
}),
$("<div>", {
"class": "vandal-cleaner-field-info-wrapper"
}).append(
$("<p>", {
"class": "vandal-cleaner-field-description",
text: i18n("revDeleteDesc")
}),
$("<p>", {
id: "vandal-cleaner-revdelete-advanced-container"
}).append(
$("<input>", {
type: "checkbox",
id: "vandal-cleaner-revdelete-hide-summaries-tog"
}),
$("<label>", {
"for": "vandal-cleaner-revdelete-hide-summaries-tog",
text: i18n("hideSummaries")
})
).hide(),
$("<p>", {
"class": "vandal-cleaner-field-attention",
id: "vandal-cleaner-revdelete-no-permission",
text: i18n("cannotRevDelete")
}),
$("<p>", {
"class": "vandal-cleaner-field-attention",
id: "vandal-cleaner-revdelete-too-many",
text: i18n("tooManyRevisions")
})
)
);
$summary.append(
$("<p>").append(
$("<label>", {
"for": "vandal-cleaner-summary-input",
text: i18n("summaryInfo")
.replace(
/\$DEFAULTSUMMARY/g,
window.vandalCleanerSummary || i18n("summaryValue")
)
})
),
$("<input>", {
type: "text",
id: "vandal-cleaner-summary-input",
placeholder: i18n("summaryPlaceholder"),
value: window.vandalCleanerSummary || i18n("summaryValue"),
maxlength: "500"
})
);
$dialog.append(
$para1, $para2, $para3, $rollbackField, $deleteField,
$blockField, $revDeleteField, $summary
).dialog({
title: i18n("dialogTitle"),
resizable: false,
draggable: false,
open: function() {
$dialog.parent().addClass("vandal-cleaner-dialog-wrapper");
if (currentUserRights.indexOf("rollback") < 0) {
$rollbackField.find("#vandal-cleaner-rollback-tog").prop("disabled", true);
$rollbackField.find("#vandal-cleaner-rollback-no-permission").show();
} else {
$rollbackField.find("#vandal-cleaner-rollback-tog").prop("checked", true);
if (totalEdits >= queryLimit) {
$rollbackField.find("#vandal-cleaner-rollback-too-many").show();
$rollbackField.find("#vandal-cleaner-rollback-tog").on("change", function() {
$rollbackField.find("#vandal-cleaner-rollback-too-many").slideToggle("fast");
});
}
}
if (currentUserRights.indexOf("delete") < 0) {
$deleteField.find("#vandal-cleaner-delete-tog").prop("disabled", true);
$deleteField.find("#vandal-cleaner-delete-no-permission").show();
} else {
$deleteField.find("#vandal-cleaner-delete-tog").prop("checked", true);
if (totalPages >= queryLimit) {
$deleteField.find("#vandal-cleaner-delete-too-many").show();
$deleteField.find("#vandal-cleaner-delete-tog").on("change", function() {
$deleteField.find("#vandal-cleaner-delete-too-many").slideToggle("fast");
});
}
}
if (currentUserRights.indexOf("block") < 0) {
$blockField.find("#vandal-cleaner-block-duration-container").hide();
$blockField.find("#vandal-cleaner-block-tog").prop("disabled", true);
$blockField.find("#vandal-cleaner-block-no-permission").show();
} else {
for (let i = 0; i < window.vandalCleanerConfig.blockOptions.length; i++) {
let blockOption = window.vandalCleanerConfig.blockOptions[i];
$blockField.find("#vandal-cleaner-block-duration-dropdown").append(
$("<option>", {
value: blockOption.duration,
text: i18n(blockOption.message)
})
);
if (blockOption.makeDefault === "anon" && isRelevantUserAnon) {
$blockField.find("option[value='" + blockOption.duration + "']")
.prop("selected", true);
$blockField.find("#vandal-cleaner-block-duration-current")
.text(i18n(blockOption.message));
} else if (blockOption.makeDefault === "registered" && !isRelevantUserAnon) {
$blockField.find("option[value='" + blockOption.duration + "']")
.prop("selected", true);
$blockField.find("#vandal-cleaner-block-duration-current")
.text(i18n(blockOption.message));
}
}
$blockField.find("#vandal-cleaner-block-tog").prop("checked", true);
$blockField.find("#vandal-cleaner-block-tog").on("change", function() {
$blockField.find("#vandal-cleaner-block-duration-container").slideToggle("fast");
});
$blockField.find("#vandal-cleaner-block-duration-change").on("click", function(e) {
e.preventDefault();
$blockField.find(
"#vandal-cleaner-block-duration-current," +
"#vandal-cleaner-block-duration-change-container"
).hide();
$blockField.find("#vandal-cleaner-block-duration-dropdown").show();
});
}
if (currentUserRights.indexOf("deleterevision") < 0) {
$revDeleteField.find("#vandal-cleaner-revdelete-tog").prop("disabled", true);
$revDeleteField.find("#vandal-cleaner-revdelete-no-permission").show();
} else {
$revDeleteField.find("#vandal-cleaner-revdelete-tog").on("change", function() {
$revDeleteField.find("#vandal-cleaner-revdelete-advanced-container").slideToggle("fast");
if (totalIDs >= queryLimit) {
$revDeleteField.find("#vandal-cleaner-revdelete-too-many").slideToggle("fast");
}
});
}
$summary.find("#vandal-cleaner-summary-input").on("keypress", function(e) {
if (e.which === 13) {
runCleaner();
}
});
},
close: function() {
$dialog.remove();
},
buttons: [
{
id: "vandal-cleaner-run-btn",
text: i18n("runCleaner"),
click: runCleaner
},
{
text: i18n("cancel"),
click: function() {
$dialog.dialog("close");
}
}
]
});
}
function runCleaner() {
isRollbackChecked =
$dialog.find("#vandal-cleaner-rollback-tog").prop("checked");
isDeleteChecked =
$dialog.find("#vandal-cleaner-delete-tog").prop("checked");
isBlockChecked =
$dialog.find("#vandal-cleaner-block-tog").prop("checked");
blockDuration =
$dialog.find("#vandal-cleaner-block-duration-dropdown").val();
isRevDeleteChecked =
$dialog.find("#vandal-cleaner-revdelete-tog").prop("checked");
isHideSummariesChecked =
$dialog.find("#vandal-cleaner-revdelete-hide-summaries-tog").prop("checked");
cleanerSummary =
$dialog.find("#vandal-cleaner-summary-input").val();
if (!isRollbackChecked && !isDeleteChecked && !isBlockChecked && !isRevDeleteChecked) {
alert(i18n("noActionSelected"));
return;
}
totalTasks =
(isBlockChecked ? 1 : 0) +
(isRollbackChecked ? totalEdits : 0) +
(isDeleteChecked ? totalPages : 0) +
(isRevDeleteChecked ? totalIDs : 0);
var $pleaseWait = $("<h5>", {
text: i18n("pleaseWait")
}),
$totalProgress = $("<div>", {
id: "vandal-cleaner-total-progress-container"
}).append(
$("<div>", {
id: "vandal-cleaner-total-progress-value"
})
),
$blockStatus = $("<p>", {
"class": "vandal-cleaner-status vandal-cleaner-status-working",
id: "vandal-cleaner-block-status",
text: i18n("blocking")
}).append(
$("<span>", {
text: " ... "
}).append(
$("<bdi>", {
id: "vandal-cleaner-block-percent",
text: "0"
})
)
),
$blockFailed = $("<p>", {
"class": "vandal-cleaner-failure",
id: "vandal-cleaner-block-failed",
text: i18n("blockFailed")
}),
$rollbackStatus = $("<p>", {
"class": "vandal-cleaner-status vandal-cleaner-status-working",
id: "vandal-cleaner-rollback-status",
text: i18n("rollbacking")
}).append(
$("<span>", {
text: " ... "
}).append(
$("<bdi>", {
id: "vandal-cleaner-rollback-percent",
text: "0"
})
)
),
$rollbackNoEdits = $("<p>", {
"class": "vandal-cleaner-info",
id: "vandal-cleaner-rollback-no-edits",
text: i18n("rollbackNoEdits")
}),
$rollbackFailed = $("<p>", {
"class": "vandal-cleaner-failure",
id: "vandal-cleaner-rollback-failed",
text: i18n("rollbackFailed")
}),
$deleteStatus = $("<p>", {
"class": "vandal-cleaner-status vandal-cleaner-status-working",
id: "vandal-cleaner-delete-status",
text: i18n("deleting")
}).append(
$("<span>", {
text: " ... "
}).append(
$("<bdi>", {
id: "vandal-cleaner-delete-percent",
text: "0"
})
)
),
$deleteNoPages = $("<p>", {
"class": "vandal-cleaner-info",
id: "vandal-cleaner-delete-no-pages",
text: i18n("deleteNoPages")
}),
$deleteFailed = $("<p>", {
"class": "vandal-cleaner-failure",
id: "vandal-cleaner-delete-failed",
text: i18n("deleteFailed")
}),
$revDeleteStatus = $("<p>", {
"class": "vandal-cleaner-status vandal-cleaner-status-working",
id: "vandal-cleaner-revdelete-status",
text: i18n("revDeleting")
}).append(
$("<span>", {
text: " ... "
}).append(
$("<bdi>", {
id: "vandal-cleaner-revdelete-percent",
text: "0"
})
)
),
$revDeleteNoEdits = $("<p>", {
"class": "vandal-cleaner-info",
id: "vandal-cleaner-revdelete-no-edits",
text: i18n("revDeleteNoEdits")
}),
$revDeleteFailed = $("<p>", {
"class": "vandal-cleaner-failure",
id: "vandal-cleaner-revdelete-failed",
text: i18n("revDeleteFailed")
});
$dialog.children().remove().end()
.attr("data-state", "working")
.append(
$pleaseWait, $totalProgress, $blockStatus, $blockFailed, $rollbackStatus,
$rollbackNoEdits, $rollbackFailed, $deleteStatus, $deleteNoPages,
$deleteFailed, $revDeleteStatus, $revDeleteNoEdits, $revDeleteFailed
)
.dialog({
buttons: [],
close: function() {
window.location.reload();
}
});
if (isBlockChecked) {
hermeticBlock();
} else if (isRollbackChecked) {
massRollback();
} else if (isDeleteChecked) {
massDelete();
} else if (isRevDeleteChecked) {
massRevDelete();
}
}
function hermeticBlock() {
var $status = $dialog.find("#vandal-cleaner-block-status");
hideTopBorderIfNeeded($status);
$status.fadeIn();
api.postWithToken("csrf", {
action: "block",
user: relevantUser,
expiry: blockDuration,
nocreate: true,
autoblock: true,
noemail: true,
reblock: true,
reason: cleanerSummary,
tags: tagExists ? "VandalCleaner" : ""
}).then(
function() {
$dialog.find("#vandal-cleaner-block-percent").text("100");
$status
.removeClass("vandal-cleaner-status-working")
.addClass("vandal-cleaner-status-complete");
},
function() {
$status.hide();
$dialog.find("#vandal-cleaner-block-failed").show();
$dialog.find("#vandal-cleaner-total-progress-value").attr("data-failure", "yes");
failedBlock = true;
}
).always(function() {
moveOn("block");
});
}
function massRollback() {
var $status = $dialog.find("#vandal-cleaner-rollback-status");
if (totalEdits === 0) {
let $noEdits = $dialog.find("#vandal-cleaner-rollback-no-edits");
hideTopBorderIfNeeded($noEdits);
$noEdits.fadeIn();
moveOn("rollback", $status);
} else {
if (editNumber === 0) {
hideTopBorderIfNeeded($status);
$status.fadeIn();
}
api.postWithToken("rollback", {
action: "rollback",
title: latestEdits[editNumber].title,
user: relevantUser,
summary: cleanerSummary,
tags: tagExists ? "VandalCleaner" : ""
}).fail(function() {
$dialog.find("#vandal-cleaner-rollback-failed").fadeIn();
$dialog.find("#vandal-cleaner-total-progress-value").attr("data-failure", "yes");
failedRollbacks = true;
}).always(function() {
moveOn("rollback", $status);
});
}
}
function massDelete() {
var $status = $dialog.find("#vandal-cleaner-delete-status");
if (totalPages === 0) {
let $noPages = $dialog.find("#vandal-cleaner-delete-no-pages");
hideTopBorderIfNeeded($noPages);
$noPages.fadeIn();
moveOn("delete", $status);
} else {
if (pageNumber === 0) {
hideTopBorderIfNeeded($status);
$status.fadeIn();
}
api.postWithToken("csrf", {
action: "delete",
title: createdPages[pageNumber].title,
reason: cleanerSummary,
tags: tagExists ? "VandalCleaner" : ""
}).fail(function() {
$dialog.find("#vandal-cleaner-delete-failed").fadeIn();
$dialog.find("#vandal-cleaner-total-progress-value").attr("data-failure", "yes");
failedDeletions = true;
}).always(function() {
moveOn("delete", $status);
});
}
}
function massRevDelete() {
var $status = $dialog.find("#vandal-cleaner-revdelete-status");
if (totalIDs === 0) {
let $noEdits = $dialog.find("#vandal-cleaner-revdelete-no-edits");
hideTopBorderIfNeeded($noEdits);
$noEdits.fadeIn();
moveOn("revdelete", $status);
} else {
if (idNumber === 0) {
hideTopBorderIfNeeded($status);
$status.fadeIn();
}
api.postWithToken("csrf", {
action: "revisiondelete",
type: "revision",
ids: revIDs[idNumber].revid,
hide: isHideSummariesChecked ? "content|comment" : "content",
reason: cleanerSummary,
tags: tagExists ? "VandalCleaner" : ""
}).fail(function() {
$dialog.find("#vandal-cleaner-revdelete-failed").fadeIn();
$dialog.find("#vandal-cleaner-total-progress-value").attr("data-failure", "yes");
failedRevDeletions = true;
}).always(function() {
moveOn("revdelete", $status);
});
}
}
function hideTopBorderIfNeeded($element) {
if (!$element.siblings("p:visible").length) {
$element.css("border-top-style", "hidden");
}
}
function moveOn(currentAction, $status) {
switch (currentAction) {
case "block":
updateProgressBar();
setTimeout(function() {
if (isRollbackChecked) {
massRollback();
} else if (isDeleteChecked) {
massDelete();
} else if (isRevDeleteChecked) {
massRevDelete();
} else {
finalizeTool();
}
}, 800);
break;
case "rollback":
if (totalEdits > 0) {
updateProgressBar();
rollbackPercent = ++editNumber / totalEdits * 100;
$dialog.find("#vandal-cleaner-rollback-percent").text(rollbackPercent.toFixed(0));
}
if (editNumber < totalEdits) {
if (currentUserRights.indexOf("noratelimit") < 0 && totalEdits > 10) {
// If we don't have the "noratelimit" right, and the vandal has
// made more than 10 edits, then we need to act more slowly;
// otherwise our actions might be throttled by the system!
if (editNumber >= 1 && editNumber <= Math.floor((totalEdits - 1) / 10) * 10 + 1) {
// Rollback slowly to avoid reaching the rate limit:
setTimeout(massRollback, 6200);
} else {
// We have less than 10 edits left, so we can now do it more quickly:
setTimeout(massRollback, 800);
}
} else {
// Either we have the "noratelimit" right and/or the vandal
// has made <=10 edits, so we can rollback all edits quickly:
setTimeout(massRollback, 700);
}
} else {
$status
.removeClass("vandal-cleaner-status-working")
.addClass("vandal-cleaner-status-complete");
setTimeout(function() {
if (isDeleteChecked) {
massDelete();
} else if (isRevDeleteChecked) {
massRevDelete();
} else {
finalizeTool();
}
}, 800);
}
break;
case "delete":
if (totalPages > 0) {
updateProgressBar();
deletePercent = ++pageNumber / totalPages * 100;
$dialog.find("#vandal-cleaner-delete-percent").text(deletePercent.toFixed(0));
}
if (pageNumber < totalPages) {
setTimeout(massDelete, 700);
} else {
$status
.removeClass("vandal-cleaner-status-working")
.addClass("vandal-cleaner-status-complete");
setTimeout(function() {
if (isRevDeleteChecked) {
massRevDelete();
} else {
finalizeTool();
}
}, 800);
}
break;
case "revdelete":
if (totalIDs > 0) {
updateProgressBar();
revDeletePercent = ++idNumber / totalIDs * 100;
$dialog.find("#vandal-cleaner-revdelete-percent").text(revDeletePercent.toFixed(0));
}
if (idNumber < totalIDs) {
setTimeout(massRevDelete, 700);
} else {
$status
.removeClass("vandal-cleaner-status-working")
.addClass("vandal-cleaner-status-complete");
setTimeout(finalizeTool, 800);
}
}
}
function updateProgressBar() {
$dialog.find("#vandal-cleaner-total-progress-value")
.css("width", (++currentTask / totalTasks * 100) + "%");
}
function finalizeTool() {
var $thumbImg = $("<img>", {
id: "vandal-cleaner-thumb-img",
src: "//upload.wikimedia.org/wikipedia/commons/c/ce/Emoji_u1f44d.svg",
alt: i18n("finishedRunning")
}),
$finishedRunning = $("<h6>", {
id: "vandal-cleaner-finished-running-heading",
text: i18n("finishedRunning")
}),
$failureWarning = $("<p>", {
"class": "warning",
id: "vandal-cleaner-failure-warning",
html: i18n("failureWarning")
.replace(
/\$LINK/g,
mw.util.getUrl("Special:Contributions", {target: relevantUser, topOnly: "1"})
)
}),
$para4 = $("<p>", {
text: i18n("para4")
}),
$para5 = $("<p>", {
html: i18n("para5")
.replace(/\$LINK/g, "//he.wikipedia.org/wiki/שיחת_מדיה_ויקי:סקריפטים/107.js")
}),
$para6 = $("<p>", {
text: i18n("para6").replace(/\$SITENAME/g, mw.config.get("wgSiteName"))
}),
$para7 = $("<p>", {
text: i18n("para7")
});
$dialog.parent()
.addClass("vandal-cleaner-dialog-wrapper-disappear")
.on("transitionend", function() {
$dialog.remove();
$dialog = $("<div>", {
id: "vandal-cleaner-finished-dialog"
});
$dialog.append(
$thumbImg, $finishedRunning, $failureWarning, $para4, $para5, $para6, $para7
).dialog({
title: i18n("dialogTitle"),
resizable: false,
draggable: false,
open: function() {
$dialog.parent()
.wrap(
$("<div>", {
"class": "vandal-cleaner-dark-cover"
})
)
.addClass("vandal-cleaner-dialog-wrapper vandal-cleaner-dialog-wrapper-reappear")
.parent().fadeTo("_default", 1)
.end().find("#vandal-cleaner-close-and-reload-btn").focus();
if (failedBlock || failedRollbacks || failedDeletions || failedRevDeletions) {
$dialog.find("#vandal-cleaner-failure-warning").show();
}
},
close: function() {
$dialog.closest(".vandal-cleaner-dark-cover").remove().end().remove();
window.location.reload();
},
buttons: [
{
id: "vandal-cleaner-close-and-reload-btn",
text: i18n("closeAndReload"),
click: function() {
$dialog.dialog("close");
}
}
]
});
});
}
});
}