MediaWiki:Gadget-OrangeLinks.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
// <nowiki>
function HTML_unescape(text) {
return new DOMParser().parseFromString(text, "text/html").body.textContent;
}
function getTitleAndAnchor(link) {
let linkTitle = decodeURIComponent(link.pathname.split("/wiki/")[1]);
let linkAnchor = decodeURIComponent(link.hash.slice(1) || "");
return [linkTitle, linkAnchor];
}
mw.util.addCSS(`
.orange-link {
color: var(--wikt-palette-gold);
}
.orange-link:visited {
color: var(--wikt-palette-dullgold);
}
.orange-link:hover, .orange-link:visited:hover {
color: var(--wikt-palette-honey);
}
`);
let actionAPI = new mw.Api({ajax: {headers: {"Api-User-Agent": "Gadget developed by [[User:Ioaxxere]]"}}});
// Maps each page to a list of IDs.
let pageIDsOf = new Map();
async function makeOrangeLinks(element) {
// Get a list of pages and links to process.
let pagesToProcess = [];
let linksToProcess = [];
for (let link of element.querySelectorAll("a")) {
// Check whether the link needs to be processed.
if (!link.href.startsWith("https://en.wiktionary.org/wiki/")) continue;
if (link.matches(".orange-link, .not-orange-link, .new, .external")) continue;
let [linkTitle, linkAnchor] = getTitleAndAnchor(link);
if (!linkAnchor || /^[a-z]/.test(linkAnchor)) continue;
if (![0, 100, 118].includes(new mw.Title(linkTitle).namespace)) continue; // Main, Appendix, Reconstruction
pagesToProcess.push(linkTitle);
linksToProcess.push(link);
}
// Filter out duplicates.
pagesToProcess = [...new Set(pagesToProcess)];
// Process the array in chunks.
let queries = [];
for (let i = 0; i < pagesToProcess.length; i += 100) {
let chunk = pagesToProcess.slice(i, i + 100);
// Query the IDs for all the pages using [[Module:get IDs]].
let params = {
action: "expandtemplates",
format: "json",
prop: "wikitext",
text: `{{#invoke:get IDs|show|${chunk.join("|")}}}`
};
queries.push(actionAPI.post(params).then(response => {
// Integrate the results into `pageIDsOf`.
let pageIDs = HTML_unescape(response.expandtemplates.wikitext).split("\n\n");
for (let j = 0; j < chunk.length; j++)
pageIDsOf.set(chunk[j], pageIDs[j].split(" "));
}));
}
await Promise.all(queries);
// After all the queries have returned, determine whether each link needs to be orange.
for (let link of linksToProcess) {
let [linkTitle, linkAnchor] = getTitleAndAnchor(link);
let anchorExists = pageIDsOf.get(linkTitle).includes(linkAnchor);
link.classList.add(anchorExists ? "not-orange-link" : "orange-link");
}
}
// Activate the gadget.
let pageContent = document.querySelector(".mw-parser-output");
if (pageContent)
makeOrangeLinks(pageContent);
// Create a global hook in case any other gadget or script would like to activate it.
window.makeOrangeLinks = makeOrangeLinks;
// </nowiki>