/**
* FastClose для русскоязычной Википедии
* Скрипт для удобного и быстрого закрытия запросов на странице [[ВП:ЗКАБ]]
* При применении скрипта обязательно проверяйте закрылся ли тот запрос, который вы хотели!!!
* Написан с использованием нейросети claude-3-5-sonnet-20241022
* Версия скрипта: 1.5
*/
// <nowiki>
$(function() {
// Проверяем, что мы на нужной странице
if (mw.config.get('wgPageName') !== 'Википедия:Запросы_к_администраторам/Быстрые') {
return;
}
// Константы для статусов
const CLOSE_STATUSES = {
done: '+',
rejected: '-'
};
let api;
// Добавляем кнопки закрытия
function addCloseButtons() {
$('span.mw-editsection').each(function() {
const $editSection = $(this);
// Проверяем, находится ли секция в преамбуле
// Преамбула содержит h2, а запросы - нет
const isInPreamble = $editSection.closest('.mw-heading-2').length > 0 ||
$editSection.parent().hasClass('mw-heading-2') ||
$editSection.parent().hasClass('vector-body-before-content');
if ($editSection.find('.quick-close-buttons').length > 0) {
return;
}
// Скрываем оригинальную ссылку "править" и квадратные скобки
$editSection.find('a').hide();
$editSection.find('.mw-editsection-bracket').hide();
// Создаём контейнер для кнопок
const $buttonContainer = $('<span>')
.addClass('quick-close-buttons')
.css({
'margin-left': '0.5em'
});
// Добавляем кнопки закрытия только если это не преамбула
if (!isInPreamble) {
const buttons = [
{text: 'выполнить', status: 'done', color: '#006400'},
{text: 'отклонить', status: 'rejected', color: '#8B0000'}
];
buttons.forEach(button => {
$buttonContainer.append(
$('<span>').text('['),
$('<span>')
.text(button.text)
.css({
'cursor': 'pointer',
'color': button.color
})
.attr('data-status', button.status)
.on('click', function(e) {
e.preventDefault();
handleRequestClose($(this), $editSection);
}),
$('<span>').text(']'),
$('<span>').text(' ')
);
});
}
// Добавляем кнопку "править"
$buttonContainer.append(
$('<span>').text('['),
$('<span>')
.text('править')
.css({
'cursor': 'pointer',
'color': '#36c'
})
.on('click', function() {
$editSection.find('a')[0].click();
}),
$('<span>').text(']')
);
$editSection.append($buttonContainer);
});
}
// Обработка закрытия запроса
function handleRequestClose($button, $editSection) {
const status = $button.attr('data-status');
var sectionTitle = (' "' + $editSection.closest('tr').find('.tmpl-raaf-request').text().trim().replace(/^Учётная запись:\s*/, '').replace(/\s*\(.*$/, '') + '"' || '');
console.log('sectionTitle:', sectionTitle);
const $dialog = $('<div>')
.attr('title', 'Закрытие запроса')
.append(
$('<p>').text('Закрыть запрос' + sectionTitle + ' как ' + ($button.attr('data-status') === 'done' ? 'выполненный' : 'отклонённый') + '?'),
$('<textarea>')
.attr('placeholder', 'Комментарий (не обязательно)')
.css({
'width': '100%',
'height': '60px',
'margin-top': '10px'
})
);
$dialog.dialog({
modal: true,
width: 400,
buttons: {
'Закрыть': function() {
const reason = $(this).find('textarea').val().trim() || ' ';
closeRequest($editSection, status, reason, $button);
$(this).dialog('close');
},
'Отмена': function() {
$(this).dialog('close');
}
}
});
}
// Функция закрытия запроса
function closeRequest($editSection, status, reason, $button) {
// Получаем номер секции из ссылки "править"
const editLink = $editSection.find('a').first().attr('href');
const sectionId = mw.util.getParamValue('section', editLink);
if (!sectionId) {
alert('Ошибка: не удалось определить номер секции');
return;
}
api = api || new mw.Api();
// Получаем текущий текст секции
api.get({
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'wikitext',
section: sectionId,
format: 'json'
}).then(function(data) {
if (!data.parse || !data.parse.wikitext['*']) {
throw new Error('Не удалось получить текст секции');
}
let content = data.parse.wikitext['*'];
console.log('Исходный текст:', content); // Отладочный вывод
// Разбиваем текст на строки
let lines = content.split('\n');
// Обрабатываем каждую строку
lines = lines.map(line => {
// Для параметра "статус"
if (line.match(/^\s*\|\s*статус\s*=/)) {
return line.replace(/^(\s*\|\s*статус\s*=\s*).*$/, '$1' + CLOSE_STATUSES[status] + '/' + reason);
}
// Для параметра "администратор"
if (line.match(/^\s*\|\s*администратор\s*=/)) {
return line.replace(/^(\s*\|\s*администратор\s*=\s*).*$/, '$1{{подст:зкаб|}}');
}
return line;
});
// Собираем текст обратно
content = lines.join('\n');
console.log('Измененный текст:', content); // Отладочный вывод
//Название секции запроса
var sectionTitle = ('' + $editSection.closest('tr').find('.tmpl-raaf-request').text().trim().replace(/^Учётная запись:\s*/, '').replace(/\s*\(.*$/, '') + '' || '');
// Сохраняем изменения
return api.edit(mw.config.get('wgPageName'), function() {
return {
text: content,
section: sectionId,
summary: `Закрыт запрос (` + sectionTitle + ` — ${(status === 'done' ? 'Выполнен' : 'Отклонён')}) скриптом [[Участница:Megitsune-chan/FastClose|FastClose.js]]`,
minor: true
};
});
}).then(function() {
location.reload();
}).catch(function(error) {
console.error('Ошибка при закрытии запроса:', error);
alert('Произошла ошибка при закрытии запроса: ' + error.message);
});
}
// Инициализация
mw.loader.using([
'mediawiki.api',
'mediawiki.util',
'jquery.ui',
], () => {
addCloseButtons();
// Обновление кнопок при динамической загрузке контента
mw.hook('wikipage.content').add(addCloseButtons);
});
});
// </nowiki>