// Based on [[:meta:User:Indic-TechCom/Script/massMover.js]]
// Advanced functionality
//<nowiki>
$(document).ready(function () {
function initializeMassMove() {
$('#mw-content-text > p').remove();
$('#firstHeading').text('MassMove');
var pagesTextarea = new OO.ui.MultilineTextInputWidget({
placeholder: 'Enter list of pages (one per line)',
autosize: true,
rows: 10
}),
searchInputField = new OO.ui.TextInputWidget({
placeholder: 'Search'
}),
replaceInputField = new OO.ui.TextInputWidget({
placeholder: 'Replace'
}),
reasonInputField = new OO.ui.TextInputWidget({
placeholder: 'Reason for moving'
}),
regexOptionField = new OO.ui.FieldLayout(
regexCheckbox = new OO.ui.CheckboxInputWidget({
selected: false
}),
{
label: 'Use regular expression for search',
align: 'inline'
}
),
previewButton = new OO.ui.ButtonWidget({
label: 'Preview Move',
flags: ['primary']
}),
startButton = new OO.ui.ButtonWidget({
label: 'Start Move',
icon: 'alert',
flags: ['primary', 'progressive'],
disabled: true
}),
cancelButton = new OO.ui.ButtonWidget({
label: 'Cancel',
flags: ['primary', 'destructive'],
href: 'https:' + mw.config.get('wgServer')
}),
logContainer = $("<div>").hide();
var labels = {
pagesLabel: $('<p>').text('Pages to Move:').css('font-weight', 'bold'),
searchLabel: $('<p>').text('Search:').css('font-weight', 'bold'),
replaceLabel: $('<p>').text('Replace:').css('font-weight', 'bold'),
reasonLabel: $('<p>').text('Reason:').css('font-weight', 'bold')
};
$('#mw-content-text').append(
labels.pagesLabel, pagesTextarea.$element,
labels.searchLabel, searchInputField.$element,
labels.replaceLabel, replaceInputField.$element,
labels.reasonLabel, reasonInputField.$element,
regexOptionField.$element,
'<br/>',
previewButton.$element,
startButton.$element,
cancelButton.$element,
'<br/>',
logContainer
);
var redirectCheckbox;
new mw.Api().get({
action: 'query',
meta: 'userinfo',
uiprop: 'rights'
}).done(function (data) {
if (data.query.userinfo.rights.includes('suppressredirect')) {
var redirectOptionField = new OO.ui.FieldLayout(
redirectCheckbox = new OO.ui.CheckboxInputWidget({
selected: false
}),
{
label: "Don't leave a redirect behind (use with caution)",
align: 'inline'
}
);
$(redirectOptionField.$element).insertBefore('<br/>');
$('#mw-content-text').append(redirectOptionField.$element);
}
});
function movePage(oldPage, newPage, reason, removeRedirect, callback) {
(new mw.Api({
ajax: {
headers: {
'Api-User-Agent': 'en:User:DreamRimmer/MassMove.js'
}
}
})).postWithToken('csrf', {
action: 'move',
from: oldPage,
to: newPage,
reason: reason,
movetalk: 1,
noredirect: removeRedirect
}, {
async: false
}).done(function (data) {
callback(null, data, oldPage);
}).fail(function (code, data) {
callback(code, data, oldPage);
});
}
function escapeSpecialChars(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function showAlert(message) {
alert("Error: " + message);
}
function handleMoveResponse(err, data, page) {
var logList = $("<ul>").appendTo(logContainer);
if (err) {
logList.append("<li>Failed to move page <b>" + page + "</b>: " + err + "</li>");
} else if (data.move) {
logList.append("<li><b>" + data.move.from + "</b> moved to <b>" + data.move.to + "</b>.</li>");
}
}
function previewMoving() {
var pages = pagesTextarea.getValue().replace(/^\s*[\r\n]/gm, '').split("\n"),
searchTerm = searchInputField.getValue().trim(),
replacementTerm = replaceInputField.getValue().trim(),
removeRedirect = false,
useRegex = regexCheckbox.isSelected();
if (pages[0].trim() === "" || searchTerm === "" || replacementTerm === "") {
showAlert("Please fill in all fields.");
return;
}
logContainer.empty();
$("<h1>").wrapInner("<span class='mw-headline'>Move preview</span>").appendTo(logContainer);
logContainer.show();
if (redirectCheckbox) {
removeRedirect = redirectCheckbox.isSelected();
}
var logList = $("<ul>").appendTo(logContainer);
pages.forEach(function (page) {
page = page.trim();
var newPageName;
if (!useRegex) {
searchTerm = escapeSpecialChars(searchTerm);
newPageName = page.replace(searchTerm, replacementTerm);
} else {
try {
searchTerm = new RegExp(searchTerm, 'gi');
newPageName = page.replace(searchTerm, replacementTerm);
} catch (e) {
logList.append("<li>Invalid regex for page <b>" + page + "</b>: " + e.message + "</li>");
return;
}
}
logList.append("<li><b>" + page + "</b> will be moved to <b>" + newPageName + "</b> (Redirect: " + (removeRedirect ? "No" : "Yes") + ")</li>");
});
startButton.setDisabled(false);
}
function startMoving() {
var pages = pagesTextarea.getValue().replace(/^\s*[\r\n]/gm, '').split("\n"),
searchTerm = searchInputField.getValue().trim(),
replacementTerm = replaceInputField.getValue().trim(),
reason = reasonInputField.getValue().trim() + " (using [[User:DreamRimmer/MassMove|MassMove.js]])",
removeRedirect = false,
useRegex = regexCheckbox.isSelected();
if (pages[0].trim() === "" || searchTerm === "" || replacementTerm === "") {
showAlert("Please fill in all fields.");
return;
}
logContainer.empty();
$("<h1>").wrapInner("<span class='mw-headline'>Move log</span>").appendTo(logContainer);
logContainer.show();
if (redirectCheckbox) {
removeRedirect = redirectCheckbox.isSelected();
}
var currentIndex = 0;
var isSysop = $.inArray('sysop', mw.config.get('wgUserGroups')) !== -1;
function getRandomSleepTime() {
var sleepTimes = [6000, 7000, 8000];
return sleepTimes[Math.floor(Math.random() * sleepTimes.length)];
}
function processNextPage() {
if (currentIndex >= pages.length) return;
var page = pages[currentIndex].trim(),
newPageName;
if (!useRegex) {
searchTerm = escapeSpecialChars(searchTerm);
newPageName = page.replace(searchTerm, replacementTerm);
} else {
try {
searchTerm = new RegExp(searchTerm, 'gi');
newPageName = page.replace(searchTerm, replacementTerm);
} catch (e) {
alert("Invalid regex: " + e.message);
currentIndex++;
processNextPage();
return;
}
}
movePage(page, newPageName, reason, removeRedirect, function (err, data) {
handleMoveResponse(err, data, page);
currentIndex++;
if (!err) {
setTimeout(processNextPage, isSysop ? 2000 : getRandomSleepTime());
} else {
processNextPage();
}
});
}
processNextPage();
}
previewButton.on('click', previewMoving);
startButton.on('click', startMoving);
}
$.when(mw.loader.using('mediawiki.util'), $.ready).then(function () {
mw.util.addPortletLink('p-tb', mw.util.getUrl('Special:BlankPage/MassMove'), 'MassMove');
});
if (mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' &&
mw.config.get('wgTitle').split('/', 2)[1] === 'MassMove') {
$.when(mw.loader.using('oojs-ui-core'), $.ready).then(function () {
initializeMassMove();
});
}
});
//</nowiki>