⚡ perf(vscode): 预览切走标签页时页面留着,切回来不再重新生成、重发文档和整份重画
This commit is contained in:
1 parent
53283808a0
commit
5426c50cd9
8 files changed
+118
-59
No files matched your search
@@ -6,16 +6,17 @@ import type { SymbolNode } from '../symbolLinks'
|
||||
import type { CodeColors } from '../theme/codeColors'
|
||||
import type { ExtensionToWebview, WebviewToExtension } from './messages'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { window, workspace } from 'vscode'
|
||||
import { commands, window, workspace } from 'vscode'
|
||||
import { documentMessage } from './documentMessage'
|
||||
import { documentSymbolNodes } from './documentSymbols'
|
||||
import { PreviewEditorProvider } from './previewEditor'
|
||||
import { OCCURRENCES_CONTEXT } from './occurrenceNavigation'
|
||||
import { PREVIEW_VIEW_TYPE, PreviewEditorProvider } from './previewEditor'
|
||||
|
||||
vi.mock('vscode', () => ({
|
||||
commands: { executeCommand: vi.fn() },
|
||||
window: { showErrorMessage: vi.fn() },
|
||||
window: { showErrorMessage: vi.fn(), registerCustomEditorProvider: vi.fn() },
|
||||
workspace: {
|
||||
onDidChangeTextDocument: () => ({ dispose: () => {} }),
|
||||
onDidChangeTextDocument: vi.fn(() => ({ dispose: () => {} })),
|
||||
onDidChangeConfiguration: () => ({ dispose: () => {} }),
|
||||
getConfiguration: () => ({ get: (_key: string, fallback: unknown) => fallback }),
|
||||
openTextDocument: vi.fn(),
|
||||
@@ -214,10 +215,10 @@ function opening(profiles = { ask: profileSet(''), rewrite: profileSet('') }, co
|
||||
return { provider, document, diffBase }
|
||||
}
|
||||
|
||||
/** 一个标签页:收发消息、切走(页面被销毁,切回来重新加载、再发 ready) */
|
||||
/** 一个标签页:收发消息;切走、切回来时页面留着,VS Code 只报一声可见性变了 */
|
||||
function tab() {
|
||||
let receive: ((message: WebviewToExtension) => Promise<void>) | undefined
|
||||
let viewStateChanged: (() => void) | undefined
|
||||
const viewStateListeners: (() => void)[] = []
|
||||
const post = vi.fn<(message: ExtensionToWebview) => void>()
|
||||
const panel = {
|
||||
active: true,
|
||||
@@ -231,20 +232,22 @@ function tab() {
|
||||
return { dispose: () => {} }
|
||||
},
|
||||
},
|
||||
onDidChangeViewState: (listener: typeof viewStateChanged) => {
|
||||
viewStateChanged = listener
|
||||
onDidChangeViewState: (listener: () => void) => {
|
||||
viewStateListeners.push(listener)
|
||||
return { dispose: () => {} }
|
||||
},
|
||||
onDidDispose: () => ({ dispose: () => {} }),
|
||||
}
|
||||
const setVisible = (visible: boolean): void => {
|
||||
panel.visible = visible
|
||||
panel.active = visible
|
||||
viewStateListeners.forEach(listener => listener())
|
||||
}
|
||||
return {
|
||||
panel: panel as unknown as Parameters<PreviewEditorProvider['resolveCustomTextEditor']>[1],
|
||||
send: (message: WebviewToExtension) => receive!(message),
|
||||
hide: () => {
|
||||
panel.visible = false
|
||||
viewStateChanged!()
|
||||
panel.visible = true
|
||||
},
|
||||
hide: () => setVisible(false),
|
||||
show: () => setVisible(true),
|
||||
posted: () => post.mock.calls.map(([message]) => message),
|
||||
clear: () => post.mockClear(),
|
||||
}
|
||||
@@ -284,7 +287,7 @@ describe('预览对比什么看这个标签页是从哪儿打开的', () => {
|
||||
expect(diffBase).not.toHaveBeenCalledWith(document.uri, 'uncommitted')
|
||||
})
|
||||
|
||||
it('开着的预览再从主栏点开就不比,再从「未提交的更改」点开又比;只切标签页不变', async () => {
|
||||
it('开着的预览再从主栏点开就不比,再从「未提交的更改」点开又比;页面重新加载后按它记着的照旧比', async () => {
|
||||
const { provider, document } = opening()
|
||||
const page = tab()
|
||||
await provider.open(document.uri as never, { from: 'uncommitted' }, async () => provider.resolveCustomTextEditor(document as never, page.panel))
|
||||
@@ -301,7 +304,6 @@ describe('预览对比什么看这个标签页是从哪儿打开的', () => {
|
||||
expect(page.posted()).toContainEqual({ type: 'openedFrom', from: 'uncommitted' })
|
||||
await vi.waitFor(() => expect(page.posted()).toContainEqual(comparedWithHead))
|
||||
|
||||
page.hide()
|
||||
page.clear()
|
||||
await page.send({ type: 'ready', openedFrom: 'uncommitted' })
|
||||
expect(page.posted()).toContainEqual({ type: 'openedFrom', from: 'uncommitted' })
|
||||
@@ -336,6 +338,67 @@ describe('预览对比什么看这个标签页是从哪儿打开的', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('标签页切走时页面留着', () => {
|
||||
it('注册时就让页面在标签页切走后留着', () => {
|
||||
const { provider } = opening()
|
||||
provider.register()
|
||||
expect(window.registerCustomEditorProvider).toHaveBeenCalledWith(PREVIEW_VIEW_TYPE, provider, { webviewOptions: { retainContextWhenHidden: true } })
|
||||
})
|
||||
|
||||
it('切走再切回来:不重新生成文档、什么都不重发,高亮照旧能用键盘跳', async () => {
|
||||
const { provider, document } = opening()
|
||||
const page = tab()
|
||||
await provider.open(document.uri as never, { from: 'uncommitted' }, async () => provider.resolveCustomTextEditor(document as never, page.panel))
|
||||
await page.send({ type: 'ready' })
|
||||
await vi.waitFor(() => expect(page.posted()).toContainEqual(comparedWithHead))
|
||||
await page.send({ type: 'occurrenceNavigation', available: true })
|
||||
|
||||
page.clear()
|
||||
vi.mocked(documentMessage).mockClear()
|
||||
vi.mocked(commands.executeCommand).mockClear()
|
||||
page.hide()
|
||||
page.show()
|
||||
// 比连续输入合并重新解析的那一下(150ms)等得久
|
||||
await new Promise(resolve => setTimeout(resolve, 200))
|
||||
expect(documentMessage).not.toHaveBeenCalled()
|
||||
expect(page.posted()).toEqual([])
|
||||
expect(commands.executeCommand).not.toHaveBeenCalledWith('setContext', OCCURRENCES_CONTEXT, false)
|
||||
})
|
||||
|
||||
it('切走期间文件在别处改了:照常把新的文档发给留着的页面', async () => {
|
||||
const { provider, document } = opening()
|
||||
const page = tab()
|
||||
provider.resolveCustomTextEditor(document as never, page.panel)
|
||||
await page.send({ type: 'ready' })
|
||||
|
||||
page.hide()
|
||||
page.clear()
|
||||
document.version = 2
|
||||
const edited = vi.mocked(workspace.onDidChangeTextDocument).mock.calls.at(-1)![0]
|
||||
edited({ document, contentChanges: [{ rangeOffset: 0, rangeLength: 0, text: '// ' }] } as never)
|
||||
await vi.waitFor(() => expect(page.posted()).toContainEqual(expect.objectContaining({ type: 'document', version: 2 })))
|
||||
})
|
||||
|
||||
it('页面真的重新加载了(webview 进程崩了重建、开发者重载):再发 ready 时照旧整份发一遍', async () => {
|
||||
const { provider, document } = opening()
|
||||
const page = tab()
|
||||
await provider.open(document.uri as never, { from: 'uncommitted' }, async () => provider.resolveCustomTextEditor(document as never, page.panel))
|
||||
await page.send({ type: 'ready' })
|
||||
await vi.waitFor(() => expect(page.posted()).toContainEqual(comparedWithHead))
|
||||
|
||||
page.clear()
|
||||
vi.mocked(documentMessage).mockClear()
|
||||
await page.send({ type: 'ready', openedFrom: 'uncommitted' })
|
||||
expect(documentMessage).toHaveBeenCalled()
|
||||
expect(page.posted().map(message => message.type)).toEqual(expect.arrayContaining(['openedFrom', 'filter', 'qa', 'codeColors', 'document']))
|
||||
await vi.waitFor(() => {
|
||||
expect(page.posted()).toContainEqual(comparedWithHead)
|
||||
expect(page.posted()).toContainEqual(expect.objectContaining({ type: 'profiles', kind: 'ask' }))
|
||||
expect(page.posted()).toContainEqual(expect.objectContaining({ type: 'profiles', kind: 'rewrite' }))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('代码配色跟着当前颜色主题', () => {
|
||||
it('ready 后先于第一份文档发;换了主题发给 ready 了的预览,还没 ready 的等 ready 时发眼下的', async () => {
|
||||
const colors = themeColors(COLORS)
|
||||
|
||||
Reference in new issue
Block a user