User:Erutuon/scripts/todo-lists.js

{const pageName = mw.config.get("wgPageName");

const templateToWikitext = function(name, parameters) { const printed = [name]; let i = 1; for (const [k, v] of parameters) { const kNumber = parseInt(k); if (kNumber && kNumber == i) { printed.push(v); i++; } else { printed.push(k + "=" + v); }	}	return ""; };

const applyChanges = function(parameters, changes) { const added = []; const additions = changes.filter(({action: [action]}) => action === "add").map(({action: [action, ...args]}) => args); const newParameters = parameters.filter(([k, v]) => {		for (const {action: [action, ...args]} of changes) {			if (action === "remove" && k === args[0]) {				return false;			}		}		return true;	}).map(([k, v]) => {		for (const [kAdded, vAdded] of additions) {			if (k === kAdded) {				added.push(k);				return [k, vAdded];			}		}		return [k, v];	}); for (const [kAdded, vAdded] of additions) { if (!added.includes(kAdded)) { newParameters.push([kAdded, vAdded]); }	}	return newParameters; };

const templateClass = "tlx"; mw.loader.using(["mediawiki.util", "mediawiki.api"], function {	mw.util.addCSS("." + templateClass + " { display: inline-grid; margin: 0.2em 0; }"); });

mw.loader.using("mediawiki.api", function { $(function { const dl = document.createElement("dl"); const pre = document.querySelector(".mw-parser-output pre.title-and-templates"); if (!pre) { return; } const articlePath = mw.config.get("wgArticlePath"); pre.textContent .split("\n") .filter(line => line !== "") .map(JSON.parse) .forEach(item => {		const dt = document.createElement("dt");		const viewLink = document.createElement("a");		viewLink.textContent = item.title;		viewLink.href = articlePath.replace("$1", item.title);		dt.appendChild(viewLink);		const sup = document.createElement("sup");		const editLink = document.createElement("a");		editLink.textContent = "edit";		editLink.href = articlePath.replace("$1", "Special:Edit/" + item.title);		sup.appendChild(editLink);		dt.appendChild(sup);		const ul = document.createElement("ul");		for (const template of item.templates) {			const li = document.createElement("li");			const innerPre = document.createElement("pre");			innerPre.classList.add(templateClass);			innerPre.textContent = template;			li.appendChild(innerPre);			ul.appendChild(li);		}		const dd = document.createElement("dd");		dd.appendChild(ul);		dl.appendChild(dt);		dl.appendChild(dd);	}); pre.insertAdjacentElement('beforeBegin', dl); }); if (pageName === "User:Erutuon/lists/best_script_not_matching_sc_parameter") $(function { const dl = document.createElement("dl"); const preList = document.querySelectorAll(".mw-parser-output pre"); if (preList.length === 0) { return; } const pre = preList[preList.length - 1]; const articlePath = mw.config.get("wgArticlePath"); pre.textContent .split("\n") .filter(line => line !== "") .map(JSON.parse) .forEach(item => {		const dt = document.createElement("dt");		const viewLink = document.createElement("a");		viewLink.textContent = item.title;		viewLink.href = articlePath.replace("$1", item.title);		dt.appendChild(viewLink);		const sup = document.createElement("sup");		const editLink = document.createElement("a");		editLink.textContent = "edit";		editLink.href = articlePath.replace("$1", "Special:Edit/" + item.title);		sup.appendChild(editLink);		dt.appendChild(sup);		const ul = document.createElement("ul");		for (const {template, link} of item.links) {			const li = document.createElement("li");			const templateElement = document.createElement("code");			templateElement.classList.add(templateClass);			templateElement.textContent = templateToWikitext(template.name, template.parameters);			li.appendChild(templateElement);			for (const name of ["lang", "best_script", "best_script_without_lang"]) { let item = link[name]; if (item) { if (item instanceof Array) item = item[1]; const code = document.createElement("code"); code.textContent = item; li.append("; " + name.replace(/_/g, " ") + " = "); li.appendChild(code); }			}			ul.appendChild(li); }		const dd = document.createElement("dd"); dd.appendChild(ul); dl.appendChild(dt); dl.appendChild(dd); });	pre.insertAdjacentElement('beforeBegin', dl); }); if (pageName === "User:Erutuon/lists/best_script_not_matching_sc_parameter/fixes" || pageName === "User:Erutuon/lists/bad_transliteration/Cyrillic_and_Latin/fixes") $(function {	const dl = document.createElement("dl");	const preList = document.querySelectorAll(".mw-parser-output pre");	const pre = preList[preList.length - 1];	const articlePath = mw.config.get("wgArticlePath");	const data = JSON.parse(pre.textContent);	const summaries = Array.from(new Set(data.flatMap(page => { if (!page.templates[0].changes.summary) { return [page.summary]; }		return page.templates.flatMap(template => template.changes.flatMap(change => change.summary)); })));	const separator = "\uE000";	new mw.Api.post({ action: "parse", summary: summaries.join(separator), prop: "text", formatversion: "2", }).fail(console.error).then(response => response.parse.parsedsummary.split(separator)).then(parsedSummaries => { const summaryMap = new Map(parsedSummaries.map((parsedSummary, i) => [summaries[i], parsedSummary])); data.forEach(item => {			const dt = document.createElement("dt");			const viewLink = document.createElement("a");			viewLink.textContent = item.title;			viewLink.href = articlePath.replace("$1", item.title);			dt.appendChild(viewLink);			const sup = document.createElement("sup");			const editLink = document.createElement("a");			editLink.textContent = "edit";			editLink.href = articlePath.replace("$1", "Special:Edit/" + item.title);			sup.appendChild(editLink);			dt.appendChild(sup);			const pageSummary = item.summary;			if (pageSummary) {				const parsedPageSummary = summaryMap.get(pageSummary);				if (parsedPageSummary) {					const summaryNoteElement = document.createElement("span");					const summaryElement = document.createElement("span");					summaryElement.innerHTML = parsedPageSummary;					summaryNoteElement.append(" (", summaryElement, ")");					summaryNoteElement.style.fontWeight = "normal"; dt.append(summaryNoteElement); } else { console.error("Failed to parse summary " + pageSummary); }			}			const ul = document.createElement("ul"); for (const {					template,					changes,				} of item.templates) { const li = document.createElement("li"); li.dataset.template = JSON.stringify(template); li.dataset.changes = JSON.stringify(changes); const templateElement = document.createElement("code"); templateElement.classList.add(templateClass); templateElement.textContent = templateToWikitext(template.name, template.parameters); li.appendChild(templateElement); li.append(" → "); const newTemplateElement = document.createElement("code"); newTemplateElement.textContent = templateToWikitext(template.name, applyChanges(template.parameters, changes)); li.appendChild(newTemplateElement); const changeSummaries = changes.map(change => change.summary); li.dataset.summary = changeSummaries.join("; "); const parsedChangeSummaries = changeSummaries.map(s => summaryMap.get(s)); if (parsedChangeSummaries.length > 0 && parsedChangeSummaries.every(s => s != undefined)) { const summaryElement = document.createElement("span"); summaryElement.innerHTML = parsedChangeSummaries.join("; "); li.append(" (");					li.appendChild(summaryElement);					li.append(")"); } else if (changes[0].summary) { const unparsedChangeSummaries = changeSummaries.filter(s => !summaryMap.get(s)); console.error("Failed to parse summaries " + JSON.stringify(unparsedChangeSummaries)); }				ul.appendChild(li); }			const dd = document.createElement("dd"); dd.appendChild(ul);

dl.appendChild(dt); dl.appendChild(dd); });		pre.insertAdjacentElement('beforeBegin', dl);		function* chunks(arr, n) {			arr = Array.from(arr);			for (let i = 0; i < arr.length; i += n) {				yield arr.slice(i, i + n);			}		}		window.filterChangeItems = function (filter) {			Array.from(chunks(document.querySelector("dl").childNodes, 2)).forEach(([t, d]) => { const lis = Array.from(d.querySelector("ul").children); const remaining = lis.filter(li => {					const summary = li.dataset.summary;					const match = summary.match(/\((? [^→]+) → (?[^\)]+)\)[^\(]+\((? [^\)]+)\) text/).groups; return filter(match.lang, match.from, match.to, summary); });				lis.forEach(li => { li.style.display = remaining.includes(li) ? "" : "none"; });				if (remaining.length === 0) {					t.style.display = "none";					d.style.display = "none";				} else {					t.style.display = "";					d.style.display = "";				}			}); }	}); })}); }