function toc({
selector = "h1,h2,h3",
heading = "<b>Table of Contents</b>",
ignoreFirst = false
} = {}) {
return Generators.observe((notify) => {
let headings = [];
const type = "<ul>";
function observed() {
const h = Array.from(document.querySelectorAll(selector));
if (ignoreFirst) h.shift();
if (
h.length !== headings.length ||
h.some((h, i) => headings.at(i) !== h)
) {
notify(
html`${heading}${type.repeat(1)}${Array.from((headings = h), (h) => {
const headingType = {
H1: () =>
html`${type.repeat(0)}<li><a style="" href=#${h.id}>${DOM.text(
h.textContent
)}</li>`,
H2: () =>
html`${type.repeat(1)}<li><a style="" href=#${h.id}>${DOM.text(
h.textContent
)}`,
H3: () =>
html`${type.repeat(2)}<li><a style="" href=#${h.id}>${DOM.text(
h.textContent
)}`,
H4: () =>
html`${type.repeat(3)}<li><a style="" href=#${h.id}>${DOM.text(
h.textContent
)}`,
H5: () =>
html`${type.repeat(4)}<li><a style="" href=#${h.id}>${DOM.text(
h.textContent
)}`,
H6: () =>
html`${type.repeat(5)}<li><a style="" href=#${h.id}>${DOM.text(
h.textContent
)}`
};
return Object.assign(headingType[h.tagName](), {
onclick: (e) => (e.preventDefault(), h.scrollIntoView())
});
})}`
);
}
}
const observer = new MutationObserver(observed);
observer.observe(document.body, { childList: true, subtree: true });
observed();
return () => observer.disconnect();
});
}