MediaWiki:Gadget-nearby.js
Jump to navigation
Jump to search
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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// <nowiki>
(async () => {
// Do a preliminary check to avoid running the gadget unnecessarily.
if ([...document.querySelectorAll("#catlinks li")].some(cat => cat.textContent.endsWith(" lemmas"))) {
mw.util.addCSS(`
.nearby-entries-box {
padding: 6px;
margin-top: 10px;
background: var(--wikt-palette-palergreen);
width: fit-content;
max-width: 100%;
border: 1.5px solid var(--wikt-palette-forestgreen);
border-radius: 2px;
overflow-wrap: break-word;
}
`);
let actionAPI = new mw.Api({ajax: {headers: {"Api-User-Agent": "Gadget developed by [[User:Ioaxxere]]"}}});
let pageName = mw.config.values.wgPageName;
const N_ENTRIES = 3; // the number of preview entries on each side of the current page
// Given a page title (no underscores), return the prettified title.
const makeDisplayTitle = rawTitle => {
rawTitle = rawTitle.replaceAll("_", " ");
if (rawTitle.startsWith("Reconstruction:"))
return `*${rawTitle.split("/").pop()}`;
if (rawTitle.startsWith("Appendix:"))
return rawTitle.split("/").pop();
if (rawTitle.startsWith("Unsupported titles/"))
return convertUnsupportedTitle(rawTitle); // from [[MediaWiki:Gadget-UnsupportedTitles.js]]
return rawTitle;
};
// Build pageCategorySortkeys, a map from each page category to its associated sortkey.
let pageCategorySortkeys = new Map();
let continueParam;
while (true) {
let params = {
action: "query",
format: "json",
cllimit: "max",
clprop: "sortkey",
prop: "categories",
titles: pageName
};
if (continueParam)
params.clcontinue = continueParam;
let response = await actionAPI.get(params);
for (let category of Object.values(response.query.pages)[0].categories)
pageCategorySortkeys.set(category.title, category.sortkeyprefix);
if (!response.continue) break;
continueParam = response.continue.clcontinue;
}
document.querySelectorAll(".mw-heading2 h2").forEach(async h2 => {
let language = h2.id.replaceAll("_", " ");
let category = `Category:${language} lemmas`;
if (!pageCategorySortkeys.has(category)) return; // skip non-lemmas and malformed entries
let params = {
action: "query",
cmlimit: 40, // arbitrary; we don't know how many we need ahead of time
format: "json",
list: "categorymembers",
cmsort: "sortkey",
cmtitle: category,
cmstartsortkeyprefix: pageCategorySortkeys.get(category)
};
let titles = (await actionAPI.get(params)).query.categorymembers
.filter(page => page.ns !== 14) // Filter out namespace 14 (Category:)
.map(page => page.title);
// pageName is guaranteed to be in this list unless there are over `cmlimit` pages with the same sortkey.
let currPagePosition = titles.indexOf(pageName.replaceAll("_", " "));
let entriesAhead = titles.slice(currPagePosition + 1, currPagePosition + N_ENTRIES + 1);
let entriesBehind = titles.slice(Math.max(currPagePosition - N_ENTRIES, 0), currPagePosition);
if (entriesBehind.length < N_ENTRIES) {
// If entriesBehind isn't yet long enough, switch direction and get the entries coming before.
// There are no duplicates between the first and second queries.
params.cmdir = "desc";
entriesBehind = (await actionAPI.get(params)).query.categorymembers
.filter(page => page.ns !== 14)
.map(page => page.title)
.slice(0, N_ENTRIES - entriesBehind.length)
.reverse()
.concat(entriesBehind);
}
// Display nearby entries on the page.
let nearbyEntriesDiv = document.createElement("div");
nearbyEntriesDiv.className = "nearby-entries-box";
nearbyEntriesDiv.innerText = "» ";
// Need to account for both HTML formats.
if (h2.parentElement.nextElementSibling.tagName === "SECTION")
h2.parentElement.nextElementSibling.prepend(nearbyEntriesDiv);
else
h2.parentElement.parentElement.insertBefore(nearbyEntriesDiv, h2.parentElement.nextElementSibling);
for (let entry of entriesBehind) {
let entryLink = document.createElement("a");
entryLink.href = `/wiki/${mw.util.wikiUrlencode(entry)}#${h2.id}`;
entryLink.title = entry;
entryLink.textContent = makeDisplayTitle(entry);
nearbyEntriesDiv.append(entryLink, " • ");
}
let selflink = document.createElement("a");
selflink.className = "mw-selflink selflink";
selflink.textContent = makeDisplayTitle(pageName);
nearbyEntriesDiv.append(selflink);
for (let entry of entriesAhead) {
let entryLink = document.createElement("a");
entryLink.href = `/wiki/${mw.util.wikiUrlencode(entry)}#${h2.id}`;
entryLink.title = entry;
entryLink.textContent = makeDisplayTitle(entry);
nearbyEntriesDiv.append(" • ", entryLink);
}
});
}
})();
// </nowiki>