Участница:Megitsune-chan/FastClose.js

/**
 * 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>
Prefix: a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9

Portal di Ensiklopedia Dunia

Kembali kehalaman sebelumnya