未验证 提交 186792ca 编写于 作者: J John Murray 提交者: GitHub

#27498 restore extension editor webview scroll positions (#85982)

* #27498 restore extension editor webview scroll positions

* Delay setInitialScrollPosition so iframe contents  have time to load fully (we hope)

* Some changes requested by @mjbvz

* revert setTimeout hack

* fix my spelling error in comment

* remove blank line to perfect the undo
Co-authored-by: NMatt Bierner <matb@microsoft.com>
上级 fc35c427
......@@ -169,6 +169,11 @@ interface IExtensionEditorTemplate {
header: HTMLElement;
}
const enum WebviewIndex {
Readme,
Changelog
}
export class ExtensionEditor extends EditorPane {
static readonly ID: string = 'workbench.editor.extension';
......@@ -179,6 +184,12 @@ export class ExtensionEditor extends EditorPane {
private extensionChangelog: Cache<string> | null;
private extensionManifest: Cache<IExtensionManifest | null> | null;
// Some action bar items use a webview whose vertical scroll position we track in this map
private initialScrollProgress: Map<WebviewIndex, number> = new Map();
// Spot when an ExtensionEditor instance gets reused for a different extension, in which case the vertical scroll positions must be zeroed
private currentIdentifier: string = '';
private layoutParticipants: ILayoutParticipant[] = [];
private readonly contentDisposables = this._register(new DisposableStore());
private readonly transientDisposables = this._register(new DisposableStore());
......@@ -336,6 +347,11 @@ export class ExtensionEditor extends EditorPane {
this.editorLoadComplete = false;
const extension = input.extension;
if (this.currentIdentifier !== extension.identifier.id) {
this.initialScrollProgress.clear();
this.currentIdentifier = extension.identifier.id;
}
this.transientDisposables.clear();
this.extensionReadme = new Cache(() => createCancelablePromise(token => extension.getReadme(token)));
......@@ -563,7 +579,7 @@ export class ExtensionEditor extends EditorPane {
return Promise.resolve(null);
}
private async openMarkdown(cacheResult: CacheResult<string>, noContentCopy: string, template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {
private async openMarkdown(cacheResult: CacheResult<string>, noContentCopy: string, template: IExtensionEditorTemplate, webviewIndex: WebviewIndex, token: CancellationToken): Promise<IActiveElement> {
try {
const body = await this.renderMarkdown(cacheResult, template);
if (token.isCancellationRequested) {
......@@ -572,15 +588,22 @@ export class ExtensionEditor extends EditorPane {
const webview = this.contentDisposables.add(this.webviewService.createWebviewOverlay('extensionEditor', {
enableFindWidget: true,
tryRestoreScrollPosition: true,
}, {}, undefined));
webview.initialScrollProgress = this.initialScrollProgress.get(webviewIndex) || 0;
webview.claim(this, this.scopedContextKeyService);
setParentFlowTo(webview.container, template.content);
webview.layoutWebviewOverElement(template.content);
webview.html = body;
webview.claim(this);
this.contentDisposables.add(webview.onDidFocus(() => this.fireOnDidFocus()));
this.contentDisposables.add(webview.onDidScroll(() => this.initialScrollProgress.set(webviewIndex, webview.initialScrollProgress)));
const removeLayoutParticipant = arrays.insert(this.layoutParticipants, {
layout: () => {
webview.layoutWebviewOverElement(template.content);
......@@ -823,7 +846,7 @@ export class ExtensionEditor extends EditorPane {
if (manifest && manifest.extensionPack && manifest.extensionPack.length) {
return this.openExtensionPackReadme(manifest, template, token);
}
return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), template, token);
return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), template, WebviewIndex.Readme, token);
}
private async openExtensionPackReadme(manifest: IExtensionManifest, template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {
......@@ -854,15 +877,15 @@ export class ExtensionEditor extends EditorPane {
const readmeContent = append(extensionPackReadme, $('div.readme-content'));
await Promise.all([
this.renderExtensionPack(manifest, extensionPackContent, token),
this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), { ...template, ...{ content: readmeContent } }, token),
this.renderExtensionPack(manifest, extensionPackContent),
this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), { ...template, ...{ content: readmeContent } }, WebviewIndex.Readme, token),
]);
return { focus: () => extensionPackContent.focus() };
}
private openChangelog(template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {
return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available."), template, token);
private openChangelog(template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement> {
return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available."), template, WebviewIndex.Changelog, token);
}
private openContributions(template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册