/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { EditorInput, EditorModel } from 'vs/workbench/common/editor'; import { IEditorModel, Position } from 'vs/platform/editor/common/editor'; import { Webview } from 'vs/workbench/parts/html/browser/webview'; import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; import * as vscode from 'vscode'; import URI from 'vs/base/common/uri'; export interface WebviewEvents { onMessage(message: any): void; onDidChangePosition(newPosition: Position): void; onDispose(): void; onDidClickLink(link: URI, options: vscode.WebviewOptions): void; } export class WebviewInput extends EditorInput { private static handlePool = 0; private readonly _resource: URI; private _name: string; private _options: vscode.WebviewOptions; private _html: string; private _currentWebviewHtml: string = ''; private _events: WebviewEvents | undefined; private _container: HTMLElement; private _webview: Webview | undefined; private _webviewOwner: any; private _webviewDisposables: IDisposable[] = []; private _position: Position; public static create( resource: URI, name: string, position: Position, options: vscode.WebviewOptions, html: string, events: WebviewEvents, partService: IPartService ): WebviewInput { const id = WebviewInput.handlePool++; const webviewContainer = document.createElement('div'); webviewContainer.id = `webview-${id}`; partService.getContainer(Parts.EDITOR_PART).appendChild(webviewContainer); return new WebviewInput(resource, name, position, options, html, events, webviewContainer, undefined); } constructor( resource: URI, name: string, position: Position, options: vscode.WebviewOptions, html: string, events: WebviewEvents, container: HTMLElement, webview: Webview | undefined ) { super(); this._resource = resource; this._name = name; this._position = position; this._options = options; this._html = html; this._events = events; this._container = container; this._webview = webview; } public getTypeId(): string { return 'webview'; } public dispose() { this.disposeWebview(); if (this._container) { this._container.remove(); this._container = undefined; } if (this._events) { this._events.onDispose(); this._events = undefined; } super.dispose(); } public getResource(): URI { return this._resource; } public getName(): string { return this._name; } public setName(value: string): void { this._name = value; this._onDidChangeLabel.fire(); } public get position(): Position { return this._position; } public get html(): string { return this._html; } public setHtml(value: string): void { if (value === this._currentWebviewHtml) { return; } this._html = value; if (this._webview) { this._webview.contents = value; this._currentWebviewHtml = value; } } public get options(): vscode.WebviewOptions { return this._options; } public set options(value: vscode.WebviewOptions) { this._options = value; } public resolve(refresh?: boolean): TPromise { return TPromise.as(new EditorModel()); } public supportsSplitEditor() { return false; } public get container(): HTMLElement { return this._container; } public get webview(): Webview | undefined { return this._webview; } public set webview(value: Webview) { this._webviewDisposables = dispose(this._webviewDisposables); this._webview = value; this._webview.onDidClickLink(link => { if (this._events) { this._events.onDidClickLink(link, this._options); } }, null, this._webviewDisposables); this._webview.onMessage(message => { if (this._events) { this._events.onMessage(message); } }, null, this._webviewDisposables); } public claimWebview(owner: any) { this._webviewOwner = owner; } public releaseWebview(owner: any) { if (this._webviewOwner === owner) { this._webviewOwner = undefined; if (this._options.retainContextWhenHidden) { this.container.style.visibility = 'hidden'; } else { this.disposeWebview(); } } } public disposeWebview() { // The input owns the webview and its parent if (this._webview) { this._webview.dispose(); this._webview = undefined; } this._webviewDisposables = dispose(this._webviewDisposables); this._webviewOwner = undefined; this.container.style.visibility = 'hidden'; this._currentWebviewHtml = ''; } public onDidChangePosition(position: Position) { if (this._events) { this._events.onDidChangePosition(position); } this._position = position; } }