User:Surjection/streamline.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
/**
* make various non-definition headers collapsible boxes
*
* mw.loader.load('//en.wiktionary.org/w/index.php?title=User:Surjection/streamline.js&action=raw&ctype=text/javascript');
*
*/
makeNavFrame = function(heading, editLinks, toggleCat, contents) {
// now make a collapsible box
var navHead = document.createElement("div");
navHead.className = "NavHead";
navHead.style.cursor = "pointer";
var navContent = document.createElement("div");
navContent.className = "NavContent";
navContent.style.textAlign = "left";
// navContent.style.padding = "0 0.4em";
var navFrame = document.createElement("div");
navFrame.className = "NavFrame NavFrame-streamline";
if (toggleCat)
navFrame.setAttribute("data-toggle-category", toggleCat);
navFrame.style.display = "block";
navFrame.appendChild(navHead);
navFrame.appendChild(navContent);
navHead.appendChild(document.createTextNode(heading));
createNavToggle(navFrame);
if (editLinks) {
navContent.appendChild(editLinks);
editLinks.style.float = "right";
}
contents.forEach(function(ex) {
navContent.appendChild(ex);
});
return navFrame;
};
isNavFrameOpen = function(frame) {
var content = frame.querySelector(".NavContent");
return content ? window.getComputedStyle(content).style.display != "none" : false;
}
openNavFrame = function(frame) {
if (!isNavFrameOpen(frame)) {
frame.querySelector(".NavHead").click();
}
}
anchorInUrl = function(anchor) {
if (window.location.hash) {
return window.location.hash == anchor;
}
return false;
}
hasElementClass = function(element, className) {
if (element.classList)
return element.classList.contains(className);
return (" " + element.className + " ").indexOf(" " + className + " ") >= 0;
}
shouldEndCollapsible = function(element) {
return element.tagName.match(/^h[\dr]$/i) // end on heading or horizontal line
|| hasElementClass(element, "NavFrame-streamline") // no nested streamline navboxes
|| hasElementClass(element, "mw-heading") // Parsoid
}
shouldExcludeFromCollapsible = function(element) {
return hasElementClass(element, "thumb") // images
|| hasElementClass(element, "sister-project") // sister project box
|| hasElementClass(element, "kanji-table") // ja-kanjitab
|| hasElementClass(element, "floatright") // various tables
|| hasElementClass(element, "etymid") // etymid
|| hasElementClass(element, "template-anchor") // anchor
|| hasElementClass(element, "t-thumbs-outer") // thumbs
|| element.getAttribute("typeof") == "mw:File/Thumb" // new floating image boxes
|| hasElementClass(element, "mw-halign-right") // mw-halign-right, by new floating image boxes
|| element.getAttribute("align") == "right" // anything that (explicitly) aligns
|| element.style.float == "right" // anything that (explicitly) floats
}
shouldCollapseForTheSakeOf = function(element) {
if (element.nodeType == 1) {
if (element.tagName == "P" || element.tagName == "DIV" || element.tagName == "SPAN")
return Array.prototype.some.call(element.childNodes, shouldCollapseForTheSakeOf);
return element.tagName != "BR";
} else if (element.nodeType == 3) {
return !!element.textContent.trim(); // only if not entirely whitespace
} else {
return false;
}
}
getHeadingQuery = function(onlyL3) {
var head = ".ns-0 #mw-content-text ";
if (onlyL3) {
return head + "h2, " + head + "h3";
} else {
return head + "h2, " + head + "h3, " + head + "h4";
}
}
makeSingleCollapsible = function(heading, toggleCat, onlyL3) {
document.querySelectorAll(getHeadingQuery(onlyL3)).forEach(function(e) {
var headingId;
var hl = e.querySelector(".mw-headline");
if (hl && hl.textContent == heading) headingId = hl.id;
// Parsoid
if (hasElementClass(e.parentElement, "mw-heading") && e.textContent == heading) {
headingId = e.id;
e = e.parentElement;
}
if (!headingId) return;
// pick all elements until next heading
var contents = [];
var nx = e.nextElementSibling;
var collapse = false;
while (nx) {
if (shouldEndCollapsible(nx))
break;
if (!shouldExcludeFromCollapsible(nx)) {
contents.push(nx);
collapse = collapse || shouldCollapseForTheSakeOf(nx);
}
nx = nx.nextElementSibling;
}
if (!collapse) return;
navFrame = makeNavFrame(heading, e.querySelector(".mw-editsection"), toggleCat, contents);
navFrame.id = headingId;
e.parentNode.replaceChild(navFrame, e);
if (anchorInUrl(navFrame.id))
openNavFrame(navFrame);
});
};
makeNumberedCollapsible = function(heading, toggleCat) {
var re = new RegExp("^" + heading + " \\d+$");
document.querySelectorAll(getHeadingQuery(false)).forEach(function(e) {
var headingId;
var hl = e.querySelector(".mw-headline");
if (hl && hl.textContent.match(re)) headingId = hl.id;
// Parsoid
if (hasElementClass(e.parentElement, "mw-heading") && e.textContent.match(re)) {
headingId = e.id;
e = e.parentElement;
}
if (!headingId) return;
// pick all elements until next heading
var contents = [];
var nx = e.nextElementSibling;
var collapse = false;
while (nx) {
if (shouldEndCollapsible(nx))
break;
if (!shouldExcludeFromCollapsible(nx)) {
contents.push(nx);
collapse = collapse || shouldCollapseForTheSakeOf(nx);
}
nx = nx.nextElementSibling;
}
if (!collapse) return;
navFrame = makeNavFrame(heading, null, toggleCat, contents);
navFrame.id = headingId;
e.parentNode.insertBefore(navFrame, e.nextElementSibling);
if (anchorInUrl(navFrame.id))
openNavFrame(navFrame);
});
};
function moveAnagrams() {
// move the Anagrams box above Further reading and References
document.querySelectorAll(".NavFrame[data-toggle-category=\"anagrams\"]").forEach(function(e) {
var p = e.previousElementSibling;
while (p) {
if (p.tagName.toUpperCase() == "H2") {
break;
}
if (p.tagName.toUpperCase() == "H3") {
var hl = p.querySelector(".mw-headline");
if (hl && (hl.textContent == "Further reading" || hl.textContent == "References")) {
e.parentElement.insertBefore(e, p);
}
}
p = p.previousElementSibling;
}
});
}
function addGaps() {
// add gaps before streamline navboxes if preceded by certain elements
document.querySelectorAll(".NavFrame-streamline").forEach(function(sl) {
var prev = sl.previousElementSibling;
var next = sl.nextElementSibling;
var tn;
if (prev) {
tn = prev.tagName.toUpperCase();
if (tn == "OL" || tn == "UL") {
sl.style.marginTop = "1em";
}
}
if (next) {
tn = next.tagName.toUpperCase();
if (tn == "HR") {
sl.style.marginBottom = "1em";
}
}
});
}
function defaultStreamline() {
makeSingleCollapsible("Alternative forms", "alternative forms", true);
makeSingleCollapsible("Etymology", "etymology");
makeSingleCollapsible("Glyph origin", "etymology");
makeSingleCollapsible("Description", "description");
makeSingleCollapsible("Pronunciation", "pronunciations");
makeNumberedCollapsible("Etymology", "etymology");
makeNumberedCollapsible("Pronunciation", "pronunciations");
addGaps();
}
function superStreamline() {
makeSingleCollapsible("Alternative forms", "alternative forms", false);
makeSingleCollapsible("Inflection", "inflection");
makeSingleCollapsible("Declension", "inflection");
makeSingleCollapsible("Conjugation", "inflection");
makeSingleCollapsible("Mutation", "mutation");
makeSingleCollapsible("Synonyms", "synonyms");
makeSingleCollapsible("Antonyms", "antonyms");
makeSingleCollapsible("Hypernyms", "hypernyms");
makeSingleCollapsible("Hyponyms", "hyponyms");
makeSingleCollapsible("Meronyms", "meronyms");
makeSingleCollapsible("Holonyms", "holonyms");
makeSingleCollapsible("Troponyms", "troponyms");
makeSingleCollapsible("Coordinate terms", "coordinate terms");
makeSingleCollapsible("Derived terms", "derived terms");
makeSingleCollapsible("Compounds", "derived terms");
makeSingleCollapsible("Related terms", "related terms");
makeSingleCollapsible("Descendants", "descendants");
makeSingleCollapsible("See also", "related terms");
makeSingleCollapsible("Anagrams", "anagrams");
moveAnagrams();
addGaps();
}
mw.hook("wikipage.content").add(function($) {
if (createNavToggle) {
try {
defaultStreamline();
if (window.doSuperStreamline)
superStreamline();
} catch (e) {
console.error(e);
}
} else
console.warn("no createNavToggle, cannot create navboxes. cannot streamline")
});