MediaWiki:Gadget-OrangeLinks.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
/ | // <nowiki> | ||
var actionAPI = new mw.Api({ ajax: { headers: { "Api-User-Agent": "Gadget developed by [[User:Ioaxxere]]" } } }); | |||
var HTML_unescape = function(text) { | |||
return new DOMParser().parseFromString(text, "text/html").body.textContent; | |||
}; | |||
function getTitleAndAnchor(link) { | function getTitleAndAnchor(link) { | ||
var linkTitle = decodeURIComponent(link.pathname.split("/wiki/")[1]); | |||
var linkAnchor = decodeURIComponent(link.hash.slice(1) || ""); | |||
return [linkTitle, linkAnchor]; | |||
} | } | ||
mw.util.addCSS( | mw.util.addCSS( | ||
".orange-link { color: #b88d00; }" + | |||
".orange-link:visited { color: #826f34; }" + | |||
".orange-link:hover, .orange-link:visited:hover { color: #81540e; }" | |||
); | |||
// Maps each page to a list of IDs. | // Maps each page to a list of IDs. | ||
var pageIDsOf = {}; | |||
function makeOrangeLinks(element) { | function makeOrangeLinks(element) { | ||
// Get a list of pages and links to process. | |||
var pagesToProcess = []; | |||
var linksToProcess = []; | |||
var links = element.querySelectorAll("a"); | |||
for (var i = 0; i < links.length; i++) { | |||
var link = links[i]; | |||
// Check whether the link needs to be processed. | |||
if (link.href.indexOf("https://en.wiktionary.org/wiki/") !== 0 && | |||
link.href.indexOf("https://en.m.wiktionary.org/wiki/") !== 0) { | |||
continue; | |||
} | |||
if (link.className.match(/orange-link|not-orange-link|new|external/)) { | |||
continue; | |||
} | |||
var parts = getTitleAndAnchor(link); | |||
var linkTitle = parts[0]; | |||
var linkAnchor = parts[1]; | |||
if (!linkAnchor || /^[a-z]/.test(linkAnchor) || (new mw.Title(linkTitle)).namespace !== 0) { | |||
continue; | |||
} | |||
pagesToProcess.push(linkTitle); | |||
linksToProcess.push(link); | |||
} | |||
// Filter out duplicates. | |||
var uniquePages = {}; | |||
var pages = []; | |||
for (var j = 0; j < pagesToProcess.length; j++) { | |||
if (!uniquePages[pagesToProcess[j]]) { | |||
uniquePages[pagesToProcess[j]] = true; | |||
pages.push(pagesToProcess[j]); | |||
} | |||
} | |||
pagesToProcess = pages; | |||
// Process the array in chunks. | |||
var queries = []; | |||
for (var k = 0; k < pagesToProcess.length; k += 100) { | |||
var chunk = pagesToProcess.slice(k, k + 100); | |||
// Query the IDs for all the pages using [[Module:get IDs]]. | |||
var wikitext = "{{#invoke:get IDs|show|" + chunk.join("|") + "}}"; | |||
var params = { | |||
action: "expandtemplates", | |||
format: "json", | |||
prop: "wikitext", | |||
text: wikitext | |||
}; | |||
queries.push( | |||
actionAPI.post(params).then((function(chunkCopy) { | |||
return function(response) { | |||
var pageIDs = HTML_unescape(response.expandtemplates.wikitext).split("\n\n"); | |||
for (var m = 0; m < chunkCopy.length; m++) { | |||
pageIDsOf[chunkCopy[m]] = pageIDs[m].split(" "); | |||
} | |||
}; | |||
})(chunk)) | |||
); | |||
} | |||
// After all the queries have returned, determine whether each link needs to be orange. | |||
Promise.all(queries).then(function() { | |||
for (var n = 0; n < linksToProcess.length; n++) { | |||
var link = linksToProcess[n]; | |||
var parts = getTitleAndAnchor(link); | |||
var linkTitle = parts[0]; | |||
var linkAnchor = parts[1]; | |||
if (pageIDsOf[linkTitle] && pageIDsOf[linkTitle].indexOf(linkAnchor) !== -1) { | |||
link.classList.add("not-orange-link"); | |||
} else { | |||
link.classList.add("orange-link"); | |||
} | |||
} | |||
}); | |||
} | } | ||
// Activate the gadget. | // Activate the gadget. | ||
var pageContent = document.querySelector(".mw-parser-output"); | |||
if (pageContent) | if (pageContent) { | ||
makeOrangeLinks(pageContent); | |||
} | |||
// Create a global hook in case any other gadget or script would like to activate it. | // Create a global hook in case any other gadget or script would like to activate it. | ||
window.makeOrangeLinks = makeOrangeLinks; | window.makeOrangeLinks = makeOrangeLinks; | ||
// </nowiki> | // </nowiki> | ||