toc = (title='Table of Contents', selector='h1,h2,h3') => {
return Generators.observe(notify => {
let old = [];
const level = (h) => parseInt(h.tagName[1], 10);
const observed = () => {
const now = Array.from(document.querySelectorAll(selector));
if ( !(now.length !== old.length || now.some((h, i) => h !== old[i])) ) return;
const header = (title && title.length > 0) ? `<b>${title}</b>` : '';
const list = (old = now).map(h => Object.assign(
html`${'<ul>'.repeat(level(h)-1)}<li><a href=#${h.id}>${DOM.text(h.textContent)}`,
{onclick: e => (e.preventDefault(), h.scrollIntoView())}
));
notify(html`${header}<ul>${list}`);
};
observed();
const observer = new MutationObserver(observed);
observer.observe(document.body, {childList: true, subtree: true});
return () => observer.disconnect();
});
}