Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**
* @Name MassUserRights
* @Version v2.4
* @Author KnazO
* @Author TheGoldenPatrik1
* @Description Mass add/remove usergroups from listed users
* @Protect <nowiki>
*/
/* jshint
esversion: 5, forin: true,
immed: true, indent: 4,
newcap: true, undef: true,
unused: true,
browser: true, jquery: true,
onevar: true, eqeqeq: true,
multistr: true, maxerr: 999999,
-W082, -W084
*/
/* global mw, importArticles, importArticle */
mw.loader.using([
'mediawiki.api',
'mediawiki.user'
], function () {
'use strict';
var config = mw.config.get([
'wgUserGroups',
'wgUserName'
]);
if (
window.MassUserRightsLoaded ||
!/sysop|bureaucrat|staff|wiki-specialist|util/.test(config.wgUserGroups.join())
) {
return;
}
window.MassUserRightsLoaded = true;
var i18n,
placement,
rightsModal,
preloads = 3,
Api = new mw.Api(),
paused = true,
groups = [
'bureaucrat',
'sysop',
'content-moderator',
'threadmoderator',
'rollback',
],
messages = {},
customGroups = window.massUserRightsCustom;
// Message fetch by KockaAdmiralac
Api.get({
action: 'query',
meta: 'allmessages',
ammessages: groups.map(function(msg) {
return 'userprofile-global-tag-' + msg;
}).join('|')
}).then(function(d) {
d.query.allmessages.forEach(function(msg, i) {
messages[groups[i]] = msg['*'];
});
/**
* @method generateElement
* @description Creates an option element
* @param {String} type - The options's value
* @param {String} isI18n - If the message uses I18n-js
*/
function generateElement (type, isI18n) {
return $('<option>', {
value: type,
text: isI18n ? i18n.msg(type).plain() : messages[type]
});
}
/**
* @method formHtml
* @description Creates the modal HTML
*/
function formHtml () {
return $('<form>', {
'class': 'WikiaForm'
}).append(
$('<fieldset>').append(
$('<p>', {
text: i18n.msg('mode').plain()
}).append(
$('<select>', {
id: 'user-rights-mode'
}).append(
$('<option>', {
value: '0',
text: i18n.msg('add').plain()
}),
$('<option>', {
value: '1',
text: i18n.msg('remove').plain()
})
)
),
$('<p>', {
text: i18n.msg('type').plain()
}).append(
$('<select>', {
id: 'user-rights-type'
}).append(
generateElement('bureaucrat'),
generateElement('sysop'),
generateElement('content-moderator'),
generateElement('threadmoderator'),
generateElement('rollback', true)
)
),
$('<p>', {
text: i18n.msg('reason').plain()
}).append (
$('<input>', {
type: 'text',
id: 'user-rights-reason'
})
),
$('<p>', {
text: i18n.msg('instructions').plain()
}),
$('<textarea>', {
id: 'text-mass-user-rights'
}),
$('<div>', {
id: 'text-error-output',
text: i18n.msg('errors').plain()
}).append(
$('<br/>')
)
)
).prop('outerHTML');
}
/**
* @method preload
* @description Preloads the script and the hooks
*/
function preload () {
if (--preloads === 0) {
placement = window.dev.placement.loader;
window.dev.i18n.loadMessages('MassUserRights').then(init);
}
}
/**
* @method init
* @description Initiates the script
* @param {String} i18nData - Variable for I18n-js
*/
function init (i18nData) {
i18n = i18nData;
placement.script('MassUserRights');
$(placement.element('tools'))[placement.type('prepend')](
$('<li>', {
'class': 'custom'
}).append(
$('<a>', {
id: 't-mu',
text: i18n.msg('title').plain(),
click: click
})
)
);
}
/**
* @method click
* @description Opens the MassUserRights modal
*/
function click () {
if (rightsModal) {
rightsModal.show();
show();
return;
}
rightsModal = new window.dev.modal.Modal({
content: formHtml(),
id: 'form-mass-user-rights',
size: 'medium',
title: i18n.msg('title').escape(),
buttons: [
{
id: 'mur-start',
text: i18n.msg('initiate').escape(),
primary: true,
event: 'start'
},
{
id: 'mur-pause',
text: i18n.msg('pause').escape(),
primary: true,
event: 'pause',
disabled: true
},
{
text: i18n.msg('group').escape(),
primary: true,
event: 'addGroupContents'
},
{
text: i18n.msg('cancel').escape(),
event: 'close'
}
],
events: {
addGroupContents: addGroupContents,
pause: pause,
start: start
}
});
rightsModal.create().then(show);
rightsModal.show();
}
/**
* @method show
* @description Handles some aspects of the modal
*/
function show () {
// Removes options admins can't use
if (!/bureaucrat|staff|wiki-specialist|util/.test(config.wgUserGroups.join())) {
$('#user-rights-type option[value="rollback"],#user-rights-type option[value="sysop"],#user-rights-type option[value="content-moderator"],#user-rights-type option[value="bureaucrat"]').remove();
}
// Support for custom groups
if (customGroups) {
$.each(customGroups, function(i,v) {
var split = v.split('|');
if (
document.domain.split('.')[0] === split[0]
&& (typeof(split)[3] === 'string' ? split[3].split(/\s*,\s*/).some(function(v) { return !!~config.wgUserGroups.indexOf(v) }) : true)
) {
$('#user-rights-type').append(
$('<option>', {
value: split[1],
text: split[2]
})
);
}
});
}
}
/**
* @method pause
* @description Pauses the operation
*/
function pause () {
paused = true;
document.getElementById('mur-pause').setAttribute('disabled', '');
document.getElementById('mur-start').removeAttribute('disabled');
}
/**
* @method start
* @description Starts the operation
*/
function start () {
paused = false;
document.getElementById('mur-start').setAttribute('disabled', '');
document.getElementById('mur-pause').removeAttribute('disabled');
process();
}
/**
* @method process
* @description Analyzes the inputted data
*/
function process () {
if (paused) {
return;
}
var txt = document.getElementById("text-mass-user-rights");
var pages = txt.value.split('\n');
var currentUser = pages[0];
if (!currentUser) {
pause();
$('#text-error-output').append(
i18n.msg('finished').escape() +
' ' +
i18n.msg('done').escape() +
'<br/>'
);
}
else {
changeRights(currentUser);
}
pages = pages.slice(1,pages.length);
txt.value = pages.join('\n');
}
/**
* @method addGroupContents
* @description Inputs users from a certain usergroup
*/
function addGroupContents () {
var group = prompt(i18n.msg('groupPrompt').plain());
if (!group) {
return;
}
Api.get({
action: 'query',
list: 'allusers|groupmembers',
augroup: group,
aulimit: 'max',
gmgroups: group,
gmlimit: 'max',
format: 'json'
})
.done(function(d) {
if (!d.error) {
(d.users || d.query.allusers).forEach(function(user) {
$('#text-mass-user-rights').val($('#text-mass-user-rights').val() + user.name + '\n');
});
}
else {
sendError(i18n.msg('groupError').escape() + ' ' + group +' : '+ d.error.code);
}
})
.fail(function() {
sendError(i18n.msg('groupError').escape() + ' ' + group +'!');
});
}
/**
* @method changeRights
* @description Performs the action
* @param {String} user - The user whose rights are being changed
*/
function changeRights (user) {
Api.get({
action: 'query',
list: 'users',
ustoken: 'userrights',
ususers: user,
meta: 'tokens',
type: 'userrights'
}).done(function(d) {
if (!d.error) {
var params = {
action: 'userrights',
user: user,
reason: $('#user-rights-reason').val(),
bot: true,
token: d.query.tokens ?
d.query.tokens.userrightstoken :
d.query.users[0].userrightstoken
};
params[Number($('#user-rights-mode').val()) === 1 ? 'remove' : 'add'] = $('#user-rights-type').val();
Api.post(params).done(function(d2) {
if (!d2.error) {
console.log(i18n.msg('success', user).plain());
}
else {
sendError(i18n.msg('fail1', user, d2.error.code).escape());
}
})
.fail(function(code) {
sendError(i18n.msg('fail1', user, code).escape());
});
}
else {
sendError(i18n.msg('fail3', user, d.error.code).escape());
}
});
setTimeout(process, window.massUserRightsDelay || 1000);
}
/**
* @method sendError
* @description Handles error notices
* @param {String} error - The error to input
*/
function sendError (error) {
console.log(error);
$('#text-error-output').append(error + '<br/>');
}
mw.hook('dev.i18n').add(preload);
mw.hook('dev.modal').add(preload);
mw.hook('dev.placement').add(preload);
importArticles({
type: 'script',
articles: [
'u:dev:MediaWiki:I18n-js/code.js',
'u:dev:MediaWiki:Modal.js',
'u:dev:MediaWiki:Placement.js'
]
});
importArticle({
type: 'style',
articles: ['u:dev:MediaWiki:MassUserRights.css']
});
});
});