From 8c33f07dc5393d0fa3ca8cf0fa72366781052a75 Mon Sep 17 00:00:00 2001 From: Penar Musaraj Date: Wed, 19 Jan 2022 17:17:30 -0500 Subject: [PATCH] FIX: Switch to a two-level sidebar list (#25) --- common/common.scss | 15 +-- .../discourse/initializers/disco-toc-main.js | 94 ++++++++++--------- 2 files changed, 49 insertions(+), 60 deletions(-) diff --git a/common/common.scss b/common/common.scss index ec2726a..60267fa 100644 --- a/common/common.scss +++ b/common/common.scss @@ -70,7 +70,6 @@ $padding-basis: 0.75em; // active line marker $selector: "> ul > li.direct-active > a:before"; -$sub: "> ul > li"; $map: ( "left": "html:not(.rtl)", "right": "html.rtl", @@ -91,21 +90,9 @@ html.rtl SELECTOR { #{$selector} { #{$prop}: (-$padding-basis); } - #{$sub} #{$selector} { + > ul > li #{$selector} { #{$prop}: (-$padding-basis) * 2; } - #{$sub} #{$sub} #{$selector} { - #{$prop}: (-$padding-basis) * 3; - } - #{$sub} #{$sub} #{$sub} #{$selector} { - #{$prop}: (-$padding-basis) * 4; - } - #{$sub} #{$sub} #{$sub} #{$sub} #{$selector} { - #{$prop}: (-$padding-basis) * 5; - } - #{$sub} #{$sub} #{$sub} #{$sub} #{$sub} #{$selector} { - #{$prop}: (-$padding-basis) * 6; - } } } // END active line marker diff --git a/javascripts/discourse/initializers/disco-toc-main.js b/javascripts/discourse/initializers/disco-toc-main.js index 9a20442..777dbd1 100644 --- a/javascripts/discourse/initializers/disco-toc-main.js +++ b/javascripts/discourse/initializers/disco-toc-main.js @@ -152,10 +152,7 @@ export default { document.querySelector(".d-toc-wrapper").appendChild(dToc); } - const startingLevel = parseInt(headings[0].tagName.substring(1), 10) - 1; - let result = document.createElement("div"); - result.setAttribute("id", "d-toc"); - buildTOC(headings, result, startingLevel || 1); + const result = this.buildTOC(Array.from(headings)); document.querySelector(".d-toc-main").appendChild(result); document.addEventListener("click", this.clickTOC, false); document.body.classList.add("d-toc-timeline-visible"); @@ -167,7 +164,10 @@ export default { } // link to each heading - if (e.target.hasAttribute("data-d-toc")) { + if ( + e.target.closest(".d-toc-item") && + e.target.hasAttribute("data-d-toc") + ) { const target = `#${e.target.getAttribute("data-d-toc")}`; const scrollTo = domUtils.offset( document.querySelector(`.d-toc-cooked ${target}`) @@ -214,61 +214,63 @@ export default { document.querySelector(".d-toc-wrapper").classList.remove("overlay"); } }, -}; -function buildTOC(nodesList, elm, lv = 1) { - let nodes = Array.from(nodesList); - node = nodes.shift(); + buildTOC(headings) { + const result = document.createElement("div"); + result.setAttribute("id", "d-toc"); - let node; - if (node) { - let li, cnt; - let curLv = parseInt(node.tagName.substring(1), 10); + const primaryH = headings[0].tagName; + const primaryHeadings = headings.filter((n) => n.tagName === primaryH); + let nextIndex = headings.length; - if (curLv === lv) { - // same level - cnt = 0; - } else if (curLv < lv) { - // walk up then append - cnt = 0; - do { - elm = elm.parentNode.parentNode; - cnt--; - } while (cnt > curLv - lv); - } else if (curLv > lv) { - // add children - cnt = 0; - do { - li = elm.lastChild; - if (li == null) { - elm = elm.appendChild(document.createElement("ul")); - } else { - elm = li.appendChild(document.createElement("ul")); + primaryHeadings.forEach((primaryHeading, index) => { + const ul = document.createElement("ul"); + ul.classList.add("d-toc-heading"); + + let li = this.buildItem(primaryHeading); + ul.appendChild(li); + + const currentIndex = headings.indexOf(primaryHeading); + if (primaryHeadings[index + 1]) { + nextIndex = headings.indexOf(primaryHeadings[index + 1]); + } else { + nextIndex = headings.length; + } + + headings.forEach((heading, subIndex) => { + if (subIndex > currentIndex && subIndex < nextIndex) { + let subUl = li.lastChild; + if (subUl.tagName !== "ul") { + subUl = subUl.appendChild(document.createElement("ul")); + subUl.classList.add("d-toc-sublevel"); + li.appendChild(subUl); + } + + let subLi = this.buildItem(heading); + subUl.appendChild(subLi); } - cnt++; - } while (cnt < curLv - lv); - } - if (curLv === 1 && elm.lastChild === null) { - elm = elm.appendChild(document.createElement("ul")); - } - // append list item + }); - li = elm.appendChild(document.createElement("li")); - li.classList.add("d-toc-item"); + result.appendChild(ul); + }); + return result; + }, + + buildItem(node) { let clonedNode = node.cloneNode(true); clonedNode.querySelector("span.clicks")?.remove(); + const li = document.createElement("li"); + li.classList.add("d-toc-item"); li.innerHTML = `${ clonedNode.textContent }`; clonedNode.remove(); - - // recurse - buildTOC(nodes, elm, lv + cnt); - } -} + return li; + }, +}; function parentsUntil(el, selector, filter) { const result = [];