Jump to content

User:Andrybak/Scripts/Unsigned helper.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Andrybak (talk | contribs) at 20:27, 15 July 2024 (formatErrorSpan: replace red with maroon for readability). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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.
(function () {
	const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

	function makeUnsignedTemplate(user, timestamp, template) {
		const ts = new Date(timestamp);
		let h = ts.getUTCHours();
		if (h < 10)
			h = '0' + h;
		let m = ts.getUTCMinutes();
		if (m < 10)
			m = '0' + m;
		const formattedTimestamp = `${h}:${m}, ${ts.getUTCDate()} ${months[ts.getUTCMonth()]} ${ts.getUTCFullYear()} (UTC)`;
		return '{{subst:' + template + '|' + user + '|' + formattedTimestamp + '}}';
	}

	function appendToEditSummary(newSummary) {
		const editSummaryField = $("#wpSummary:first");
		if (editSummaryField.length == 0) {
			console.warn('Cannot find edit summary text field.');
			return;
		}
		const oldText = editSummaryField.val().trimEnd();
		// get text without trailing whitespace
		let newText = "";
		if (oldText.match(/[*]\/$/)) {
			// check if "/* section name */" is present
			newText = oldText + " " + newSummary;
		} else if (oldText.length != 0) {
			newText = oldText + ", " + newSummary;
		} else {
			newText = newSummary;
		}
		editSummaryField.val(newText);
	}

	function formatErrorSpan(errorMessage) {
		return `<span style="color:maroon;"><b>Error:</b> ${errorMessage}</span>`;
	}

	function doAddUnsignedTemplate() {
		var f = document.getElementById('editform');
		var e = f.elements.wpTextbox1;
		var pos = $(e).textSelection('getCaretPosition', { startAndEnd: true });
		var txt;
		if (pos[0] != pos[1]) {
			txt = e.value.substring(pos[0], pos[1]);
			pos = pos[1];
		} else {
			pos = pos[1];
			if (pos <= 0)
				pos = e.value.length;
			txt = e.value.substr(0, pos);
			txt = txt.replace(new RegExp('[\\s\\S]*\\d\\d:\\d\\d, \\d+ (' + months.join('|') + ') \\d\\d\\d\\d \\(UTC\\)'), '');
			txt = txt.replace(/[\s\S]*\n=+.*=+\s*\n/, '');
		}
		txt = txt.replace(/^\s+|\s+$/g, '');

		var rvct = 1;
		var dialog = $('<div>Examining revision 1...</div>').dialog({
			buttons: {
				Cancel: function () {
					dialog.dialog('close');
				} },
			modal: true,
			title: 'Adding {{unsigned}}'
		});

		var revid, user, ts, comment, template;
		var q = {
			url: mw.util.wikiScript('api'),
			dataType: 'json',
			type: 'POST',
			data: {
				format: 'json',
				action: 'query',
				titles: mw.config.get('wgPageName'),
				prop: 'revisions',
				rvprop: 'ids|timestamp|user|parsedcomment|content',
				rvlimit: 1,
				rawcontinue: 1
			},
			success: function (r, sts, xhr) {
				if (!dialog.dialog('isOpen'))
					return;

				if (!r.query || !r.query.pages) {
					dialog.html(formatErrorSpan('Bad response from API'));
					if (window.console && typeof (window.console.error) == 'function')
						window.console.error("Bad response", r);
					return;
				}

				for (var k in r.query.pages) {
					var rr = r.query.pages[k].revisions[0];
					var cont = function () {
						if (r['query-continue'] && r['query-continue'].revisions) {
							dialog.html('Evaluating revision ' + (++rvct) + '...');
							q.data.rvcontinue = r['query-continue'].revisions.rvcontinue;
							$.ajax(q);
						} else {
							var t = makeUnsignedTemplate(user, ts, template);
							var tt = e.value.substr(0, pos).replace(/\s*$/, ' ') + t;
							e.value = tt + e.value.substr(pos);
							$(e).textSelection('setSelection', {
								start: tt.length });
							appendToEditSummary(`mark unsigned [[Special:Diff/${revid}]]`);
							dialog.dialog('close');
						}
					};

					if (typeof (rr['*']) != 'undefined' && rr['*'].indexOf(txt) < 0) {
						if (!user) {
							dialog.html(formatErrorSpan('Text was not found in the starting revision! Did you edit it?'));
							return;
						}
						var cb = function () {
							var t = makeUnsignedTemplate(user, ts, template);
							var tt = e.value.substr(0, pos).replace(/\s*$/, ' ') + t;
							e.value = tt + e.value.substr(pos);
							$(e).textSelection('setSelection', {
								start: tt.length });
							appendToEditSummary(`unsigned [[Special:Diff/${revid}]]`);
							dialog.dialog('close');
						};
						if (/reverted|undid/i.test(comment)) {
							var dialog2 = $('<div>')
								.append(
									'The ',
									$('<a>').prop({
										href: '/w/index.php?diff=prev&oldid=' + revid, target: '_blank' }).text('found revision'),
									' may be a revert: ',
									comment
								)
								.dialog({
									title: "Possible revert!",
									modal: true,
									buttons: {
										"Use that revision": function () {
											dialog2.dialog('close');
											cb();
										},
										"Keep looking": function () {
											dialog2.dialog('close');
											cont();
										},
										"Cancel": function () {
											dialog2.dialog('close');
											dialog.dialog('close');
										},
									}
								});
						} else {
							cb();
						}
					} else {
						revid = rr.revid;
						user = rr.user;
						ts = rr.timestamp;
						comment = rr.parsedcomment;
						if (typeof (rr.anon) !== 'undefined') {
							template = 'Unsigned IP';
						} else if (typeof (rr.temp) !== 'undefined') {
							// Seems unlikely "temporary" users will have a user page, so this seems the better template for them for now.
							template = 'Unsigned IP';
						} else {
							template = 'Unsigned';
						}
						cont();
					}
					return;
				}
				dialog.html(formatErrorSpan('No revisions found in the page!'));
			},
			error: function (xhr, textStatus, errorThrown) {
				if (!dialog.dialog('isOpen'))
					return;
				dialog.html(formatErrorSpan(textStatus + ' ' + errorThrown));
			}
		};
		if (f.elements.baseRevId)
			q.data.rvstartid = f.elements.baseRevId.value;
		$.ajax(q);
	}

	window.unsignedHelperAddUnsignedTemplate = function(event) {
		mw.loader.using(['mediawiki.util', 'jquery.ui'], doAddUnsignedTemplate);
		event.preventDefault();
		event.stopPropagation();
		return false;
	}
	
	if (!window.charinsertCustom)
		window.charinsertCustom = {};
	if (!window.charinsertCustom['Insert'])
		window.charinsertCustom['Insert'] = '';
	window.charinsertCustom['Insert'] += ' {{unsigned}}\x10unsignedHelperAddUnsignedTemplate';
	if (!window.charinsertCustom['Wiki markup'])
		window.charinsertCustom['Wiki markup'] = '';
	window.charinsertCustom['Wiki markup'] += ' {{unsigned}}\x10unsignedHelperAddUnsignedTemplate';
	if (window.updateEditTools)
		window.updateEditTools();
})();