Skip to content

Commit

Permalink
Add documentation for widget manager & open handler
Browse files Browse the repository at this point in the history
- Document 'WidgetManager' and related interfaces
- Document 'WidgetOpenHandler' and related interfaces
Signed-off-by: Tobias Ortmayr <tortmayr@eclipsesource.com>
Contributed on behalf of STMicroelectronics
  • Loading branch information
tortmayr committed Oct 8, 2020
1 parent 56c158d commit a041e2c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 16 deletions.
52 changes: 42 additions & 10 deletions packages/core/src/browser/widget-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,30 @@
import { inject, named, injectable } from 'inversify';
import { Widget } from '@phosphor/widgets';
import { ILogger, Emitter, Event, ContributionProvider, MaybePromise, WaitUntilEvent } from '../common';

/* 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<Widget> {
* return new MyWidget();
* }
* }
* ```
*/
export interface WidgetFactory {

Expand All @@ -31,8 +50,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<Widget>;
}
Expand Down Expand Up @@ -82,7 +103,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 {
Expand All @@ -106,13 +129,14 @@ export class WidgetManager {
readonly onWillCreateWidget: Event<WillCreateWidgetEvent> = this.onWillCreateWidgetEmitter.event;

protected readonly onDidCreateWidgetEmitter = new Emitter<DidCreateWidgetEvent>();

readonly onDidCreateWidget: Event<DidCreateWidgetEvent> = 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[] = [];
Expand All @@ -125,7 +149,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`.
*/
Expand All @@ -140,8 +166,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<T extends Widget>(factoryId: string, options?: any): Promise<T | undefined> {
const key = this.toKey({ factoryId, options });
Expand All @@ -159,7 +187,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<T extends Widget>(factoryId: string, options?: any): Promise<T> {
const key = this.toKey({ factoryId, options });
Expand Down
35 changes: 29 additions & 6 deletions packages/core/src/browser/widget-open-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<W extends BaseWidget> implements OpenHandler {

Expand Down Expand Up @@ -74,7 +79,11 @@ export abstract class WidgetOpenHandler<W extends BaseWidget> 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<W> {
const widget = await this.getOrCreateWidget(uri, options);
Expand All @@ -97,7 +106,10 @@ export abstract class WidgetOpenHandler<W extends BaseWidget> 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<W | undefined> {
return this.getWidget(uri);
Expand All @@ -106,14 +118,19 @@ export abstract class WidgetOpenHandler<W extends BaseWidget> 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<W> {
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[];
Expand All @@ -131,6 +148,12 @@ export abstract class WidgetOpenHandler<W extends BaseWidget> 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<W[]> {
const closed = await Promise.all(this.all.map(widget => this.shell.closeWidget(widget.id, options)));
return closed.filter(widget => !!widget) as W[];
Expand Down

0 comments on commit a041e2c

Please sign in to comment.