🐛 fix(vscode): 代码阅读预览跳到还没打开的文件时停在文件顶上不再发生:新开的预览注释里有仓库图片时,问图片才把仓库根加进 webview 能读的目录,改了选项 VS Code 重新加载页面,第二次 ready 发的文档不带要滚到的那处;页面能读的目录(页面资源、问答图片、这一页仓库链接的各个根及其真实位置)改在装页面之前一次定好,之后不再改选项,LinkBase 带上它算得出的根
This commit is contained in:
1 parent
95fc539c3a
commit
ad35898716
3 files changed
+66
-35
No files matched your search
@@ -149,22 +149,41 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
|
||||
[...this.previews].find(p => p.uri.toString() === key && p.active)?.reopen(request)
|
||||
}
|
||||
|
||||
resolveCustomTextEditor(document: TextDocument, panel: WebviewPanel): void {
|
||||
// 问答带的图片(工作区文件夹的 .spx/code-qa/)也要能读,历史里才画得出缩略图
|
||||
const imageRoot = this.qa.imageRoot(topSubjectOf(document.uri).uri)
|
||||
panel.webview.options = { enableScripts: true, localResourceRoots: [webviewUiRoot(this.extensionUri), ...(imageRoot ? [imageRoot] : [])] }
|
||||
panel.webview.html = webviewHtml(panel.webview, this.extensionUri, 'code-reader.html')
|
||||
/**
|
||||
* 新开一个预览:先接下给它的打开请求、接上消息,再装页面。页面能读的本地目录(见 [readableRoots])装之前一次定好,之后不再改:
|
||||
* 改了 webview 的选项 VS Code 会重新加载页面,打开时要滚到的那处就丢了。
|
||||
*/
|
||||
async resolveCustomTextEditor(document: TextDocument, panel: WebviewPanel): Promise<void> {
|
||||
const key = document.uri.toString()
|
||||
const request = this.requests.get(key)
|
||||
this.requests.delete(key)
|
||||
const preview = new Preview(document, panel, this, this.registry, this.runtime, this.filter, request)
|
||||
this.previews.add(preview)
|
||||
let disposed = false
|
||||
panel.onDidDispose(() => {
|
||||
disposed = true
|
||||
this.previews.delete(preview)
|
||||
this.navigation.update(preview, false)
|
||||
this.finding.update(preview, false)
|
||||
preview.dispose()
|
||||
})
|
||||
const roots = await this.readableRoots(document.uri)
|
||||
// 找目录的工夫标签页已经关了
|
||||
if (disposed)
|
||||
return
|
||||
panel.webview.options = { enableScripts: true, localResourceRoots: roots }
|
||||
panel.webview.html = webviewHtml(panel.webview, this.extensionUri, 'code-reader.html')
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览页面能读的本地目录:页面自己的脚本和样式;问答带的图片所在的目录(工作区文件夹的 .spx/code-qa/),历史里才画得出缩略图;
|
||||
* 注释、回答里的仓库图片所在的各个根(见 [linkBaseOf]),根的真实位置和这个路径不一样时两个都放,读不到真实位置就只放这个路径。
|
||||
*/
|
||||
private async readableRoots(uri: Uri): Promise<Uri[]> {
|
||||
const imageRoot = this.qa.imageRoot(topSubjectOf(uri).uri)
|
||||
const { roots } = await linkBaseOf(uri)
|
||||
const repoRoots = await Promise.all(roots.map(async root => [root, await realpath(root).catch(() => root)]))
|
||||
return [webviewUiRoot(this.extensionUri), ...(imageRoot ? [imageRoot] : []), ...[...new Set(repoRoots.flat())].map(root => Uri.file(root))]
|
||||
}
|
||||
|
||||
/** 「跳到下一处 / 上一处高亮」:发给能跳的那个预览,从命令面板运行时发给活动的预览。 */
|
||||
@@ -967,35 +986,13 @@ class Preview {
|
||||
})
|
||||
}
|
||||
|
||||
/** 仓库根放进这个预览能读的本地目录,图片地址才能加载。真实位置和 git 给的路径不一样时两个都放。 */
|
||||
private addLocalRoot(fsPath: string): void {
|
||||
const uri = Uri.file(fsPath)
|
||||
const roots = this.panel.webview.options.localResourceRoots ?? []
|
||||
if (roots.some(root => root.fsPath === uri.fsPath))
|
||||
return
|
||||
this.panel.webview.options = { ...this.panel.webview.options, localResourceRoots: [...roots, uri] }
|
||||
}
|
||||
|
||||
private async allowRepoRoot(root: string): Promise<void> {
|
||||
this.addLocalRoot(root)
|
||||
try {
|
||||
const real = await realpath(root)
|
||||
if (real !== root)
|
||||
this.addLocalRoot(real)
|
||||
}
|
||||
catch {
|
||||
// 仓库根这会儿读不到真实位置,就按 git 给的路径放行
|
||||
}
|
||||
}
|
||||
|
||||
/** 这批仓库图片哪些在。在的带回预览里能直接用的地址;不在、不是图片、跑出仓库的没有地址。 */
|
||||
private async checkRepoImages(id: number, paths: string[]): Promise<void> {
|
||||
const base = await linkBaseOf(this.document.uri)
|
||||
const images = await Promise.all(paths.map(async (rel) => {
|
||||
const place = isRepoImagePath(rel) ? base(rel) : undefined
|
||||
const place = isRepoImagePath(rel) ? base.place(rel) : undefined
|
||||
if (!place)
|
||||
return { path: rel }
|
||||
await this.allowRepoRoot(place.root)
|
||||
const entry = await resolveRepoEntry(place.root, place.rel)
|
||||
if (!entry || entry.isDirectory)
|
||||
return { path: rel }
|
||||
@@ -1164,7 +1161,7 @@ class Preview {
|
||||
|
||||
/** 一条仓库链接指到磁盘上的哪个文件或目录,路径按这一页的算法算(见 [linkBaseOf]);算不出来、不在、跑出根的没有。 */
|
||||
async function linkEntry(base: LinkBase, rel: string): Promise<RepoEntry | undefined> {
|
||||
const place = base(rel)
|
||||
const place = base.place(rel)
|
||||
return place && resolveRepoEntry(place.root, place.rel)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user