Skip to content

Commit 186792c

Browse files
gjsjohnmurraymjbvz
andauthored
#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: Matt Bierner <[email protected]>
1 parent fc35c42 commit 186792c

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

src/vs/workbench/contrib/extensions/browser/extensionEditor.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ interface IExtensionEditorTemplate {
169169
header: HTMLElement;
170170
}
171171

172+
const enum WebviewIndex {
173+
Readme,
174+
Changelog
175+
}
176+
172177
export class ExtensionEditor extends EditorPane {
173178

174179
static readonly ID: string = 'workbench.editor.extension';
@@ -179,6 +184,12 @@ export class ExtensionEditor extends EditorPane {
179184
private extensionChangelog: Cache<string> | null;
180185
private extensionManifest: Cache<IExtensionManifest | null> | null;
181186

187+
// Some action bar items use a webview whose vertical scroll position we track in this map
188+
private initialScrollProgress: Map<WebviewIndex, number> = new Map();
189+
190+
// Spot when an ExtensionEditor instance gets reused for a different extension, in which case the vertical scroll positions must be zeroed
191+
private currentIdentifier: string = '';
192+
182193
private layoutParticipants: ILayoutParticipant[] = [];
183194
private readonly contentDisposables = this._register(new DisposableStore());
184195
private readonly transientDisposables = this._register(new DisposableStore());
@@ -336,6 +347,11 @@ export class ExtensionEditor extends EditorPane {
336347
this.editorLoadComplete = false;
337348
const extension = input.extension;
338349

350+
if (this.currentIdentifier !== extension.identifier.id) {
351+
this.initialScrollProgress.clear();
352+
this.currentIdentifier = extension.identifier.id;
353+
}
354+
339355
this.transientDisposables.clear();
340356

341357
this.extensionReadme = new Cache(() => createCancelablePromise(token => extension.getReadme(token)));
@@ -563,7 +579,7 @@ export class ExtensionEditor extends EditorPane {
563579
return Promise.resolve(null);
564580
}
565581

566-
private async openMarkdown(cacheResult: CacheResult<string>, noContentCopy: string, template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {
582+
private async openMarkdown(cacheResult: CacheResult<string>, noContentCopy: string, template: IExtensionEditorTemplate, webviewIndex: WebviewIndex, token: CancellationToken): Promise<IActiveElement> {
567583
try {
568584
const body = await this.renderMarkdown(cacheResult, template);
569585
if (token.isCancellationRequested) {
@@ -572,15 +588,22 @@ export class ExtensionEditor extends EditorPane {
572588

573589
const webview = this.contentDisposables.add(this.webviewService.createWebviewOverlay('extensionEditor', {
574590
enableFindWidget: true,
591+
tryRestoreScrollPosition: true,
575592
}, {}, undefined));
576593

594+
webview.initialScrollProgress = this.initialScrollProgress.get(webviewIndex) || 0;
595+
577596
webview.claim(this, this.scopedContextKeyService);
578597
setParentFlowTo(webview.container, template.content);
579598
webview.layoutWebviewOverElement(template.content);
580599

581600
webview.html = body;
601+
webview.claim(this);
582602

583603
this.contentDisposables.add(webview.onDidFocus(() => this.fireOnDidFocus()));
604+
605+
this.contentDisposables.add(webview.onDidScroll(() => this.initialScrollProgress.set(webviewIndex, webview.initialScrollProgress)));
606+
584607
const removeLayoutParticipant = arrays.insert(this.layoutParticipants, {
585608
layout: () => {
586609
webview.layoutWebviewOverElement(template.content);
@@ -823,7 +846,7 @@ export class ExtensionEditor extends EditorPane {
823846
if (manifest && manifest.extensionPack && manifest.extensionPack.length) {
824847
return this.openExtensionPackReadme(manifest, template, token);
825848
}
826-
return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), template, token);
849+
return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), template, WebviewIndex.Readme, token);
827850
}
828851

829852
private async openExtensionPackReadme(manifest: IExtensionManifest, template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {
@@ -854,15 +877,15 @@ export class ExtensionEditor extends EditorPane {
854877
const readmeContent = append(extensionPackReadme, $('div.readme-content'));
855878

856879
await Promise.all([
857-
this.renderExtensionPack(manifest, extensionPackContent, token),
858-
this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), { ...template, ...{ content: readmeContent } }, token),
880+
this.renderExtensionPack(manifest, extensionPackContent),
881+
this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), { ...template, ...{ content: readmeContent } }, WebviewIndex.Readme, token),
859882
]);
860883

861884
return { focus: () => extensionPackContent.focus() };
862885
}
863886

864-
private openChangelog(template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {
865-
return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available."), template, token);
887+
private openChangelog(template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement> {
888+
return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available."), template, WebviewIndex.Changelog, token);
866889
}
867890

868891
private openContributions(template: IExtensionEditorTemplate, token: CancellationToken): Promise<IActiveElement | null> {

0 commit comments

Comments
 (0)