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 NavboxStuff() {
	if(mw.config.get('wgAction')=="view") {
		var getRedirectTitles = function(nav) {
			var rLinks = nav.getElementsByClassName("mw-redirect");
			if(rLinks.length == 0) return;
			var rPipe = Array.from(rLinks, r => r.title).join("|");
			var rQuery = "&redirects=" + encodeURIComponent(rPipe);
			if(navEdit = nav.getElementsByClassName("nv-edit")[0])
				navEdit.getElementsByTagName("a")[0].href += rQuery;
			if(mw.config.get('wgNamespaceNumber') == 10)
				document.getElementById("ca-edit").getElementsByTagName("a")[0].href += rQuery;
			};
		Array.from(document.getElementsByClassName("navbox")).forEach(getRedirectTitles);
		}
	if(mw.config.get('wgAction')=="edit") {
		var textbox = document.getElementById("wpTextbox1");
		if(textbox.getAttribute("readonly")) return;
		var rQuery = new URLSearchParams(location.href).get("redirects");
		if(!rQuery) return;
		var titles = decodeURIComponent(rQuery).split('|');
		var targets = { };
		var count = titles.length;
		// divide titles into groups of 50 because this is the limit
		var getChunks = function(a, n) {
			var r = [];
			for(var i = 0, s = a.length; i < s; i += n) r.push(a.slice(i,i+n));
 		 	return r;
			}
		var chunks = getChunks(titles, 50);
		var allDone = false;
		var f1 = function(r) { return r.json(); }
		var f2 = function(r) { r.query.pages.forEach(mapTarget); }
		var urlBase = "/w/api.php?action=query&prop=revisions&rvprop=content&rvslots=main&format=json&formatversion=2&titles=";
		var mapTarget = function(p) {
			var content = p.revisions[0].slots.main.content;
			// grab first [[Wikilink]] from content of a known-functional redirect
			var tRaw = content.match(/(?<=\[\[)[^\[\]]+(?=\]\])/)[0];
			// normalize underscores and excess spaces
			targets[p.title] = tRaw.replace(/[\s_]+/g, " ").trim();
			}
		var replaceIfAllLoaded = function() { 
			if(allDone || Object.keys(targets).length < count) return;
			allDone = true;
			replaceLinks(textbox, targets);
			}
		for(var i = 0; i < chunks.length; i++) {	
			var url = urlBase + chunks[i].join("|");
			fetch(url).then(f1).then(f2);
			}
		setInterval(replaceIfAllLoaded, 250);
		}
	}

function replaceLinks(textbox, dict) {
	var keys = Object.keys(dict);
	var text = textbox.value;
	for(var i = 0; i < keys.length; i++) {
		var redirect = keys[i];
		var target = dict[redirect];
		if(target.includes('#')) continue; 
		var parts = ((FF = redirect[0].toUpperCase()) != (ff = redirect[0].toLowerCase()))?
			[`[${FF}${ff}]`, redirect.substring(1)] : ['', redirect];
		var parts2 = parts[0] + parts[1].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
		var reg1 = '[\\s_]*(' + parts2.replace(/ /g, '[\\s_]+') + ')[\\s_]*';
		var reg = new RegExp("\\[\\[" + reg1 + "(?:\\|\\s*([^\\[\\]\n]+))?\\s*\\]\\]", "g");
		var replace2 = function(m,mLink,mPipe) {
			if(mPipe) {
				// normalize
				mPipe = mPipe.replace(/[\s_]+/g, " ").trim();
				// simplify [[Foo|Foo]] → [[Foo]]
				if(target == mPipe) return `[[${target}]]`; 
				// if existing redirect link is like [[Foo (song)|Foo]]
				if(redirect.startsWith(mPipe)) {
					// determine the suffix of redirect link
					var suff = redirect.substring(mPipe.length);
					// if target title is like "Föó (song)"
					if(target.endsWith(suff)) {
						// subtract suffix from target title when piping new link
						var tPipe = target.substring(0, target.length - suff.length);
						// [[Föó (song)|Föó]]
						return `[[${target}|${tPipe}]]`;
						}
					return `[[${target}]]`;
					}
				// [[Foo|Bar]] became [[Föó|Bar]]
				return `[[${target}|${mPipe}]]`;
				}
			// no return yet means original link was unpiped
			// if target has parentheses, pipe it anyway [[Foo (film)]] → [[Foo (film)|Foo]]
			var mPar = target.match(/^([^\(\)]+) \([^\(\)]+\)$/);
			if(mPar) return `[[${target}|${mPar[1]}]]`;
			// no special effects
			return `[[${target}]]`;
			}
		text = text.replace(reg, replace2);
		}
	if(text == textbox.value) return;
	textbox.value = text;
	document.getElementById("wpDiff").click();
	}

NavboxStuff();