🐛 fix(vscode): 代码阅读预览跳到定义后页面还在长高(注释里的 mermaid 画成图、中文名到了)不再把视口带跑:页面滚动统一交给滚动所有者,跟住跳到的目标、用户自己滚了改钉视口顶部那块,关掉浏览器自带的滚动锚定

This commit is contained in:
cruldra committed 2026-10-14 06:11:25 +11:00
1 parent 2fa6319dd4
commit 3c5f5f5f35
24 files changed
+1016 -149

No files matched your search

@@ -1,6 +1,7 @@
import type { DocumentMessage } from './types'
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
import { pageLayout } from './pageLayout'
import { scrollOwner } from './scrollOwner'
import { postMessage, viewState } from './vscode'
/** 滚动时最多这么久记一次位置 */
@@ -38,7 +39,8 @@ function record(reportedLine: { current: number | undefined }): void {
/**
* 记住并恢复预览看到的位置:
* ① 滚动时把视口顶部那块记进 webview 状态,页面重新加载后(VS Code 重启后恢复标签页、webview 进程崩了重建)照着滚回去;
* ① 滚动时([scrollOwner] 转来的滚动事件)把视口顶部那块记进 webview 状态,页面重新加载后(VS Code 重启后恢复标签页、webview 进程崩了重建)
* 交给 [scrollOwner] 滚回去、钉住那块,之后注释里的图画出来、中文名到了也不跑;
* ② 同时把那块的起始行报给扩展端,切回文本编辑器时把这行放到顶部。
* 第一份文档带 reveal(刚从文本编辑器切过来、跳到定义)时不恢复,交给 useReveal 滚。
* 块的位置从 pageLayout 取:滚动时用量过的,不每次量全部卡片。
@@ -54,21 +56,20 @@ export function useScrollPosition(doc: DocumentMessage | null): void {
restored.current = true
const saved = viewState.get().scroll
if (doc.reveal === undefined && saved)
window.scrollTo(0, pageLayout.topFor(saved) - pageLayout.pinnedHeight())
scrollOwner.align(saved)
record(reportedLine)
}, [doc])
useEffect(() => {
let timer: number | undefined
const onScroll = (): void => {
const off = scrollOwner.onScroll(() => {
timer ??= window.setTimeout(() => {
timer = undefined
record(reportedLine)
}, RECORD_INTERVAL_MS)
}
window.addEventListener('scroll', onScroll, { passive: true })
})
return () => {
window.removeEventListener('scroll', onScroll)
off()
window.clearTimeout(timer)
}
}, [])