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.
// <nowiki>
function preprocessInput(input) {
	// Replace "{{#invoke:cite" with "{{cite"
	input = input.replace(/{{#invoke:cite/gi, "{{cite");

	// Replace "{{!}}" with 'PLACEHOLDER_FOR_BANG'
	return input.replace(/{{\s*!\s*}}/gi, 'PLACEHOLDER_FOR_BANG');
}

function replaceTitle(title) {
	// Replace "[" and "]" in the title with "<nowiki>[</nowiki>" and "<nowiki>]</nowiki>"
	return title.replace(/\[/g, '<nowiki>[</nowiki>').replace(/\]/g, '<nowiki>]</nowiki>');
}

function createCitation(url, title, archiveUrl) {
	let citation = `[${url} ${title}]`;

	if (archiveUrl) {
		citation += ` ([${archiveUrl} Archived])`;
	}

	return citation;
}

function replaceCite(inputText, citeType) {
	const regex = new RegExp(`{{cite\\s*${citeType}\\s*([^}]*)}}`, 'gi');

	const convertedText = inputText.replace(regex, function(match, content) {
		let title = '';
		let url = '';
		let archiveUrl = '';
		let user = '';
		let number = '';

		const paramRegex = /([^|=]+)=([^|]+)/g;
		let paramMatch;

		while ((paramMatch = paramRegex.exec(content)) !== null) {
			const paramName = paramMatch[1].trim();
			const paramValue = paramMatch[2].trim();

			if (paramName === 'title' || paramName === 'script-title' || paramName === 'trans-title') {
				title = replaceTitle(paramValue);
			} else if (paramName === 'url') {
				url = paramValue;
			} else if (paramName === 'archive-url') {
				archiveUrl = paramValue;
			} else if (paramName === 'user') {
				user = paramValue;
			} else if (paramName === 'number') {
				number = paramValue;
			}
		}

		if (citeType === 'tweet') {
			return `[https://twitter.com/${user}/status/${number} ${title}]`;
		} else {
			return createCitation(url, title, archiveUrl);
		}
	});

	return convertedText;
}

function replaceCiteTweet(inputText) {
	return replaceCite(inputText, 'tweet');
}

function restoreBangPlaceholder(input) {
	return input.replace(RegExp('PLACEHOLDER_FOR_BANG', 'g'), '{{!}}');
}

function addToArticleTop(editor) {
	const botsText = "{{bots|deny=Citation bot}}";
	const commentText = "<!-- References should be in <ref>[url & title]</ref> format, as full citations make the page too slow to load, and too big to edit. -->";
	const articleContent = editor.get();

	if (articleContent.indexOf(botsText) === -1) {
		editor.prepend(botsText + "\n");
	}

	if (articleContent.indexOf(commentText) === -1) {
		editor.prepend(commentText + "\n");
	}
}

function editSummary(editor) {
	editor
		.options({
			minor: true
		})
		.appendEditSummary("Converted references to [[Wikipedia:Bare URLs|simple titles]] using [[User:Pbrks/script/PlainURL.js|a script]]");
}

$.ajax("//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js", {
	dataType: "script",
	cache: true
}).then(function() {
	pathoschild.TemplateScript.add([{
		name: "Plain URL references",
		script: function(editor) {
			let input = editor.get();

			editor.replace(input, preprocessInput(input));
			input = editor.get();

			editor.replace(input, replaceCiteTweet(input));
			input = editor.get();

			editor.replace(input, replaceCite(input, ''));
			input = editor.get();

			editor.replace(input, restoreBangPlaceholder(input));
			input = editor.get();

			addToArticleTop(editor);
			editSummary(editor);
		}
	}]);
});
// </nowiki>