| 1 | export type ListReadAnchor = { scroller: HTMLElement; row: HTMLElement; key: string; top: number; scrollTop: number }; |
| 2 | |
| 3 | export function captureListReadAnchor(root: HTMLElement | null): ListReadAnchor | undefined { |
| 4 | if (!root) return; |
| 5 | let scroller: HTMLElement | null = root.querySelector(".project-tree__list") ?? root; |
| 6 | while (scroller && !(scroller.scrollHeight > scroller.clientHeight && /(auto|scroll)/.test(getComputedStyle(scroller).overflowY))) scroller = scroller.parentElement; |
| 7 | if (!scroller) return; |
| 8 | const bounds = scroller.getBoundingClientRect(); |
| 9 | const row = Array.from(root.querySelectorAll<HTMLElement>("[data-topic-open-key]")).find((row) => { |
| 10 | const box = row.getBoundingClientRect(); return box.bottom > bounds.top && box.top < bounds.bottom; |
| 11 | }); |
| 12 | if (row) return { scroller, row, key: row.dataset.topicOpenKey ?? "", top: row.getBoundingClientRect().top, scrollTop: scroller.scrollTop }; |
| 13 | } |
| 14 | |
| 15 | export function restoreListReadAnchor(root: HTMLElement | null, anchor?: ListReadAnchor): void { |
| 16 | if (!root || !anchor || !anchor.scroller.isConnected || anchor.scroller.scrollTop !== anchor.scrollTop) return; |
| 17 | const row = anchor.row.isConnected ? anchor.row : Array.from(root.querySelectorAll<HTMLElement>("[data-topic-open-key]")).find((row) => row.dataset.topicOpenKey === anchor.key); |
| 18 | if (row) anchor.scroller.scrollTop += row.getBoundingClientRect().top - anchor.top; |
| 19 | } |
| 20 |