/********************************************************************************
 * Copyright (C) 2018 TypeFox 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
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License v. 2.0 are satisfied: GNU General Public License, version 2
 * with the GNU Classpath Exception which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 ********************************************************************************/ import { inject , postConstruct , injectable } from 'inversify' ; import URI from '../common/uri' ; import { MaybePromise , Emitter , Event } from '../common' ; import { BaseWidget } from './widgets' ; import { ApplicationShell } from './shell' ; 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  WidgetOpenHandler .
  export interface WidgetOpenerOptions extends OpenerOptions { /**
     * Determines whether the widget should be only opened, revealed or activated.
     * By default is `activate`.
     */ mode ? : WidgetOpenMode ; /**
     * Specify how an opened widget should be added to the shell.
     * By default to the main area.
     */ widgetOptions ? : ApplicationShell . WidgetOptions ; } /**
 * Generic base class for  OpenHandler s that are opening a widget for a given  URI .
  @ injectable ( ) export abstract class WidgetOpenHandler < W extends BaseWidget > implements OpenHandler { @ inject ( ApplicationShell ) protected readonly shell : ApplicationShell ; @ inject ( WidgetManager ) protected readonly widgetManager : WidgetManager ; protected readonly onCreatedEmitter = new Emitter < W > ( ) ; /**
     * Emit when a new widget is created.
     */ readonly onCreated : Event < W > = this . onCreatedEmitter . event ; @ postConstruct ( ) protected init ( ) { this . widgetManager . onDidCreateWidget ( ( { factoryId , widget } ) => { if ( factoryId === this . id ) { this . onCreatedEmitter . fire ( widget as W ) ; } } ) ; } /**
     * The widget open handler id.
     *
     * #### Implementation
     * - A widget factory for this id should be registered.
     * - Subclasses should not implement `WidgetFactory`
     * to avoid exposing capabilities to create a widget outside of `WidgetManager`.
     */ abstract readonly id : string ; abstract canHandle ( uri , options ? ) ; param uri param options returns async open ( uri , options ? ) { const widget = await this . getOrCreateWidget ( uri , options ) ; await this . doOpen ( widget , options ) ; return widget ; } protected async doOpen ( widget , options ? ) { const op = { mode : 'activate' , ... options } ; if ( ! widget . isAttached ) { this . shell . addWidget ( widget , op . widgetOptions || { area : 'main' } ) ; } if ( op . mode === 'activate' ) { await this . shell . activateWidget ( widget . id ) ; } else if ( op . mode === 'reveal' ) { await this . shell . revealWidget ( widget . id ) ; } } param uri returns getByUri ( uri ) { return this . getWidget ( uri ) ; } /**
     * Return an existing widget for the given uri or creates a new one.
     *
     * It does not open a widget, use  WidgetOpenHandler instead.
     *  param uri returns getOrCreateByUri ( uri ) { return this . getOrCreateWidget ( uri ) ; } returns get all ( ) : W [ ] { return this . widgetManager . getWidgets ( this . id ) as W [ ] ; } protected tryGetPendingWidget ( uri , options ? ) { const factoryOptions = this . createWidgetOptions ( uri , options ) ; return this . widgetManager . tryGetPendingWidget ( this . id , factoryOptions ) ; } protected getWidget ( uri , options ? ) { const widgetOptions = this . createWidgetOptions ( uri , options ) ; return this . widgetManager . getWidget < W > ( this . id , widgetOptions ) ; } protected getOrCreateWidget ( uri , options ? ) { const widgetOptions = this . createWidgetOptions ( uri , options ) ; return this . widgetManager . getOrCreateWidget < W > ( this . id , widgetOptions ) ; } protected abstract createWidgetOptions ( uri , options ? ) ; param options returns async closeAll ( options ? ) { const closed = await Promise . all ( this . all . map ( widget => this . shell . closeWidget ( widget . id , options ) ) ) ; return closed . filter ( widget => ! ! widget ) as W [ ] ; } }