mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-10 15:39:01 +00:00
feat: show scroll progress in outliner #834, fix: jump to headings in columns
This commit is contained in:
parent
d156d810ba
commit
f32cf56a67
@ -11,8 +11,8 @@ function Heading({ indent, ...props }, ...children) {
|
|||||||
const { html } = globalThis.__enhancerApi;
|
const { html } = globalThis.__enhancerApi;
|
||||||
return html`<div
|
return html`<div
|
||||||
role="button"
|
role="button"
|
||||||
class="notion-enhancer--outliner-heading
|
class="notion-enhancer--outliner-heading block
|
||||||
block cursor-pointer select-none text-[14px]
|
relative cursor-pointer select-none text-[14px]
|
||||||
decoration-(2 [color:var(--theme--fg-border)])
|
decoration-(2 [color:var(--theme--fg-border)])
|
||||||
hover:bg-[color:var(--theme--bg-hover)]
|
hover:bg-[color:var(--theme--bg-hover)]
|
||||||
py-[6px] pr-[2px] pl-[${indent * 18}px]
|
py-[6px] pr-[2px] pl-[${indent * 18}px]
|
||||||
@ -60,13 +60,7 @@ export default async (api, db) => {
|
|||||||
</section>`,
|
</section>`,
|
||||||
});
|
});
|
||||||
|
|
||||||
let $page;
|
let $page, $scroller;
|
||||||
const updatePage = () => {
|
|
||||||
if (document.contains($page)) return;
|
|
||||||
$page = document.querySelector(page);
|
|
||||||
updateHeadings();
|
|
||||||
};
|
|
||||||
|
|
||||||
const getHeadings = () => {
|
const getHeadings = () => {
|
||||||
return [...$page.querySelectorAll(headings.join(", "))];
|
return [...$page.querySelectorAll(headings.join(", "))];
|
||||||
},
|
},
|
||||||
@ -87,24 +81,57 @@ export default async (api, db) => {
|
|||||||
}
|
}
|
||||||
return title;
|
return title;
|
||||||
},
|
},
|
||||||
|
getBlockOffset = ($block) => {
|
||||||
|
let offset = 0;
|
||||||
|
while (!$block.matches("[data-content-editable-root]")) {
|
||||||
|
offset += $block.offsetTop;
|
||||||
|
$block = $block.offsetParent;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
},
|
||||||
updateHeadings = debounce(() => {
|
updateHeadings = debounce(() => {
|
||||||
$toc.innerHTML = "";
|
$toc.innerHTML = "";
|
||||||
if (!$page) return;
|
if (!$page) return;
|
||||||
const $frag = document.createDocumentFragment();
|
const $frag = document.createDocumentFragment();
|
||||||
for (const $heading of getHeadings()) {
|
for (const $heading of getHeadings()) {
|
||||||
const $h = html`<${Heading}
|
$heading._$outline = html`<${Heading}
|
||||||
indent=${getHeadingLevel($heading)}
|
indent=${getHeadingLevel($heading)}
|
||||||
onclick=${() => {
|
onclick=${() => {
|
||||||
const $scroller = document.querySelector(scroller);
|
$scroller.scrollTo({
|
||||||
$scroller.scrollTo({ top: $heading.offsetTop - 24, behavior });
|
top: getBlockOffset($heading) - 24,
|
||||||
}}>${getHeadingTitle($heading)}</p>`;
|
behavior,
|
||||||
$frag.append($h);
|
});
|
||||||
|
}}
|
||||||
|
>${getHeadingTitle($heading)}
|
||||||
|
<//>`;
|
||||||
|
$frag.append($heading._$outline);
|
||||||
}
|
}
|
||||||
$toc.append($frag);
|
$toc.append($frag);
|
||||||
|
onScroll();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const $progressMarker = html`<span
|
||||||
|
class="absolute block left-[6px] top-[calc(50%-1px)]
|
||||||
|
size-[6px] rounded-full bg-[color:var(--theme--fg-secondary)]"
|
||||||
|
></span>`,
|
||||||
|
onScroll = () => {
|
||||||
|
const $h = getHeadings().find(($h) => {
|
||||||
|
return $scroller.scrollTop < getBlockOffset($h) - 16;
|
||||||
|
})?._$outline;
|
||||||
|
if ($h) $h.prepend($progressMarker);
|
||||||
|
},
|
||||||
|
setup = () => {
|
||||||
|
if (document.contains($page)) return;
|
||||||
|
$page = document.querySelector(page);
|
||||||
|
console.log($page);
|
||||||
|
$scroller = document.querySelector(scroller);
|
||||||
|
$scroller?.removeEventListener("scroll", onScroll);
|
||||||
|
$scroller?.addEventListener("scroll", onScroll);
|
||||||
|
updateHeadings();
|
||||||
|
};
|
||||||
|
|
||||||
const semanticHeadings = '[class$="header-block"] :is(h2, h3, h4)';
|
const semanticHeadings = '[class$="header-block"] :is(h2, h3, h4)';
|
||||||
addMutationListener(`${page} ${semanticHeadings}`, updateHeadings);
|
addMutationListener(`${page} ${semanticHeadings}`, updateHeadings);
|
||||||
addMutationListener(`${page}, ${scroller}`, updatePage, false);
|
addMutationListener(`${page}, ${scroller}`, setup, false);
|
||||||
updatePage();
|
setup();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user