fix(sidebar): add correct node identity to heading set
This commit is contained in:
parent
574d17f201
commit
ef7295ff7a
|
|
@ -35,29 +35,14 @@ const SidebarContent: Component<SidebarContentProps> = (props) => {
|
||||||
props.pathHeadings[pathname] || props.pathHeadings[`${pathname}.md`] || []
|
props.pathHeadings[pathname] || props.pathHeadings[`${pathname}.md`] || []
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
const revealedHeadings = createMemo(() => {
|
|
||||||
const pathname = decodeURIComponent(location.pathname);
|
|
||||||
const set = new Set<string>();
|
|
||||||
function traverse(node: TocNode, cb: (node: TocNode) => void) {
|
|
||||||
cb(node);
|
|
||||||
node.children?.forEach((child) => traverse(child, cb));
|
|
||||||
}
|
|
||||||
for (const node of currentFileHeadings()) {
|
|
||||||
traverse(node, (anode) => {
|
|
||||||
if (isPathRevealed(pathname, anode.id ?? anode.title)) {
|
|
||||||
traverse(anode, (each) => set.add(anode.id ?? anode.title));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return set;
|
|
||||||
});
|
|
||||||
const isFileHidden = (node: FileNode): boolean => {
|
const isFileHidden = (node: FileNode): boolean => {
|
||||||
if (isPathRevealed(node.path)) return false;
|
if (isPathRevealed(node.path)) return false;
|
||||||
if (node.children?.some((child) => !isFileHidden(child))) return false;
|
if (node.children?.some((child) => !isFileHidden(child))) return false;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
const isHeadingHidden = (node: TocNode): boolean => {
|
const isHeadingHidden = (node: TocNode): boolean => {
|
||||||
if (revealedHeadings().has(node.id ?? node.title)) return false;
|
const pathname = decodeURIComponent(location.pathname);
|
||||||
|
if (isPathRevealed(pathname, node.id ?? node.title)) return false;
|
||||||
if (node.children?.some((child) => !isHeadingHidden(child))) return false;
|
if (node.children?.some((child) => !isHeadingHidden(child))) return false;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -676,11 +676,26 @@ export function addRevealedClasses(root: HTMLDivElement, path: string) {
|
||||||
};
|
};
|
||||||
for (const child of root.children) collect(child);
|
for (const child of root.children) collect(child);
|
||||||
|
|
||||||
// ---- Cascade: if a heading is revealed, its parents are too ----
|
// ---- Cascade: directly revealed headings propagate ----
|
||||||
const revealedSet = new Set<string>();
|
// 1. directly revealed headings
|
||||||
|
const revealedSet = new Set<string>(revealed);
|
||||||
|
|
||||||
|
// 2. Downward: all children of directly revealed headings
|
||||||
|
// let changed = true;
|
||||||
|
// while (changed) {
|
||||||
|
// changed = false;
|
||||||
|
// for (const h of headings) {
|
||||||
|
// if (revealedSet.has(h.text)) continue;
|
||||||
|
// if (h.parents.some((p) => revealedSet.has(p))) {
|
||||||
|
// revealedSet.add(h.text);
|
||||||
|
// changed = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 3. Upward: all parents of directly revealed headings
|
||||||
for (const h of headings) {
|
for (const h of headings) {
|
||||||
if (revealed.has(h.text) || revealedSet.has(h.text)) {
|
if (revealed.has(h.text)) {
|
||||||
revealedSet.add(h.text);
|
|
||||||
for (const p of h.parents) revealedSet.add(p);
|
for (const p of h.parents) revealedSet.add(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue