User:NguoiDungKhongDinhDanh/WarningDialog.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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * WarningDialog is a script that helps adding warning templates.
 * Note that this only works in User/User talk namespaces and
 * Special:Contributions.
 * 
 * See also: [[User:NguoiDungKhongDinhDanh/RfDHelper.js]]
 * 
 * For attribution: [[User:1234qwer1234qwer4/warnings.js]] 
**/
// <nowiki>

$(function() {
	if ((![2, 3].includes(mw.config.get('wgNamespaceNumber')) &&
		mw.config.get('wgCanonicalSpecialPageName') !== 'Contributions') ||
		!mw.config.get('wgRelevantUserName') ||
		mw.config.get('wgRelevantUserName') === mw.config.get('wgUserName') || // [[Special:Diff/23314073]]
		(new mw.Uri()).query.noWD
	) {
		return;
	}
		
	mw.util.addPortletLink('p-cactions', '', 'Warn', 'ca-warningdialog', 'Initialize WarningDialog');
	
	$('#ca-warningdialog').click(function(e) {
		e.preventDefault();
		if ($('#warningdialog').length) {
			$('#warningdialog').dialog('open');
			return;
		}
		
		var api = new mw.Api();
		
		var u = mw.config.get('wgRelevantUserName');
		var ad = ' ([[User:NguoiDungKhongDinhDanh/WarningDialog.js|WD]])';
		var type = [
			{
				h: '',
				t: 'welcome',
				s: 'Welcome to Meta-Wiki!',
				l: 'Welcome',
				c: true,
				i: true
			},
			{
				l: 'Report user',
				c: true,
				n: 'report',
				p: function() {
					$('#warningdialog-report').parents('li').append(
						$('<div>').attr({
							class: 'warningdialog-fieldset',
							id: 'warningdialog-fieldset-report'
						}).css({
							'display': 'flex',
							'flex-direction': 'column-reverse',
							'justify-content': 'space-between'
						}).append(
							$('<input>').attr({
								type: 'text',
								placeholder: 'Reason here...',
								class: 'warningdialog-input',
								id: 'warningdialog-input-report'
							}).css({
								'flex-grow': 2,
								'margin': '0.2em',
								'padding': '0.2em'
							}),
							$('<select>').attr({
								class: 'warningdialog-select',
								id: 'warningdialog-select-report'
							}).css({
								'margin': '0.2em',
								'padding': '0.2em'
							}).append(
								$('<option>').attr('value', '').prop('selected', true).text('Blank'),
								$('<option>').attr('value', 'Long-term abuse.').text('Long-term abuse'),
								$('<option>').attr('value', 'Vandalism.').text('Vandalism'),
								$('<option>').attr('value', 'Disruptive editing.').text('Disruptive editing'),
								$('<option>').attr('value', 'Troll.').text('Troll'),
								$('<option>').attr('value', 'Spam / spambot.').text('Spam / spambot')
							)
						)
					);
					
					$('#warningdialog').on('change', '#warningdialog-report', function() {
						$('#warningdialog-fieldset-report').toggle($(this).prop('checked'));
					});
					$('#warningdialog-report').trigger('change');
					
					$('#warningdialog-select-report').on('change', function() {
						$('#warningdialog-input-report').val($(this).val());
					}).trigger('change');
				},
				u: true,
				f: function() {
					if (!$('#warningdialog-input-report').val().trim()) {
						$('#warningdialog-reportmessage').css({
							'color': '#D33',
							'font-weight': 'bold'
						}).text('No reason provided. Aborting.');
					}
					$('#warningdialog').append(
						$('<p>').attr('id', 'warningdialog-reportmessage').css({
							'padding': '1em',
							'font-size': '1.25em'
						}).text('Reporting user...')
					);
					api.get({
						action: 'parse',
						page: 'Meta:Requests for help from a sysop or bureaucrat',
						prop: ['sections'],
						format: 'json',
						formatversion: 2
					}).done(function(response) {
						var sections = response.parse.sections;
						for (let section of sections) {
							if (section.line.replace(/_/g, ' ').toLowerCase() === 'Report concerning ' + u) {
								$('#warningdialog-reportmessage').css({
									'color': '#D33',
									'font-weight': 'bold'
								}).text('User has already been reported.');
								return;
							}
						}
						api.postWithToken('csrf', {
							action: 'edit',
							title: 'Meta:Requests for help from a sysop or bureaucrat',
							section: 'new',
							sectiontitle: 'Report concerning [[Special:Contributions/' + u + '|' + u + ']]',
							appendtext: '* {{vandal|' + u + '}}\n' + $('#warningdialog-input-report').val().replace(/\s*~{4}$/, '') + ' ~~~~',
							summary: 'Reporting [[Special:Contributions/' + u + '|' + u + ']]' + ad,
							nocreate: true,
							format: 'json',
							formatversion: 2
						}).done(function(response) {
							$('#warningdialog-reportmessage').css({
								'color': '#006400',
								'font-weight': 'bold'
							}).text('Reported successfully.');
						}).fail(function(error, response) {
							$('#warningdialog-reportmessage').css({
								'color': '#D33',
								'font-weight': 'bold'
							}).text('Report failed. API error: ' + response.error.info);
						});
					}).fail(function(error, response) {
						$('#warningdialog-reportmessage').css({
							'color': '#D33',
							'font-weight': 'bold'
						}).text('API error: ' + response.error.info);
					});
				}
			},
			{
				h: 'No warnings',
				t: '',
				s: ''
			},
			{
				h: 'Editing tests',
				t: 'test1',
				s: 'Warning: Please use [[Meta:Sandbox|the sandbox]] for testing.'
			},
			{
				h: '',
				t: 'test2',
				s: 'Warning: Please use [[Meta:Sandbox|the sandbox]] for testing (level 2)',
				l: 'Editing tests (level 2)'
			},
			{
				h: '',
				t: 'test3',
				s: 'Warning: Please use [[Meta:Sandbox|the sandbox]] for testing (level 3)',
				l: 'Editing tests (level 3)'
			},
			{
				h: '',
				t: 'test4',
				s: 'Last warning: Please use [[Meta:Sandbox|the sandbox]] for testing',
				l: 'Editing tests (level 4)'
			},
			{
				h: 'Only warning',
				t: 'test4im',
				s: 'Only warning: Please use [[Meta:Sandbox|the sandbox]] for testing',
				l: 'Editing tests (level 4im)'
			},
			{
				h: 'Vandalism',
				t: 'bv',
				s: 'Warning: Blatant vandalism.'
			},
			{
				h: 'Spamming or promotion',
				t: 'spam',
				s: 'Warning: Spamming or promotional content.'
			},
			{
				h: 'Deleted user (sub)page',
				t: 'deleted userpage',
				s: 'Warning: Your user (sub)page has been or will soon be deleted.'
			},
			{
				h: 'Off-topic contributions',
				t: 'offtopic',
				s: 'Warning: Your page was outside of Meta\'s [[Meta:Inclusion policy|scope]].'
			},
			{
				h: 'Off-topic edits',
				t: 'offtopic-edits',
				s: 'Warning: Your edits were outside of Meta\'s [[Meta:Inclusion policy|scope]].'
			},
			{
				h: 'Recreating deleted content',
				t: 'norecreate',
				s: 'Warning: Do not recreate deleted content.'
			},
			{
				h: 'Personal attacks',
				t: 'attack',
				s: 'Warning: Do not make personal attacks.'
			}
			/* {
				h: 'Blocked',
				t: 'blocked|1=$1|2=$2|sig=~~~~',
				s: 'You have been blocked from editing Meta-Wiki.'
			} */
		];
		var getcontent = function(button) {
			var t = {};
			t.s = [];
			t.c = [];
			$('.warningdialog-checkbox').each(function() {
				if ($(this).prop('checked')) {
					var c = JSON.parse($(this).val());
					if (c.u) {
						for (let i of type) {
							if (i.l === c.l) {
								if (button !== 'preview') i.f();
							}
						}
					} else {
						t.c.push((c.h ? '== ' + c.h + ' ==\n' : '') + '{{subst:' + c.t + '}}\n' + (c.i ? '~~~~' : ''));
						t.s.push(c.s);
					}
				}
			});
			t.r = JSON.parse($('.warningdialog-radio:checked').val());
			if (t.r.h !== 'No warnings') {
				t.r = {
					c: (t.r.h ? '== ' + t.r.h + ' ==\n' : '') + '{{subst:' + t.r.t + '}}\n' + (t.r.i ? '~~~~' : ''),
					s: t.r.s
				};
			} else {
				t.r = '';
			}
			t.text = t.c.join('\n\n') + (t.c.join('') && t.r && t.r.c ? '\n\n' : '') + (t.r ? t.r.c : '');
			return t;
		};
		
		$('<div>').attr('id', 'warningdialog').append(function() {
			var l1 = $('<ul>').css({
				'flex-grow': 2,
				'flex-basis': '50%',
				'list-style-type': 'none',
				'list-style-image': 'none',
				'margin': '0.3em',
				'border': '1px solid #C8CCD1',
				'min-height': '7.5em',
				'overflow-y': 'auto',
				'padding': '1em',
				'font-size': '1.2em'
			});
			var l2 = l1.clone();
			
			for (let i of type) {
				(i.c ? l1 : l2).append(
					$('<li>').css({
						'display': 'flex',
						'flex-direction': 'column',
						'align-content': 'stretch'
					}).html(
						$('<label>').attr({
							class: 'warningdialog-label'
						}).append(
							i.c ?
								$('<input>')
								.attr({
									type: 'checkbox',
									value: JSON.stringify(i),
									class: 'warningdialog-checkbox',
									id: 'warningdialog-' + i.n
								})
							:
								$('<input>')
								.attr({
									type: 'radio',
									name: 'warningdialog-radio',
									value: JSON.stringify(i),
									class: 'warningdialog-radio',
									id: 'warningdialog-' + i.n
								})
						).append(
							$('<span>').attr({
								class: 'warningdialog-labelname',
								style: 'margin: 0 0.5em;'
							}).text(i.h || i.l)
						)
					)
				);
			}
			l2.find('.warningdialog-radio').first().prop('checked', true);
			return $('<div>').css({
				'display': 'flex'
			}).append(l1, l2);
		}).append(
			$('<div>').attr('id', 'warningdialog-preview').css({
				'display': 'none',
				'margin': '0.3em',
				'border': '1px solid #C8CCD1',
				'max-height': '30em',
				'overflow-y': 'auto',
				'padding': '1em'
			})
		).appendTo('body');
		
		type.forEach(function(i) {
			if (i.p) i.p();
		});
		
		$('#warningdialog').dialog({
			autoOpen: true,
			width: '60%',
			title: 'Warning user: ' + u,
			buttons: [
				{
					text: 'Preview',
					click: function() {
						if (!$('#warningdialog-preview').is(':visible')) {
							$('#warningdialog-preview').show();
						}
						$('#warningdialog-preview').html(
							$('<p>').css({
								'padding': '1em',
								'font-size': '1.25em'
							}).text('Loading...')
						);
						
						var t = getcontent('preview');
						var text = t.text;
						
						api.get({
							action: 'parse',
							title: 'User talk:' + u,
							text: text,
							prop: ['text'],
							pst: true,
							disablelimitreport: true,
							disableeditsection: true,
							sectionpreview: true,
							disabletoc: true,
							useskin: mw.config.get('skin'),
							contentmodel: 'wikitext',
							format: 'json',
							formatversion: 2
						}).done(function(response) {
							$('#warningdialog-preview').html(response.parse.text);
						}).fail(function(error, response) {
							console.warn(error, response);
							$('#warningdialog-preview').html(response.error.info);
						});
					}
				},
				{
					text: 'Submit',
					click: function() {
						$(this).parent().find('button').button('disable');
						$('#warningdialog').children().hide();
						
						var t = getcontent('submit');
						var text = t.text;
						if (!text.trim()) return;
						
						$('#warningdialog').append(
							$('<p>').attr('id', 'warningdialog-main').css({
								'padding': '1em',
								'font-size': '1.25em'
							}).text('Submitting edit...')
						);
						
						api.get({
							action: 'query',
							titles: ['User talk:' + u],
							prop: ['revisions'],
							rvprop: ['content'],
							rvslots: '*',
							rvlimit: 1,
							format: 'json',
							formatversion: 2
						}).done(function(res) {
							var m = res.query.pages[0].missing || (res.query.pages[0].revisions[0].slots.main.content.trim() === '');
							text = (m ? '' : '\n\n') + text;
							
							api.postWithToken('csrf', {
								action: 'edit',
								title: 'User talk:' + u,
								watchlist: window.WDwatchlist || 'preferences',
								appendtext: text,
								summary: (t.r.s || t.s[0]) + ad,
								format: 'json',
								formatversion: 2
							}).done(function(response) {
								$('#warningdialog-main').css({
									'color': '#006400',
									'font-weight': 'bold'
								}).text('Changes made successfully.');
							}).fail(function(error, response) {
								$('#warningdialog-main').css({
									'color': '#D33',
									'font-weight': 'bold'
								}).text('Failed to submit. API error: ' + response.error.info);
							});
						}).fail(function(error, response) {
							$('#warningdialog-main').css({
								'color': '#D33',
								'font-weight': 'bold'
							}).text('API error: ' + response.error.info);
						});
					}
				}
			]
		});
		
		$('#warningdialog-preview').click(function() {
			$(this).toggle();
		});
	});
});

// </nowiki>