/* * notion-enhancer: outliner * (c) 2020 CloudHill (https://github.com/CloudHill) * (c) 2021 dragonwocky (https://dragonwocky.me/) * (https://notion-enhancer.github.io/) under the MIT license */ export default async function ({ web, components }, db) { const dbNoticeText = 'Open a page to see its table of contents.', pageNoticeText = 'Click on a heading to jump to it.', $notice = web.html`

${dbNoticeText}

`; const $headingList = web.html`
`; let viewFocused = false, $page; await components.addPanelView({ id: '87e077cc-5402-451c-ac70-27cc4ae65546', icon: web.html` `, title: 'Outliner', $content: web.render(web.html`
`, $notice, $headingList), onFocus: () => { viewFocused = true; updateHeadings(); }, onBlur: () => { viewFocused = false; }, }); await web.whenReady(); function updateHeadings() { if (!$page) return; const $headerBlocks = $page.querySelectorAll('[class^="notion-"][class*="header-block"]'), $fragment = web.html`
`; let depth = 0, indent = 0; for (const $header of $headerBlocks) { const id = $header.dataset.blockId.replace(/-/g, ''), placeholder = $header.querySelector('[placeholder]').getAttribute('placeholder'), headerDepth = +placeholder.at(-1); if (depth && depth < headerDepth) { indent += 18; } else if (depth > headerDepth) { indent = Math.max(indent - 18, 0); } depth = headerDepth; const $outlineHeader = web.render( web.html``, $header.innerText ); $outlineHeader.addEventListener('click', (event) => { location.hash = ''; }); $fragment.append($outlineHeader); } if ($fragment.innerHTML !== $headingList.innerHTML) { web.render(web.empty($headingList), ...$fragment.children); } } const pageObserver = () => { if (!viewFocused) return; if (document.contains($page)) { updateHeadings(); } else { $page = document.getElementsByClassName('notion-page-content')[0]; if ($page) { $notice.innerText = pageNoticeText; $headingList.style.display = ''; updateHeadings(); } else { $notice.innerText = dbNoticeText; $headingList.style.display = 'none'; } } }; web.addDocumentObserver(pageObserver, [ '.notion-header-block', '.notion-sub_header-block', '.notion-sub_sub_header-block', '.notion-collection_view_page-block', ]); pageObserver(); }