From 2f457e4dad9778a06970765d243c91c94b04affc Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sun, 8 Apr 2018 19:07:53 +0100 Subject: [PATCH] Add ability to open and close major headings by clicking on them Former-commit-id: 13c75e59b6489e0dfe52baa7bb6dea73f3734fd7 [formerly 43eb7358f51e594d6581b07676fbb3ea8e6b6894] Former-commit-id: f2cf4bb735610cdd16f399a2afdd315150352d5d --- www/js/app.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/www/js/app.js b/www/js/app.js index 1df3d43a..593741dc 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -2114,6 +2114,76 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies', 'q', 'module' removePageMaxWidth(); setupTableOfContents(); + + // Attach listeners to headers to open-close following sections + var eles = ["H2", "H3"]; + for (var i = 0; i < eles.length; i++) { + // Process headers + var collection = articleContent.getElementsByTagName(eles[i]); + for (var j = 0; j < collection.length; j++) { + collection[j].classList.add("open-block"); + collection[j].addEventListener("click", function () { + var topTag = this.tagName; + this.classList.toggle("open-block"); + var nextElement = this.nextElementSibling; + if (!nextElement) nextElement = this.parentNode.nextElementSibling; + if (!nextElement) return; + // Decide toggle direction based on first sibling element + var toggleDirection = nextElement.style.display == "none" ? "block" : "none"; + var k = 0; + do { + if (nextElement) { + nextElement.style.display = toggleDirection; + if (!k) { //Only add or remove br for first element + if (nextElement.style.display == "none") { + this.innerHTML += "
"; + } else { + this.innerHTML = this.innerHTML.replace(/$/i, ""); + } + } + nextElement = nextElement.nextElementSibling; + } + k++; + } + while (nextElement && !~nextElement.tagName.indexOf(topTag) && !~nextElement.tagName.indexOf("H1")); + }); + } + } + // Process endnote references (so they open the reference block if closed) + function getClosest(el, fn) { + return el && (fn(el) ? el : getClosest(el.previousElementSibling, fn)) || + el && (fn(el) ? el : getClosest(el.parentNode, fn)); + } + var refs = articleContent.getElementsByClassName("mw-reflink-text"); + if (refs) { + for (var l = 0; l < refs.length; l++) { + var reference = refs[l].parentElement; + if (reference) { + reference.addEventListener("click", function (obj) { + var refID = obj.target.hash || obj.target.parentNode.hash; + if (!refID) return; + refID = refID.replace(/#/, ""); + var refLocation = articleContent.getElementById(refID); + var refHead = getClosest(refLocation, function (el) { + return el.tagName == "H2"; + }); + if (refHead) { + refHead.classList.add("open-block"); + refHead.innerHTML = refHead.innerHTML.replace(/$/i, ""); + var refNext = refHead.nextElementSibling; + do { + if (refNext) { + refNext.style.display = "block"; + refNext = refNext.nextElementSibling; + } + } + while (refNext && refNext.style.display == "none"); + } + }); + } + } + } + //Hide top-level scrolling -- gets rid of interfering useless scroll bar, but re-enable for Config and About pages document.getElementById('search-article').scrollTop = 0; document.getElementById('search-article').style.overflow = "hidden";