User:Ioaxxere/minitoc.js
Jump to navigation
Jump to search
Note: You may have to bypass your browser’s cache to see the changes. In addition, after saving a sitewide CSS file such as MediaWiki:Common.css, it will take 5-10 minutes before the changes take effect, even if you clear your cache.
- 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
// <nowiki>
// Initialize preferred languages from local storage.
let preferredLanguages = new Set(JSON.parse(localStorage.getItem("minitocLangs")));
// Empty and filled-in bookmark icons.
const unselectedIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="17" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor" style="vertical-align: text-top; cursor: pointer"><g><path d="M5 1a2 2 0 00-2 2v16l7-5 7 5V3a2 2 0 00-2-2zm10 14.25-5-3.5-5 3.5V3h10z"></path></g></svg>`;
const selectedIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="17" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor" style="vertical-align: text-top; cursor: pointer"><g><path d="M5 1a2 2 0 00-2 2v16l7-5 7 5V3a2 2 0 00-2-2z"></path></g></svg>`;
function displayLanguages() {
// Clear out previously displayed languages.
document.querySelectorAll(".minitoc-linked-languages").forEach(elem => elem.remove());
for (let minitoc of document.querySelectorAll(".minitoc")) {
let linkedLanguages = document.createElement("span");
linkedLanguages.className = "minitoc-linked-languages";
for (let languageLink of minitoc.querySelectorAll(".NavContent > a")) {
if (preferredLanguages.has(languageLink.textContent)) {
let link = document.createElement("a");
link.textContent = "→ " + languageLink.textContent;
link.href = languageLink.href;
link.style.whiteSpace = "nowrap";
linkedLanguages.append(" ", link);
}
}
if (linkedLanguages.childElementCount)
minitoc.querySelector(".NavHead").append(linkedLanguages);
}
}
// Setup.
// Note: the code is generic and can handle multiple miniTOCs on one page, although this probably isn't necessary.
for (let minitoc of document.querySelectorAll(".minitoc")) {
minitoc.querySelector(".NavContent").insertAdjacentHTML("beforeend",
`<span style="font-size: 85%" class="minitoc-button-container">
 
[<a class="minitoc-button-select" role="button">
Select preferred languages
</a>]
<span style="display: none">
 
[<a class="minitoc-button-clear" role="button">
Clear all
</a>]
</span>
</span>`
.replace(/[\n\t]/g, "")
);
let selectButton = minitoc.querySelector(".minitoc-button-select");
let clearButton = minitoc.querySelector(".minitoc-button-clear");
selectButton.addEventListener("click", () => {
// The button can be in two states: "select" and "save".
if (selectButton.textContent === "Select preferred languages") {
clearButton.parentElement.style.display = "";
// Make sure you can't have multiple miniTOCs in "select" mode simultaneously.
for (let button of document.querySelectorAll(".minitoc-button-select")) {
if (button.textContent === "Save preferred languages") {
// Trigger the saving procedure.
button.click();
}
}
selectButton.textContent = "Save preferred languages";
for (let languageLink of minitoc.querySelectorAll(".NavContent > a")) {
let iconContainer = document.createElement("span");
iconContainer.role = "button";
languageLink.insertAdjacentElement("beforebegin", iconContainer);
if (preferredLanguages.has(languageLink.textContent)) {
iconContainer.className = "minitoc-icon-selected";
iconContainer.innerHTML = selectedIcon;
} else {
iconContainer.className = "minitoc-icon-unselected";
iconContainer.innerHTML = unselectedIcon;
}
iconContainer.addEventListener("click", () => {
if (preferredLanguages.has(languageLink.textContent)) {
preferredLanguages.delete(languageLink.textContent);
iconContainer.className = "minitoc-icon-unselected";
iconContainer.innerHTML = unselectedIcon;
} else {
preferredLanguages.add(languageLink.textContent);
iconContainer.className = "minitoc-icon-selected";
iconContainer.innerHTML = selectedIcon;
}
});
}
} else {
// Save to local storage.
localStorage.setItem("minitocLangs", JSON.stringify(Array.from(preferredLanguages)));
// Reset state.
minitoc.querySelectorAll(".minitoc-icon-selected, .minitoc-icon-unselected").forEach(elem => elem.remove());
selectButton.textContent = "Select preferred languages";
clearButton.parentElement.style.display = "none";
displayLanguages();
}
});
clearButton.addEventListener("click", () => {
preferredLanguages = new Set();
minitoc.querySelectorAll(".minitoc-icon-selected").forEach(iconContainer => {
iconContainer.innerHTML = unselectedIcon;
iconContainer.className = "minitoc-icon-unselected";
});
});
}
displayLanguages();
// </nowiki>