Jump to content

User:Cobaltcigs/NavboxStuff.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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();