User:Erutuon/scripts/todo-lists.js
< User:Erutuon | scripts
Note – after saving, you may have to bypass your browser’s cache to see the changes.
- Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
- Konqueror and Chrome: click Reload or press F5;
- Opera: clear the cache in Tools → Preferences;
- Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.
- This script lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • redirects • your own
{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 "{{" + printed.join("|") + "}}";
};
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(/\((?<from>[^→]+) → (?<to>[^\)]+)\)[^\(]+\((?<lang>[^\)]+)\) 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 = "";
}
});
}
});
})});
}