User:DreamRimmer/SBRequest.js
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.
// <nowiki>
mw.loader.using(['mediawiki.api', 'mediawiki.util', 'oojs-ui'], function () {
'use strict';
const page = mw.config.get('wgPageName');
const api = new mw.Api();
let token = null;
async function getToken() {
try {
const res = await api.get({
action: 'query',
meta: 'tokens',
type: 'csrf'
});
token = res.query.tokens.csrftoken;
} catch (e) {
console.error('Error getting token:', e);
throw e;
}
}
function ItemInputWidget() {
OO.ui.Widget.call(this);
this.textInput = new OO.ui.TextInputWidget({
placeholder: 'Enter item',
required: true,
rows: 1
});
this.dropdown = new OO.ui.DropdownInputWidget({
options: [
{ data: 'link', label: 'URL' },
{ data: 'ip', label: 'IP' },
{ data: 'user', label: 'User' }
],
value: 'link'
});
this.textInput.$element.css('width', '67%');
this.dropdown.$element.css('width', '30%');
this.layout = new OO.ui.HorizontalLayout({
items: [ this.textInput, this.dropdown ]
});
this.$element.addClass('itemInputWidget').css('margin-bottom', '5px');
this.$element.append(this.layout.$element);
}
OO.inheritClass(ItemInputWidget, OO.ui.Widget);
function createItemField() {
return new ItemInputWidget();
}
function RequestDialog(config) {
RequestDialog.super.call(this, config);
}
OO.inheritClass(RequestDialog, OO.ui.ProcessDialog);
RequestDialog.static.name = 'requestDialog';
RequestDialog.static.title = 'SBRequest';
RequestDialog.static.actions = [
{ action: 'accept', label: 'Submit', flags: ['primary', 'progressive'] },
{ action: 'cancel', label: 'Cancel', flags: 'safe' }
];
RequestDialog.prototype.initialize = function () {
RequestDialog.super.prototype.initialize.apply(this, arguments);
this.itemContainer = new OO.ui.FieldsetLayout({
label: 'Blacklist items:'
});
this.itemContainer.addItems([ createItemField() ]);
this.reasonInput = new OO.ui.MultilineTextInputWidget({
placeholder: 'Reason for blacklist',
multiline: true,
required: true,
rows: 2
});
const addButton = new OO.ui.ButtonWidget({
label: '+',
flags: ['progressive']
});
addButton.on('click', () => {
this.itemContainer.addItems([ createItemField() ]);
this.updateSize();
});
this.content = new OO.ui.PanelLayout({ padded: true, expanded: false });
this.content.$element.append(
new OO.ui.FieldsetLayout({
items: [
this.itemContainer,
new OO.ui.FieldLayout(addButton),
new OO.ui.FieldLayout(this.reasonInput, { label: 'Reason:', align: 'top' })
]
}).$element
);
this.$body.append(this.content.$element);
};
RequestDialog.prototype.getBodyHeight = function () {
return this.content.$element.outerHeight(true) + 20;
};
RequestDialog.prototype.getActionProcess = function (action) {
if (action === 'accept') {
return new OO.ui.Process(async () => {
const items = this.itemContainer.items.map(widget => {
return {
value: widget.textInput.getValue(),
type: widget.dropdown.getValue()
};
}).filter(item => item.value);
const reason = this.reasonInput.getValue();
if (items.length === 0) {
alert('Please enter at least one item to be blacklisted.');
return;
}
if (!reason) {
alert('Please enter a reason for the blacklist.');
return;
}
const signature = '~~~~';
let report;
if (items.length === 1) {
const item = items[0];
report = `=== ${item.value} ===\n* {{${item.type === 'link' ? 'LinkSummary' : item.type === 'ip' ? 'ipsummary' : 'usersummary'}|${item.value}}}\n${reason} ${signature}\n`;
} else {
report = `=== Bulk spam additions (${items[0].value} and more) ===\n`;
items.forEach(item => {
report += `* {{${item.type === 'link' ? 'LinkSummary' : item.type === 'ip' ? 'ipsummary' : 'usersummary'}|${item.value}}}\n`;
});
report += `${reason} ${signature}\n`;
}
const success = await appendReport(report);
if (success) {
alert('Request submitted successfully!');
location.reload();
this.close({ action: 'accept' });
}
});
} else if (action === 'cancel') {
return new OO.ui.Process(() => {
this.close({ action: 'cancel' });
});
}
};
async function appendReport(report) {
if (!token) await getToken();
const res = await api.get({
action: 'query',
prop: 'revisions',
titles: page,
rvprop: 'content',
format: 'json'
});
const pages = res.query.pages;
const data = pages[Object.keys(pages)[0]];
let content = data.revisions[0]['*'];
const headingRegex = /^==[^=]+==/gm;
const headings = [...content.matchAll(headingRegex)];
const proposedAdditionsIndex = headings.findIndex(h => /^==\s*proposed additions\s*==$/i.test(h[0]));
if (proposedAdditionsIndex === -1) {
alert('Could not find the "Proposed additions" section.');
return false;
}
const nextHeadingIndex = proposedAdditionsIndex + 1;
let insertPos;
if (nextHeadingIndex < headings.length) {
insertPos = headings[nextHeadingIndex].index;
} else {
insertPos = content.length;
}
const newContent = content.substring(0, insertPos) + report + '\n' + content.substring(insertPos);
await api.postWithToken('csrf', {
action: 'edit',
title: page,
text: newContent,
summary: 'Requesting additions (using [[User:DreamRimmer/SBRequest.js|SBRequest.js]])',
format: 'json'
});
return true;
}
async function init() {
if (page === 'Talk:Spam_blacklist') {
const button = document.createElement('button');
button.id = 'request-addition-button';
button.className = 'oo-ui-buttonElement oo-ui-buttonElement-progressive oo-ui-widget oo-ui-widget-enabled';
button.style = 'margin: 10px auto;background-color: rgb(51, 102, 204);color: white;border: 1px solid rgb(51, 102, 204);text-align: center;border-radius: 3px;font-size: 18px;padding: 8px 15px;display: block;font-weight: bold;cursor: pointer;';
button.textContent = 'Request addition';
document.querySelector('table[role="presentation"]').insertAdjacentElement('afterend', button);
button.addEventListener('click', function (e) {
e.preventDefault();
const windowManager = new OO.ui.WindowManager();
$(document.body).append(windowManager.$element);
const requestDialog = new RequestDialog({ size: 'medium' });
windowManager.addWindows([requestDialog]);
windowManager.openWindow(requestDialog);
});
}
}
init();
});
// </nowiki>