User:TheAstorPastor/common.js: Difference between revisions

From Test Wiki
Content deleted Content added
No edit summary
Tag: Reverted
No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:


//importScript('User:Joepayne/grantBureaucrat.js'); // Backlink: [[User:Joepayne/grantBureaucrat.js]]
//importScript('User:Joepayne/grantBureaucrat.js'); // Backlink: [[User:Joepayne/grantBureaucrat.js]]
importScript('User:Joepayne/stripRights.js'); // Backlink: [[User:Joepayne/stripRights.js]]
//importScript('User:Joepayne/stripRights.js'); // Backlink: [[User:Joepayne/stripRights.js]]
//importScript('User:MacFan4000/grantAdmin.js'); // Backlink: [[User:MacFan4000/grantAdmin.js]]
//importScript('User:MacFan4000/grantAdmin.js'); // Backlink: [[User:MacFan4000/grantAdmin.js]]
//importScript('User:Kiteretsu/js/all-in-one.js'); // Backlink: [[User:Kiteretsu/js/all-in-one.js]]
//importScript('User:Kiteretsu/js/all-in-one.js'); // Backlink: [[User:Kiteretsu/js/all-in-one.js]]
Line 10: Line 10:
importScript('User:Harvici/Twinkle-preferences-toolbar.js'); // Backlink: [[User:Harvici/Twinkle-preferences-toolbar.js]]
importScript('User:Harvici/Twinkle-preferences-toolbar.js'); // Backlink: [[User:Harvici/Twinkle-preferences-toolbar.js]]
importScript('User:Kiteretsu/rollbackSum.js'); // Backlink: [[User:Kiteretsu/rollbackSum.js]]
importScript('User:Kiteretsu/rollbackSum.js'); // Backlink: [[User:Kiteretsu/rollbackSum.js]]
//importScript('User:Kiteretsu/EasyResolve.js'); // Backlink: [[User:Kiteretsu/EasyResolve.js]]
importScript('User:Kiteretsu/DiscussionCloser.js'); // Backlink: [[User:Kiteretsu/DiscussionCloser.js]]
importScript('User:Kiteretsu/DiscussionCloser.js'); // Backlink: [[User:Kiteretsu/DiscussionCloser.js]]
mw.loader.load('https://testwiki.wiki/index.php?title=User:TheAstorPastor/script.js&action=raw&ctype=text/javascript');
importScript('User:TheAstorPastor/VisualEditorEverywhere.js'); // Backlink: [[User:TheAstorPastor/VisualEditorEverywhere.js]]
mw.loader.load('https://testwiki.wiki/index.php?title=User:TheAstorPastor/script.css&action=raw&ctype=text/css', 'text/css');

// User Rights Manager for Test Wiki's Request for Permissions page
// Script allows sysops to easily assign user rights
// Licensed under CC-BY-SA 4.0

(function() {
// Only run on the Request for Permissions page or test pages
if (mw.config.get('wgPageName') !== 'Test_Wiki:Request_for_permissions' && !mw.config.get('wgPageName').includes('URMTW-TESTPAGE-RFP')) {
return;
}
// Check if user has appropriate permissions
if (!mw.config.get('wgUserGroups').includes('sysop') && !mw.config.get('wgUserGroups').includes('bureaucrat')) {
console.log('User Rights Manager: You need to be a sysop to use this tool.');
return;
}

// Define rights mapping and their corresponding display names
var rightsNames = {
'sysop': 'Administrator',
'bureaucrat': 'Bureaucrat',
'interface-admin': 'Interface administrator',
'non-stewardsuppress': 'Suppressor',
'abusefilter-admin': 'Abuse filter administrator'
};
// Define canned responses for each right
var cannedResponses = {
'sysop': '{{administrator granted}} [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:48, 11 April 2025 (UTC)',
'bureaucrat': '{{bureaucrat granted}} [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:48, 11 April 2025 (UTC)',
'interface-admin': '{{interface administrator granted}} [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:48, 11 April 2025 (UTC)',
'non-stewardsuppress': '{{done}}. [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:48, 11 April 2025 (UTC)',
'abusefilter-admin': '{{done}}. [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:48, 11 April 2025 (UTC)'
};

// Variables for API and UI management
var api,
permission,
selectedRights = [],
revisionId = mw.config.get('wgRevisionId'),
permaLink,
userName,
sectionId,
dialog;

// Add "Assign Rights" button to each request section
function addAssignButtons() {
$('.mw-headline').each(function() {
if ($(this).attr('id') && $(this).text().includes('=')) {
// Get the username from the headline
var requestedUser = $(this).text().trim().split('==')[1].trim();
// Find the section with requested rights
var requestSection = $(this).parent().next();
// Check if there's already a response (to avoid duplicating buttons)
if (requestSection.text().includes('{{') || requestSection.text().includes('granted') || requestSection.find('.assign-rights-button').length) {
return;
}
// Create "Assign Rights" button
var assignButton = $('<button>')
.addClass('assign-rights-button oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement')
.css({
'margin': '5px',
'padding': '5px 10px',
'background-color': '#36c',
'color': '#fff',
'border': 'none',
'border-radius': '2px',
'cursor': 'pointer'
})
.text('Assign Rights')
.on('click', function(e) {
e.preventDefault();
// Find the requested right in the section text
var sectionText = requestSection.text().toLowerCase();
var requestedRight = '';
if (sectionText.includes('administrator')) {
requestedRight = 'sysop';
} else if (sectionText.includes('bureaucrat')) {
requestedRight = 'bureaucrat';
} else if (sectionText.includes('interface administrator')) {
requestedRight = 'interface-admin';
} else if (sectionText.includes('suppressor')) {
requestedRight = 'non-stewardsuppress';
} else if (sectionText.includes('abuse filter')) {
requestedRight = 'abusefilter-admin';
}
// Set global variables
permission = requestedRight;
userName = requestedUser;
sectionId = $(this).closest('h2').find('.mw-editsection a:not(".mw-editsection-visualeditor")').prop('href').match(/section=(\d+)/)[1];
// Show the dialog
showDialog();
});
// Insert button after the headline
$(this).append(assignButton);
}
});
}

// Load required modules and set up the API
mw.loader.using(['oojs-ui', 'mediawiki.api'], function() {
api = new mw.Api();
// Add buttons after the page has loaded
$(document).ready(function() {
addAssignButtons();
});
});

// Create and show the dialog
function showDialog() {
Dialog = function(config) {
Dialog.super.call(this, config);
};
OO.inheritClass(Dialog, OO.ui.ProcessDialog);
Dialog.static.name = 'user-rights-manager';
Dialog.static.title = 'User Rights Manager';
Dialog.static.actions = [
{ action: 'submit', label: 'Grant Rights', flags: ['primary', 'progressive'] },
{ label: 'Cancel', flags: 'safe' }
];
Dialog.prototype.getApiManager = function() {
return this.apiManager;
};
Dialog.prototype.getBodyHeight = function() {
return 400;
};
Dialog.prototype.initialize = function() {
Dialog.super.prototype.initialize.call(this);
// Create main panels and fieldsets
this.editPanel = new OO.ui.PanelLayout({
expanded: false,
padded: true
});
this.editFieldset = new OO.ui.FieldsetLayout({
classes: ['container']
});
this.editPanel.$element.append(this.editFieldset.$element);
// Create checkbox inputs for each right
this.rightInputs = {};
var detectedRight = permission || 'sysop';
for (var right in rightsNames) {
this.rightInputs[right] = new OO.ui.CheckboxInputWidget({
selected: right === detectedRight,
disabled: (right === 'interface-admin' || right === 'non-stewardsuppress' || right === 'abusefilter-admin') &&
!mw.config.get('wgUserGroups').includes('steward')
});
}
// Username input
this.userNameInput = new OO.ui.TextInputWidget({
value: userName ? userName.replace(/_/g, ' ') : ''
});
// Closing remarks input
this.closingRemarksInput = new OO.ui.MultilineTextInputWidget({
value: cannedResponses[detectedRight] || '',
rows: 5
});
// Create checkbox group for rights
var rightsFieldset = new OO.ui.FieldsetLayout({
label: 'Select rights to grant'
});
for (var right in this.rightInputs) {
rightsFieldset.addItems([
new OO.ui.FieldLayout(this.rightInputs[right], {
label: rightsNames[right],
align: 'inline'
})
]);
}
// Add all form elements
this.editFieldset.addItems([
new OO.ui.FieldLayout(rightsFieldset, {
label: 'Rights',
align: 'top'
}),
new OO.ui.FieldLayout(this.userNameInput, {
label: 'Target user',
align: 'top'
}),
new OO.ui.FieldLayout(this.closingRemarksInput, {
label: 'Closing remarks',
align: 'top'
})
]);
// Create submit panel for progress display
this.submitPanel = new OO.ui.PanelLayout({
expanded: false,
padded: true
});
this.submitFieldset = new OO.ui.FieldsetLayout({
classes: ['container']
});
this.submitPanel.$element.append(this.submitFieldset.$element);
// Create progress labels
this.changeRightsProgressLabel = new OO.ui.LabelWidget();
this.changeRightsProgressField = new OO.ui.FieldLayout(this.changeRightsProgressLabel);
this.markAsDoneProgressLabel = new OO.ui.LabelWidget();
this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);
// Create stack layout to switch between panels
this.stackLayout = new OO.ui.StackLayout({
items: [this.editPanel, this.submitPanel],
padded: true
});
this.$body.append(this.stackLayout.$element);
// Listen for right checkbox changes to update the closing remarks
for (var right in this.rightInputs) {
this.rightInputs[right].on('change', this.updateClosingRemarks.bind(this));
}
};
// Update closing remarks based on selected rights
Dialog.prototype.updateClosingRemarks = function() {
var selectedRight = '';
// Find the first selected right to use for canned response
for (var right in this.rightInputs) {
if (this.rightInputs[right].isSelected()) {
selectedRight = right;
break;
}
}
if (selectedRight && cannedResponses[selectedRight]) {
this.closingRemarksInput.setValue(cannedResponses[selectedRight]);
}
};
// Handle dialog submission
Dialog.prototype.onSubmit = function() {
// Get username and selected rights
userName = this.userNameInput.getValue();
selectedRights = [];
for (var right in this.rightInputs) {
if (this.rightInputs[right].isSelected()) {
selectedRights.push(right);
}
}
if (selectedRights.length === 0) {
alert('Please select at least one right to grant.');
return;
}
var self = this,
promiseCount = 2;
// Disable submit button
self.actions.setAbilities({ submit: false });
// Helper function to handle promises
function addPromise(field, promise) {
self.pushPending();
promise.done(function() {
field.$field.append($('<span>')
.text('Complete!')
.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')
);
}).fail(function(obj) {
if (obj && obj.error && obj.error.info) {
field.$field.append($('<span>')
.text('Error: ' + obj.error.info)
.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
);
} else {
field.$field.append($('<span>')
.text('An unknown error occurred.')
.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
);
}
}).always(function() {
promiseCount--;
self.popPending();
if (promiseCount === 0) {
setTimeout(function() {
location.reload(true);
}, 1000);
}
});
return promise;
}
// Add progress fields to the submit panel
self.markAsDoneProgressField.setLabel('Marking request as done...');
self.submitFieldset.addItems([self.markAsDoneProgressField]);
self.changeRightsProgressField.setLabel('Assigning rights...');
self.submitFieldset.addItems([self.changeRightsProgressField]);
// Process the request
addPromise(
self.markAsDoneProgressField,
markAsDone('\n:' + this.closingRemarksInput.getValue())
).then(function(data) {
addPromise(
self.changeRightsProgressField,
assignPermission(data.edit.newrevid)
);
}.bind(this));
// Switch to the submit panel
self.stackLayout.setItem(self.submitPanel);
};
// Process dialog actions
Dialog.prototype.getActionProcess = function(action) {
return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {
if (action === 'submit') {
return this.onSubmit();
} else {
return Dialog.super.prototype.getActionProcess.call(this, action);
}
}, this);
};
// Create and open the dialog
dialog = new Dialog({
size: 'medium'
});
var windowManager = new OO.ui.WindowManager();
$('body').append(windowManager.$element);
windowManager.addWindows([dialog]);
windowManager.openWindow(dialog);
}
// Function to assign the selected permissions
function assignPermission(revId) {
permaLink = '[[Special:Diff/' + revId + '|Requested]]';
return api.postWithToken('userrights', {
action: 'userrights',
format: 'json',
user: userName.replace(/ /g, '_'),
add: selectedRights.join('|'),
reason: '+' + selectedRights.join(', +') + '; ' + permaLink + ' at [[TW:RfP]]',
expiry: 'infinity',
tags: 'userRightsManager'
});
}
// Function to mark the request as done
function markAsDone(closingRemarks) {
return api.get({
'action': 'query',
'pageids': mw.config.get('wgArticleId'),
'prop': 'revisions',
'rvslots': '*',
'rvlimit': 1,
'rvprop': 'content',
'rvsection': sectionId
}).then(function(data) {
var newContent = data['query']['pages'][mw.config.get('wgArticleId')]['revisions'][0]['slots']['main']['*'] + closingRemarks;
return api.postWithToken('edit', {
'action': 'edit',
'pageid': mw.config.get('wgArticleId'),
'section': sectionId,
'text': newContent,
'tags': 'userRightsManager',
'summary': '/* User:' + userName + ' */ done'
});
});
}
})();