User:Suffusion of Yellow/filterNotes.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*
 * filterNotes: Parses the "notes" section of edit filters, so links are
 * clickable. Also adds an "add note" button to insert a new note with your
 * username and timestamp.
 */
// <nowiki>
// jshint esnext: false, esversion: 8
(function() {
	/* globals $, mw, OO */
	'use strict';
	function addNote($notes, note) {
		let sig = window.filterSignature || "--" + mw.config.get('wgUserName');
		let now = new Date();

		const monthNamesShort =
			  [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
				"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
		let timestamp = ("0" + now.getUTCHours()).slice(-2) +
			":" + ("0" + now.getUTCMinutes()).slice(-2) +
			" " + now.getUTCDate() +
			" " + monthNamesShort[now.getUTCMonth()] +
			" " + now.getUTCFullYear();

		$notes.val($notes.val().replace(/\s+$/, '') +
				   "\n\n" + note.replace(/\s+$/, '') +
				   " " + sig + " " + timestamp);

		/* Scroll the added note into view */
		$notes[0].scrollTop = $notes[0].scrollHeight - $notes[0].clientHeight;
	}

	async function parseNotes(notes, $div) {
		$div.addClass("efb-parsednotes-working");

		/* Cleanup, no one expected this to be parsed */
		let fixed = notes.replace(/\r\n/g, '\n')
			.replace(/\n\n+/g, '<p>')
			.replace(/\n/g, '<br>')
			.replace(/\{\{/g, '{{tlx|');

		let response = await (new mw.Api()).post( {
			action: "parse",
			title: mw.config.get('wgPageName'),
			text: fixed,
			preview: true,
			pst: false,
			contentmodel: "wikitext"
		}).catch(() => null); /* Trigger exception in next try{} block */

		try {
			$div.html(response.parse.text["*"]);
			$div.removeClass("efb-parsednotes-working");
		} catch(e) {
			$div.text("Failed to parse notes. Use 'Edit notes' button to view");
		}

		/* For [[WP:POPUPS]], etc. */
		mw.hook('wikipage.content').fire($div);
	}

	function setup() {
		let $notesWidget = $("#mw-abusefilter-notes-editor");
		let $notes = $("textarea[name=wpFilterNotes]");

		if (!$notesWidget.length || !$notes.length)
			return;

		let canEdit = !$notes.prop("readOnly");

		mw.util.addCSS(".efb-parsednotes { font-color: black; background: #EEE; overflow: auto; border: 1px solid black; resize: both; }");
		mw.util.addCSS(".efb-parsednotes-working { background: #FDD; }");

		let $parsedNotes = $('<div class="efb-parsednotes efb-parsednotes-working"></div>');

		let newNote = new OO.ui.MultilineTextInputWidget({
			rows: 3
		});

		let addNoteButton = new OO.ui.ButtonWidget( {
			label: "Add note",
			title: "Add note with username and timestamp"
		});

		let editNotesButton = new OO.ui.ToggleButtonWidget( {
			label: canEdit ? "Edit notes" : "View source",
			title: "View notes as plain text" + (canEdit ? " and edit" : ""),
			value: false
		});

		$parsedNotes.width($notesWidget.width());
		$parsedNotes.height($notesWidget.height());
		newNote.$element.width($notesWidget.width());

		if (canEdit) {
			$notesWidget.after($parsedNotes,
							   newNote.$element,
							   addNoteButton.$element,
							   editNotesButton.$element);
		} else {
			$notesWidget.after($parsedNotes,
							   editNotesButton.$element);
		}

		addNoteButton.on('click', () => {
			addNote($notes, newNote.getValue());
			newNote.setValue('');

			if (!$parsedNotes.is(":hidden"))
				parseNotes($notes.val(), $parsedNotes).then(() => {
					/* Scroll the added note into view */
					$parsedNotes[0].scrollTop = $parsedNotes[0].scrollHeight -
						$parsedNotes[0].clientHeight;
				});
		});

		editNotesButton.on('change', value => {
			if (value) {
				$parsedNotes.hide();
				$notesWidget.show();
			} else {
				$notesWidget.hide();
				$parsedNotes.show();

				parseNotes($notes.val(), $parsedNotes);
			}
		});

		$notesWidget.hide();
		parseNotes($notes.val(),$parsedNotes);
	}

	if (mw.config.get('wgCanonicalSpecialPageName') == "AbuseFilter") {
		$.when($.ready, mw.loader.using(['mediawiki.util',
										 'mediawiki.api',
										 'oojs-ui'])).then(setup);
	}
})();
// </nowiki>