Thành viên:NguoiDungKhongDinhDanh/AfDCloser.js

Bách khoa toàn thư mở Wikipedia

Chú ý: Sau khi lưu thay đổi trang, bạn phải xóa bộ nhớ đệm của trình duyệt để nhìn thấy các thay đổi. Google Chrome, Firefox, Internet ExplorerSafari: Giữ phím ⇧ Shift và nhấn nút Reload/Tải lại trên thanh công cụ của trình duyệt. Để biết chi tiết và hướng dẫn cho các trình duyệt khác, xem Trợ giúp:Xóa bộ nhớ đệm.

/** <nowiki>
 * Công cụ hỗ trợ đóng biểu quyết xoá bài.
 * Cài đặt: Thêm dòng dưới đây vào trang common.js của bạn:
 * mw.loader.load('/wiki/User:NguoiDungKhongDinhDanh/AfDCloser.js?action=raw&ctype=text/javascript');
 * 
 * Inspired by [[:en:WP:XFDCLOSER]]
 * 
 * Danh sách người sử dụng: //w.wiki/4rYP
 * Giấy phép: CC BY-SA 3.0
**/
/* jshint esversion: 6, maxerr: 9999, undef: true, unused: true, quotmark: single */
/* globals window, document, $, mw */
 
mw.loader.using(['mediawiki.util'], function() {
	var database = mw.config.get('wgDBname');
	var [pageName, afdPageName, articleName] = (
		mw.config.get('wgPageName').replace(/_/g, ' ').match(
			/^[^\/]+\/((.+?)(?: \(lần \d+\))?)$/
		) || []
	);
	
	if (database !== 'viwiki' || !articleName) {
		return;
	}
	
	var api = new mw.Api();
	var ad = '([[User:NguoiDungKhongDinhDanh/AfDCloser.js|AfDCloser]])';
	var groups = new Set(mw.config.get('wgUserGroups'));
	var isAdmin = groups.has('eliminator') || groups.has('sysop');
	
	var aliasesRegex = [
		'Độ nổi bật', 'Không nổi bật',
		'Chưa xứng đáng', 'Bàn cãi về giá trị',
		'Tiêu chuẩn', 'Tiêu chuẩn đưa vào',
		'Tiêu chuẩn tổ chức', 'Tiêu chuẩn nhân vật',
		'Notability', 'Dnb', 'Knb'
	].map(e => `[${e[0]}${e[0].toLowerCase()}]${e.slice(1).replace(/ /g, '[_ ]+')}`).join('|');
	
	function notify(content, title, type, tag) {
		mw.notify(content, {
			type, title,
			tag: `afdcloser-${tag || 'main'}`,
			autoHide: true,
			autoHideSeconds: 5
		});
	}
	function applyRegex(text, keep) {
		return text.replace(
			/^\{\{[Aa]fd\/dated\|[^{}]+\}\}$/m, ''
		).replace(
			new RegExp(String.raw`\{\{\s*(?:${aliasesRegex})\s*(?:[^{}]+)?\}\}`),
			s => keep ? '' : s
		).trim();
	}
	function onfail(error, response) {
		notify(`Nội dung lỗi: ${response.error.info}`, `Lỗi: ${error}`, 'error', 'error');
		throw Error('Có lỗi.');
	}
	
	function dialog() {
		$(this).remove();
		
		var css = (`
			#afdcloser {
				display: flex;
				flex-direction: column;
				font-size: 1.25em;
			}
			.afdcloser-fieldset {
				display: flex;
				flex-direction: column;
			}
			.afdcloser-fieldset > * {
				margin: 0.75em 0.3em 0;
			}
			.afdcloser-labels {
				display: block;
				font-size: 1.25em;
			}
			#afdcloser-result {
				display: flex;
				justify-content: space-between;
				flex-wrap: wrap;
			}
			#afdcloser-result label {
				display: inline-flex;
				flex: 2 1 calc((100% - 30px) / 3);
				padding: 3px 5px;
			}
			#afdcloser-result input {
				margin: 0;
				align-self: center;
			}
			#afdcloser-result span {
				margin-left: 10px;
				align-self: center;
				font-size: 0.75em;
			}
			#afdcloser-note {
				flex-grow: 2;
				padding: 0.5em;
				-webkit-transition: border-color 100ms, box-shadow 100ms;
				transition: border-color 100ms, box-shadow 100ms;
			}
			#afdcloser-note:focus,
			#afdcloser-note:active {
				outline: 0;
				border-color: #3366CC;
				box-shadow: inset 0 0 0 1px #3366CC;
			}
		`); // :focus/:active copied from OO.UI core.
		try {
			mw.util.addCSS(css);
		} catch (ignore) {
			mw.loader.addStyleTag(css);
		}
		
		$('<div>').attr('id', 'afdcloser').append(
			$('<div>').attr('class', 'afdcloser-fieldset').append(
				$('<label>').attr({
					'for': 'afdcloser-result',
					'class': 'afdcloser-labels'
				}).text('Kết quả:'),
				$('<div>').attr('id', 'afdcloser-result').append(
					$('<label>').attr('class', 'afdcloser-labels').append(
						$('<input>').attr({
							'type': 'radio',
							'name': 'afdcloser-result',
							'value': 1,
							'class': 'afdcloser-result'
						}),
						$('<span>').text('Xoá')
					),
					$('<label>').attr('class', 'afdcloser-labels').append(
						$('<input>').attr({
							'type': 'radio',
							'name': 'afdcloser-result',
							'value': -1,
							'class': 'afdcloser-result'
						}),
						$('<span>').text('Giữ')
					),
					$('<label>').attr('class', 'afdcloser-labels').append(
						$('<input>').attr({
							'type': 'radio',
							'name': 'afdcloser-result',
							'value': 0,
							'class': 'afdcloser-result'
						}).prop('checked', true),
						$('<span>').text('Không đủ phiếu')
					),
					$('<label>').attr('class', 'afdcloser-labels').append(
						$('<input>').attr({
							'type': 'checkbox',
							'id': 'afdcloser-close'
						}).prop({
							'checked': !isAdmin,
							'disabled': !isAdmin
						}),
						$('<span>').text('Đóng thảo luận')
					)
				)
			),
			$('<div>').attr('class', 'afdcloser-fieldset').append(
				$('<label>').attr({
					'for': 'afdcloser-note',
					'class': 'afdcloser-labels'
				}).text('Ghi chú (tuỳ chọn):'),
				$('<input>').attr({
					'type': 'text',
					'autocomplete': 'off',
					'id': 'afdcloser-note'
				})
			)
		).appendTo(document.body);
		
		$('#afdcloser').dialog({
			autoOpen: true,
			width: 500,
			minWidth: 500,
			height: 400,
			minHeight: 400,
			title: 'AfDCloser.js',
			buttons: [
				{
					text: 'Thực hiện',
					click: function() {
						$('#afdcloser').dialog('destroy').css('display', 'none');
						
						var result = +$('.afdcloser-result:checked').val();
						var note = $('#afdcloser-note').val().trim();
						var close = $('#afdcloser-close').prop('checked');
						
						if (close !== false) {
							closeAfd(note);
						}
						
						switch (result) {
							case -1:
								addTag(); // jshint ignore: line
							case 0:
								removeTag(result);
								break;
							case 1:
								(isAdmin ? deletePage : requestDeletion)();
								break;
						}
					}
				}
			]
		});
	}
	
	function closeAfd(note) {
		api.get({
			action: 'query',
			prop: ['revisions'],
			titles: [pageName],
			rvslots: ['main'],
			rvprop: ['content'],
			format: 'json',
			formatversion: 2
		}).done(function(response) {
			var text = response.query.pages[0].revisions[0].slots.main.content.replace(
				/^{{REMOVE THIS TEMPLATE WHEN CLOSING THIS AfD\|[^{}]+}}$/m,
				`{{đầu biểu quyết|KQ = ${note}${note ? '. ' : note.slice(-1) === '.' ? ' ' : ''}~~~~}}`
			) + '\n{{kết biểu quyết}}';
			
			api.postWithToken('csrf', {
				action: 'edit',
				title: pageName,
				text: text,
				summary: `Đóng biểu quyết xoá bài ${ad}`,
				format: 'json',
				formatversion: 2
			}).done(function() {
				notify('Đã đóng biểu quyết xoá bài.', 'Đã đóng biểu quyết!', 'success', 'close');
			}).fail(onfail);
		}).fail(onfail);
	}
	
	function removeTag(keep) {
		api.get({
			action: 'query',
			prop: ['revisions'],
			titles: [articleName],
			rvslots: ['main'],
			rvprop: 'content',
			format: 'json',
			formatversion: 2
		}).done(function(response) {
			var text = applyRegex(response.query.pages[0].revisions[0].slots.main.content, keep);
			
			api.postWithToken('csrf', {
				action: 'edit',
				title: articleName,
				text: text,
				summary: `Gỡ bản mẫu theo kết quả [[${pageName}|biểu quyết]] ${ad}`,
				format: 'json',
				formatversion: 2
			}).done(function() {
				notify('Đã gỡ bản mẫu biểu quyết xoá trang.',  'Đã gỡ bản mẫu!', 'success', 'remove');
			}).fail(onfail);
		});
	}
	function addTag() {
		api.postWithToken('csrf', {
			action: 'edit',
			title: (new mw.Title(articleName)).getTalkPage().toText(),
			prependtext: `{{đã biểu quyết giữ|1=${pageName}}}\n`,
			summary: `Thêm bản mẫu theo kết quả [[${pageName}|biểu quyết]] ${ad}`,
			format: 'json',
			formatversion: 2
		}).done(function() {
			notify('Đã gán nhãn trang thảo luận.',  'Đã gán nhãn!', 'success', 'add');
		}).fail(onfail);
	}
	
	function requestDeletion() {
		api.postWithToken('csrf', {
			action: 'edit',
			title: articleName,
			prependtext: `{{db-xfd|votepage=${afdPageName}}}\n`,
			summary: `Yêu cầu xoá trang theo kết quả [[${pageName}|biểu quyết]] ${ad}`,
			format: 'json',
			formatversion: 2
		}).done(function() {
			notify(`Đã yêu cầu xoá ${articleName}.`,  'Đã yêu cầu xoá!', 'success', 'request');
		}).fail(onfail);
	}
	
	function deletePage() {
		api.postWithToken('csrf', {
			action: 'delete',
			title: articleName,
			reason: `[[WP:BQXB|BQXB]]: Xoá theo kết quả [[${pageName}|biểu quyết xoá bài]] ${ad}`,
			deletetalk: true,
			format: 'json',
			formatversion: 2
		}).done(function() {
			notify(`Đã xoá ${articleName}.`, 'Đã xoá!', 'success', 'delete');
		}).fail(onfail);
	}
	
	$(function() {
		mw.util.addPortletLink(
			'p-tb', 'javascript:void(0)', 'AfDCloser', 'ca-afdcloser',
			'Hỗ trợ đóng biểu quyết xoá bài'
		);
		
		$('#ca-afdcloser').click(dialog);
	});
});

// </nowiki>