Last active
August 31, 2022 14:18
-
-
Save thedamon/17e049e33014709f96186520768f5a5b to your computer and use it in GitHub Desktop.
returns the header of the section containing a given element
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function getSectionHeader(element, headerDepth = 6){ | |
const headerSelector = Array(headerDepth).fill().map((i,idx) => `h${idx+1}`).join(','); | |
console.log(headerSelector); | |
if (element.matches(headerSelector)) { | |
return element; | |
} | |
const tempAttr = 'data-getSectionInTitleElement'; | |
element.setAttribute(tempAttr, ""); | |
const els = document.querySelectorAll(`${headerSelector},[${tempAttr}]`); | |
let headerIndex; | |
Array.from(els).some((el, idx)=>{ | |
if (el.matches(`[${tempAttr}]`)){ | |
headerIndex = idx - 1; | |
return true; | |
} | |
return false; | |
}); | |
const headerEl = els.item(headerIndex); | |
element.removeAttribute(tempAttr); | |
return headerEl; | |
} | |
function getSectionTitle(element){ | |
const header = getSectionHeader(element); | |
if (header) return header.textContent; | |
return document.title; | |
} | |
function getSections(element){ | |
let sections = ''; | |
let header = getSectionHeader(element); | |
if (header){ | |
let maxLevel = Number(header.tagName.substr(1)) | |
sections = `${maxLevel}.${header.textContent}`; | |
let currentLevel = maxLevel - 1 | |
while (currentLevel){ | |
header = getSectionHeader(element, currentLevel); | |
if (header){ | |
sections = `${currentLevel}.${header.textContent} - ${sections}` | |
} | |
currentLevel --; | |
} | |
} | |
return sections || document.title; | |
} | |
function findPrecedingMatch(el, selector){ | |
const siblingMatch = (el, selector) => { | |
while (el) { | |
el = el.previousElementSibling; | |
if (!el || el.matches(selector)) return el | |
} | |
} | |
const matchingSib = siblingMatch(el, selector); | |
if (matchingSib) return matchingSib; | |
// level up. | |
const nextContentParent = (el) => { | |
let parent = el.parentElement; | |
while (parent){ | |
if (parent.children.length > 1) return parent; | |
parent = parent.parentElement; | |
} | |
} | |
let levelEl = nextContentParent(el); | |
while(levelEl){ | |
let currentEl = levelEl; | |
while(currentEl){ | |
let matches = currentEl.querySelectorAll(selector); | |
if (matches.length){ | |
return matches[matches.length - 1] | |
}; | |
currentEl = currentEl.previousElementSibling; | |
} | |
levelEl = nextContentParent(levelEl); | |
} | |
return null; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment