function toc(selector = "h1,h2,h3", title = "Table of Contents") {
return Generators.observe(notify => {
let previousHeadings = [];
function observed() {
const currentHeadings = Array.from(document.querySelectorAll(selector));
if (
currentHeadings.length !== previousHeadings.length ||
currentHeadings.some((h, i) => previousHeadings[i] !== h)
) {
let currentIndentation;
let startIndentation;
previousHeadings = currentHeadings;
const entries = [];
for (const h of Array.from(previousHeadings)) {
let nodeIndentiation = parseInt(h.tagName[1], 10);
if (typeof currentIndentation === 'undefined') {
currentIndentation = startIndentation = nodeIndentiation;
} else {
while (currentIndentation < nodeIndentiation) {
entries.push('<ul>');
currentIndentation++;
}
while (currentIndentation > nodeIndentiation) {
entries.push('</ul>');
currentIndentation--;
}
}
entries.push(
Object.assign(
html`<li><a href=#${h.id}>${DOM.text(h.textContent)}`,
{ onclick: e => (e.preventDefault(), h.scrollIntoView()) }
)
);
}
while (currentIndentation > startIndentation) {
entries.push('</ul>');
currentIndentation--;
}
const content = html`<b>${title}</b><ul>${entries}`;
console.log(content);
notify(content);
}
}
const observer = new MutationObserver(observed);
observer.observe(document.body, { childList: true, subtree: true });
observed();
return () => observer.disconnect();
});
}