diff --git a/packages/core/src/browser/widget-manager.ts b/packages/core/src/browser/widget-manager.ts index d327634ef4a93..e00c7e6cb82dd 100644 --- a/packages/core/src/browser/widget-manager.ts +++ b/packages/core/src/browser/widget-manager.ts @@ -165,6 +165,18 @@ export class WidgetManager { return undefined; } + /** + * Try to get the existing widget for the given description. + * @param factoryId The widget factory id. + * @param options The widget factory specific information. + * + * @returns A promise that resolves to the widget, if any exists. The promise may be pending, so be cautious when assuming that it will not reject. + */ + tryGetPendingWidget(factoryId: string, options?: any): MaybePromise | undefined { + const key = this.toKey({ factoryId, options }); + return this.doGetWidget(key); + } + /** * Get the widget for the given description. * @param factoryId The widget factory id. @@ -172,9 +184,11 @@ export class WidgetManager { * * @returns a promise resolving to the widget if available, else `undefined`. */ - getWidget(factoryId: string, options?: any): MaybePromise | undefined { + async getWidget(factoryId: string, options?: any): Promise { const key = this.toKey({ factoryId, options }); - return this.doGetWidget(key); + const pendingWidget = this.doGetWidget(key); + const widget = pendingWidget && await pendingWidget; + return widget; } protected doGetWidget(key: string): MaybePromise | undefined { diff --git a/packages/core/src/browser/widget-open-handler.ts b/packages/core/src/browser/widget-open-handler.ts index 8023cc3c1d4e7..b2f73ff7f0d66 100644 --- a/packages/core/src/browser/widget-open-handler.ts +++ b/packages/core/src/browser/widget-open-handler.ts @@ -111,7 +111,7 @@ export abstract class WidgetOpenHandler implements OpenHan * * @returns a promise that resolves to the existing widget or `undefined` if no widget for the given uri exists. */ - getByUri(uri: URI): MaybePromise | undefined { + getByUri(uri: URI): Promise { return this.getWidget(uri); } @@ -136,7 +136,12 @@ export abstract class WidgetOpenHandler implements OpenHan return this.widgetManager.getWidgets(this.id) as W[]; } - protected getWidget(uri: URI, options?: WidgetOpenerOptions): MaybePromise | undefined { + protected tryGetPendingWidget(uri: URI, options?: WidgetOpenerOptions): MaybePromise | undefined { + const factoryOptions = this.createWidgetOptions(uri, options); + return this.widgetManager.tryGetPendingWidget(this.id, factoryOptions); + } + + protected getWidget(uri: URI, options?: WidgetOpenerOptions): Promise { const widgetOptions = this.createWidgetOptions(uri, options); return this.widgetManager.getWidget(this.id, widgetOptions); } diff --git a/packages/editor-preview/src/browser/editor-preview-frontend-module.ts b/packages/editor-preview/src/browser/editor-preview-frontend-module.ts index 96df28071ff7d..14dccb11546dc 100644 --- a/packages/editor-preview/src/browser/editor-preview-frontend-module.ts +++ b/packages/editor-preview/src/browser/editor-preview-frontend-module.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (C) 2018 Google and others. + * Copyright (C) 2018-2021 Google and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at diff --git a/packages/editor-preview/src/browser/editor-preview-manager.ts b/packages/editor-preview/src/browser/editor-preview-manager.ts index 748a8cf98588d..af88b69d8f5cb 100644 --- a/packages/editor-preview/src/browser/editor-preview-manager.ts +++ b/packages/editor-preview/src/browser/editor-preview-manager.ts @@ -98,12 +98,16 @@ export class EditorPreviewManager extends EditorManager { this.toDisposeOnPreviewChange.push(widget.onDidDispose(() => this.toDisposeOnPreviewChange.dispose())); } - protected getWidget(uri: URI, options?: EditorOpenerOptions): MaybePromise | undefined { - return super.getWidget(uri, { ...options, preview: true }) ?? super.getWidget(uri, { ...options, preview: false }); + protected tryGetPendingWidget(uri: URI, options?: EditorOpenerOptions): MaybePromise | undefined { + return super.tryGetPendingWidget(uri, { ...options, preview: true }) ?? super.tryGetPendingWidget(uri, { ...options, preview: false }); + } + + protected async getWidget(uri: URI, options?: EditorOpenerOptions): Promise { + return (await super.getWidget(uri, { ...options, preview: true })) ?? super.getWidget(uri, { ...options, preview: false }); } protected async getOrCreateWidget(uri: URI, options?: EditorOpenerOptions): Promise { - return this.getWidget(uri, options) ?? super.getOrCreateWidget(uri, options); + return this.tryGetPendingWidget(uri, options) ?? super.getOrCreateWidget(uri, options); } protected createWidgetOptions(uri: URI, options?: EditorOpenerOptions): EditorPreviewOptions { diff --git a/packages/editor/src/browser/editor-manager.ts b/packages/editor/src/browser/editor-manager.ts index 6257a66ab62ac..1dc7499736e7c 100644 --- a/packages/editor/src/browser/editor-manager.ts +++ b/packages/editor/src/browser/editor-manager.ts @@ -82,7 +82,7 @@ export class EditorManager extends NavigatableWidgetOpenHandler { this.updateCurrentEditor(); } - getByUri(uri: URI, options?: EditorOpenerOptions): MaybePromise | undefined { + getByUri(uri: URI, options?: EditorOpenerOptions): Promise { return this.getWidget(uri, options); } @@ -90,8 +90,8 @@ export class EditorManager extends NavigatableWidgetOpenHandler { return this.getOrCreateWidget(uri, options); } - protected getWidget(uri: URI, options?: EditorOpenerOptions): MaybePromise | undefined { - const editorPromise = super.getWidget(uri, options); + protected tryGetPendingWidget(uri: URI, options?: EditorOpenerOptions): MaybePromise | undefined { + const editorPromise = super.tryGetPendingWidget(uri, options); if (editorPromise) { // Reveal selection before attachment to manage nav stack. (https://github.com/eclipse-theia/theia/issues/8955) if (!(editorPromise instanceof Widget)) { @@ -103,6 +103,15 @@ export class EditorManager extends NavigatableWidgetOpenHandler { return editorPromise; } + protected async getWidget(uri: URI, options?: EditorOpenerOptions): Promise { + const editor = await super.getWidget(uri, options); + if (editor) { + // Reveal selection before attachment to manage nav stack. (https://github.com/eclipse-theia/theia/issues/8955) + this.revealSelection(editor, options, uri); + } + return editor; + } + protected async getOrCreateWidget(uri: URI, options?: EditorOpenerOptions): Promise { const editor = await super.getOrCreateWidget(uri, options); // Reveal selection before attachment to manage nav stack. (https://github.com/eclipse-theia/theia/issues/8955)