User:Alex 21/script-references.js

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($) {
	mw.loader.using( ['mediawiki.util'] ).then( function () {
		var portletlink = mw.util.addPortletLink('p-tb', '#', 'Sort references');
		$(portletlink).click( function(e) {
			e.preventDefault();
			// Declare variables
			var loc = window.location.href; var wpTextbox1 = document.getElementById('wpTextbox1'); var i; var r; var x;
			if (loc.indexOf('action=edit') < 0 && loc.indexOf('action=submit') < 0) {
				// Check page is in editing move
				alert("Go to the edit page to use this script.");
			} else {
				// Declare variables
				var allRefs = [];
				var allRefNames = [];
				var addToReflist = "";
				var wpTextboxContents;
				var regexDateFormats = [
					/\|\s*?date\s*=\s*(([A-Za-z]+) \d{1,2}, (\d{4}))/,
					/\|\s*?date\s*=\s*(\d{1,2} ([A-Za-z]+) (\d{4}))/,
					/\|\s*?date\s*=\s*((\d{4})-(\d{1,2})-(\d{1,2}))/,
					/\|\s*?archive-?date\s*=\s*(([A-Za-z]+) \d{1,2}, (\d{4}))/,
					/\|\s*?archive-?date\s*=\s*(\d{1,2} ([A-Za-z]+) (\d{4}))/,
					/\|\s*?archive-?date\s*=\s*((\d{4})-(\d{1,2})-(\d{1,2}))/,
					/\|\s*?access-?date\s*=\s*(([A-Za-z]+) \d{1,2}, (\d{4}))/,
					/\|\s*?access-?date\s*=\s*(\d{1,2} ([A-Za-z]+) (\d{4}))/,
					/\|\s*?access-?date\s*=\s*((\d{4})-(\d{1,2})-(\d{1,2}))/,
				];
				
				// Fix all references as they exist, use double quotes instead of single/none
				while (x = /(<ref[^>]*name=)'?([^'">]+)'?([^>]*>([^>]+<\/ref>)?)/.exec(wpTextbox1.value)) {
					wpTextbox1.value = wpTextbox1.value.replaceAll(x[0], x[1]+"\""+x[2]+"\""+x[3]);
				}
				
				// Gather all references
				wpTextboxContents = wpTextbox1.value.split("\n");
				for (i = 0; i < wpTextboxContents.length; i++) {
					if (wpTextboxContents[i].indexOf('ref') > 0) {
						var reg = /<ref[^>]*>([^>]+<\/ref>)?/g;
						while (x = reg.exec(wpTextboxContents[i])) {
							if (x[0].indexOf("/>") < 0) allRefs[allRefs.length] = x[0];
						}
					}
				}
				
				// Sort all references by date
				var allRefsDated = [];
				var dateRegex;
				for (i = 0; i < allRefs.length; i++) {
					dateRegex = null;
					for (r = 0; r < regexDateFormats.length; r++) {
						if (!dateRegex) dateRegex = regexDateFormats[r].exec(allRefs[i]);
					}
					allRefsDated[allRefsDated.length] = [parseInt((new Date(dateRegex[1]).getTime() / 1000).toFixed(0)), allRefs[i]];
				}
				allRefsDated.sort(function(a, b) {
					if (a[0] < b[0]) return -1;
					else if (a[0] > b[0]) return 1;
					else return 0;
				});
				for (i = 0; i < allRefs.length; i++) {
					allRefs[i] = allRefsDated[i][1];
				}
				
				// Loop through all references
				for (i = 0; i < allRefs.length; i++) {
					// Reference does not have a name - provide one
					if (allRefs[i].indexOf('<ref name=') < 0) {
						// Gather website name, date month and year
						var urlRegex = /https?:\/\/(www\.)?([-a-zA-Z0-9@:%._\+~#=]{1,256})\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/.exec(allRefs[i]);
						dateRegex = null;
						for (r = 0; r < regexDateFormats.length; r++) {
							if (!dateRegex) dateRegex = regexDateFormats[r].exec(allRefs[i]);
						}
						// Reference name = website name + date month + date year
						var citeName = ( urlRegex ? citeName = urlRegex[2] : citeName = /\{\{[Cc]ite\s*([^\|]+)\s*\|/.exec(allRefs[i])[1] );
						var newName = citeName.charAt(0).toUpperCase() + citeName.slice(1) + dateRegex[2] + dateRegex[3];
						// Duplicate reference names, update to name, name-2, name-3, etc.
						if (typeof allRefNames[newName] != "undefined") {
							var newNameTmp = newName;
							var repeatNameCount = 2;
							while (typeof allRefNames[newNameTmp] != "undefined") {
								newNameTmp = newName+"-"+repeatNameCount;
								repeatNameCount++;
							}
							newName = newNameTmp;
						}
						
						// Update this unnamed reference
						var oldRefName = allRefs[i];
						var newRefName = allRefs[i].replace("<ref", "<ref name=\""+newName+"\"");
						wpTextbox1.value = wpTextbox1.value.replaceAll(oldRefName, newRefName);
						
						// Update all references list with named reference
						allRefs[i] = newRefName;
					}
					// Add reference to list that will end in {{Reflist}}
					addToReflist += "\n\n" + allRefs[i];
					
					// Gather name of reference, and update all <ref name="*">...</ref> to <ref name="*" />
					var regNamed = /(<ref[^>]*name=['"]?([^'">]+)['"]?[^>]*)>([^>]+<\/ref>)?/g;
					x = regNamed.exec(allRefs[i]);
					if (x) {
						var name = x[2];
						allRefNames[name] = true;
						var reg2 = new RegExp("(<ref[^>]*name=['\"]?"+name+"['\"]?[^>]*)>([^>]+<\/ref>)?","g");
						wpTextbox1.value = wpTextbox1.value.replace(reg2, x[1]+" />");
					}
				}
				
				// Update {{reflist}} to {{Reflist}}, then add all reference within template
				wpTextbox1.value = wpTextbox1.value.replace("{{reflist", "{{Reflist");
				wpTextbox1.value = wpTextbox1.value.replace("{{Reflist", "{{Reflist |refs="+addToReflist+"\n\n");
				
				// Done
				document.getElementById('wpSummary').value += "Adjusted references via [[User:Alex 21/script-references|script]].";
			}
		});
	});
});