🐛 fix(vscode): 代码阅读的钉住卡片改成每张卡片都算一层,折叠着、没有子块的高卡片滚到一半也钉在顶上

This commit is contained in:
cruldra committed 2026-10-08 07:17:26 +08:00
1 parent a53a5d4504
commit a1fbefd3aa
14 files changed
+45 -34

No files matched your search

@@ -22,8 +22,12 @@ function limitOf(maxLineCount: number): number {
return lineLimit(window.innerHeight - pinnedHeight(), STICKY_LINE_HEIGHT, maxLineCount)
}
/** root 里能钉住的卡片:画出了子层的那些(子层带 data-owner,挂在子行上的子块那层在卡片里面),按页面先后;竖直坐标以筛选栏下沿为 0 */
function measureScopes(root: HTMLElement): StickyScope[] {
/**
* root 里能钉住的卡片,按页面先后,竖直坐标以筛选栏下沿为 0:画出来了、不在编辑的每一张(BlockCard 带 data-line;删掉的块那张没有),
* 折叠着的、没有子块的也算,卡片自己就是一层。下沿算到它画出来的子块的最后(它名下的子层带 data-owner,挂在子行上的子块那层在卡片里面)。
* 只留可能钉住的:上沿在钉住的那几行(高 band)以内或更高、下沿还在筛选栏下沿以下
*/
function measureScopes(root: HTMLElement, band: number): StickyScope[] {
const bottoms = new Map<string, number>()
for (const level of root.querySelectorAll<HTMLElement>('.cr-level[data-owner]')) {
const owner = level.dataset.owner ?? ''
@@ -31,13 +35,13 @@ function measureScopes(root: HTMLElement): StickyScope[] {
}
const base = pinnedHeight()
const scopes: StickyScope[] = []
for (const card of root.querySelectorAll<HTMLElement>('.cr-block[data-id]')) {
for (const card of root.querySelectorAll<HTMLElement>('.cr-block[data-line]:not([data-editing])')) {
const id = card.dataset.id ?? ''
const levelBottom = bottoms.get(id)
if (levelBottom === undefined)
continue
const rect = card.getBoundingClientRect()
scopes.push({ id, depth: depthOf(card), top: rect.top - base, bottom: Math.max(rect.bottom, levelBottom) - base, left: rect.left, right: rect.right })
const top = rect.top - base
const bottom = Math.max(rect.bottom, bottoms.get(id) ?? rect.bottom) - base
if (top < band && bottom >= 0)
scopes.push({ id, depth: depthOf(card), top, bottom, left: rect.left, right: rect.right })
}
return scopes
}
@@ -65,7 +69,8 @@ export function useStickyLines(content: RefObject<HTMLElement | null>, maxLineCo
const update = (): void => {
frame = 0
const root = content.current
const next = root ? pinnedLines(measureScopes(root), STICKY_LINE_HEIGHT, limitOf(maxLineCount)) : NO_PINNED
const limit = limitOf(maxLineCount)
const next = root ? pinnedLines(measureScopes(root, limit * STICKY_LINE_HEIGHT), STICKY_LINE_HEIGHT, limit) : NO_PINNED
setLines(prev => samePinned(prev, next) ? prev : next)
}
schedule.current = () => {