diff --git a/packages/core/src/browser/widget-manager.ts b/packages/core/src/browser/widget-manager.ts index 161514aec47a9..8f915d1c09532 100644 --- a/packages/core/src/browser/widget-manager.ts +++ b/packages/core/src/browser/widget-manager.ts @@ -20,8 +20,28 @@ import { ILogger, Emitter, Event, ContributionProvider, MaybePromise, WaitUntilE /* eslint-disable @typescript-eslint/no-explicit-any */ export const WidgetFactory = Symbol('WidgetFactory'); + /** - * `OpenHandler` should be implemented to provide a new opener. + * A {@link WidgetFactory} is used to create new widgets. Factory-specific information (options) can be passed as serializable JSON data. + * The common {@link WidgetManager} collects {@link WidgetFactory} contributions and delegates to the corresponding factory when + * a widget should be created or restored. To identify widgets the {@link WidgetManager} uses a description composed of the factory id and the options. + * The {@link WidgetFactory} does support both, synchronous and asynchronous widget creation. + * + * ### Example usage + * + * ```typescript + * export class MyWidget extends BaseWidget { + * } + * + * @injectable() + * export class MyWidgetFactory implements WidgetFactory { + * id = 'myWidgetFactory'; + * + * createWidget(): MaybePromise { + * return new MyWidget(); + * } + * } + * ``` */ export interface WidgetFactory { @@ -31,8 +51,10 @@ export interface WidgetFactory { readonly id: string; /** - * Creates a widget and attaches it to the application shell. - * @param options serializable JSON data. + * Creates a widget using the given options. + * @param options factory specific information as serializable JSON data. + * + * @returns the newly created widget or a promise of the widget */ createWidget(options?: any): MaybePromise; } @@ -82,7 +104,9 @@ export interface DidCreateWidgetEvent { } /** - * Creates and manages widgets. + * The {@link WidgetManager} is the common component responsible for creating and managing widgets. Additional widget factories + * can be registered by using the {@link WidgetFactory} contribution point. To identify a widget, created by a factory, the factory id and + * the creation options are used. This key is commonly referred to as `description` of the widget. */ @injectable() export class WidgetManager { @@ -106,13 +130,14 @@ export class WidgetManager { readonly onWillCreateWidget: Event = this.onWillCreateWidgetEmitter.event; protected readonly onDidCreateWidgetEmitter = new Emitter(); + readonly onDidCreateWidget: Event = this.onDidCreateWidgetEmitter.event; /** - * Get the list of widgets created for the given factory id. + * Get the list of widgets created by the given widget factory. * @param factoryId the widget factory id. * - * @returns the list of widgets created for the given factory id. + * @returns the list of widgets created by the factory with the given id. */ getWidgets(factoryId: string): Widget[] { const result: Widget[] = []; @@ -125,7 +150,9 @@ export class WidgetManager { } /** - * Try and get the widget. + * Try to get the existing widget for the given description. + * @param factoryId the widget factory id. + * @param options The widget factory specific information. * * @returns the widget if available, else `undefined`. */ @@ -140,8 +167,10 @@ export class WidgetManager { /** * Get the widget for the given description. + * @param factoryId the widget factory id. + * @param options The widget factory specific information. * - * @returns a promise resolving to the widget if available, else `undefined. + * @returns a promise resolving to the widget if available, else `undefined`. */ async getWidget(factoryId: string, options?: any): Promise { const key = this.toKey({ factoryId, options }); @@ -159,7 +188,11 @@ export class WidgetManager { } /** - * Creates or returns the widget for the given description. + * Creates a new widget or returns the existing widget for the given description. + * @param factoryId the widget factory id. + * @param options the widget factory specific information. + * + * @returns a promise resolving to the widget. */ async getOrCreateWidget(factoryId: string, options?: any): Promise { const key = this.toKey({ factoryId, options }); diff --git a/packages/core/src/browser/widget-open-handler.ts b/packages/core/src/browser/widget-open-handler.ts index 1c8ddfbb4d731..e70af0c194171 100644 --- a/packages/core/src/browser/widget-open-handler.ts +++ b/packages/core/src/browser/widget-open-handler.ts @@ -23,10 +23,12 @@ import { OpenHandler, OpenerOptions } from './opener-service'; import { WidgetManager } from './widget-manager'; export type WidgetOpenMode = 'open' | 'reveal' | 'activate'; - +/** + * `WidgetOpenerOptions` define serializable generic options used by the {@link WidgetOpenHandler}. + */ export interface WidgetOpenerOptions extends OpenerOptions { /** - * Whether the widget should be only opened, revealed or activated. + * Determines whether the widget should be only opened, revealed or activated. * By default is `activate`. */ mode?: WidgetOpenMode; @@ -37,6 +39,9 @@ export interface WidgetOpenerOptions extends OpenerOptions { widgetOptions?: ApplicationShell.WidgetOptions; } +/** + * Generic base class for {@link OpenHandler}s that are opening a widget for a given {@link URI}. + */ @injectable() export abstract class WidgetOpenHandler implements OpenHandler { @@ -74,7 +79,11 @@ export abstract class WidgetOpenHandler implements OpenHan /** * Open a widget for the given uri and options. - * Reject if the given options is not an widget options or a widget cannot be opened. + * Reject if the given options are not widget options or a widget cannot be opened. + * @param uri the uri of the resource that should be opened. + * @param options the widget opener options. + * + * @returns promise of the widget that resolves when the widget has been opened */ async open(uri: URI, options?: WidgetOpenerOptions): Promise { const widget = await this.getOrCreateWidget(uri, options); @@ -97,7 +106,10 @@ export abstract class WidgetOpenHandler implements OpenHan } /** - * Return an existing widget for the given uri. + * Tries to get an existing widget for the given uri. + * @param uri the uri of the widget. + * + * @returns a promise that resolves to the existing widget or `undefined` if no widget for the given uri exists. */ getByUri(uri: URI): Promise { return this.getWidget(uri); @@ -106,14 +118,19 @@ export abstract class WidgetOpenHandler implements OpenHan /** * Return an existing widget for the given uri or creates a new one. * - * It does not open a widget, use `open` instead. + * It does not open a widget, use {@link WidgetOpenHandler#open} instead. + * @param uri uri of the widget. + * + * @returns a promise of the existing or newly created widget. */ getOrCreateByUri(uri: URI): Promise { return this.getOrCreateWidget(uri); } /** - * All opened widgets. + * Retrieves all open widgets that have been opened by this handler. + * + * @returns all open widgets for this open handler. */ get all(): W[] { return this.widgetManager.getWidgets(this.id) as W[]; @@ -131,6 +148,12 @@ export abstract class WidgetOpenHandler implements OpenHan protected abstract createWidgetOptions(uri: URI, options?: WidgetOpenerOptions): Object; + /** + * Closes all widgets that have been opened by this open handler. + * @param options the close options that should be applied to all widgets. + * + * @returns a promise of all closed widgets that resolves after they have been closed. + */ async closeAll(options?: ApplicationShell.CloseOptions): Promise { const closed = await Promise.all(this.all.map(widget => this.shell.closeWidget(widget.id, options))); return closed.filter(widget => !!widget) as W[];