<commit_before>/*---------------------------------------------------------------------------------------------
 *  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 * as map from 'vs/base/common/map';
import { TPromise } from 'vs/base/common/winjs.base';
import { MainThreadWebviewsShape, MainContext, IExtHostContext, ExtHostContext, ExtHostWebviewsShape, WebviewHandle } from 'vs/workbench/api/node/extHost.protocol';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { extHostNamedCustomer } from './extHostCustomers';
import { EditorInput, EditorModel, EditorOptions } from 'vs/workbench/common/editor';
import { IEditorModel, Position } from 'vs/platform/editor/common/editor';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { WebviewEditor as BaseWebviewEditor, KEYBINDING_CONTEXT_WEBVIEWEDITOR_FOCUS, KEYBINDING_CONTEXT_WEBVIEWEDITOR_FIND_WIDGET_INPUT_FOCUSED, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/parts/html/browser/webviewEditor';
import { Builder, Dimension } from 'vs/base/browser/builder';
import { Webview } from 'vs/workbench/parts/html/browser/webview';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
import { Registry } from 'vs/platform/registry/common/platform';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { localize } from 'vs/nls';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import * as vscode from 'vscode';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import URI from 'vs/base/common/uri';
import DOM = require('vs/base/browser/dom');
import Event, { Emitter } from 'vs/base/common/event';


interface WebviewEvents {
	onMessage(message: any): void;
	onDidChangePosition(newPosition: Position): void;
	onDispose(): void;
	onDidClickLink(link: URI, options: vscode.WebviewOptions): void;
}

class WebviewInput extends EditorInput {
	private static handlePool = 0;

	private readonly _resource: URI;
	private _name: string;
	private _options: vscode.WebviewOptions;
	private _html: string;
	private _events: WebviewEvents | undefined;
	private _container: HTMLElement;
	private _webview: Webview | undefined;
	private _webviewOwner: any;
	private _webviewDisposables: IDisposable[] = [];

	public static create(
		resource: URI,
		name: string,
		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, options, html, events, webviewContainer, undefined);
	}

	constructor(
		resource: URI,
		name: string,
		options: vscode.WebviewOptions,
		html: string,
		events: WebviewEvents,
		container: HTMLElement,
		webview: Webview | undefined
	) {
		super();
		this._resource = resource;
		this._name = name;
		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 html(): string {
		return this._html;
	}

	public setHtml(value: string): void {
		this._html = value;

		if (this._webview) {
			this._webview.contents = value;
		}
	}

	public get options(): vscode.WebviewOptions {
		return this._options;
	}

	public set options(value: vscode.WebviewOptions) {
		this._options = value;
	}

	public resolve(refresh?: boolean): TPromise<IEditorModel, any> {
		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.disposeWebview();
			}
		}
	}

	public disposeWebview() {
		// The input owns the webview and its parent
		if (this._webview) {<commit_msg>Fix retained webviews not being properly when their editor hides<commit_after>/*---------------------------------------------------------------------------------------------
 *  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 * as map from 'vs/base/common/map';
import { TPromise } from 'vs/base/common/winjs.base';
import { MainThreadWebviewsShape, MainContext, IExtHostContext, ExtHostContext, ExtHostWebviewsShape, WebviewHandle } from 'vs/workbench/api/node/extHost.protocol';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { extHostNamedCustomer } from './extHostCustomers';
import { EditorInput, EditorModel, EditorOptions } from 'vs/workbench/common/editor';
import { IEditorModel, Position } from 'vs/platform/editor/common/editor';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { WebviewEditor as BaseWebviewEditor, KEYBINDING_CONTEXT_WEBVIEWEDITOR_FOCUS, KEYBINDING_CONTEXT_WEBVIEWEDITOR_FIND_WIDGET_INPUT_FOCUSED, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/parts/html/browser/webviewEditor';
import { Builder, Dimension } from 'vs/base/browser/builder';
import { Webview } from 'vs/workbench/parts/html/browser/webview';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
import { Registry } from 'vs/platform/registry/common/platform';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { localize } from 'vs/nls';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import * as vscode from 'vscode';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import URI from 'vs/base/common/uri';
import DOM = require('vs/base/browser/dom');
import Event, { Emitter } from 'vs/base/common/event';


interface WebviewEvents {
	onMessage(message: any): void;
	onDidChangePosition(newPosition: Position): void;
	onDispose(): void;
	onDidClickLink(link: URI, options: vscode.WebviewOptions): void;
}

class WebviewInput extends EditorInput {
	private static handlePool = 0;

	private readonly _resource: URI;
	private _name: string;
	private _options: vscode.WebviewOptions;
	private _html: string;
	private _events: WebviewEvents | undefined;
	private _container: HTMLElement;
	private _webview: Webview | undefined;
	private _webviewOwner: any;
	private _webviewDisposables: IDisposable[] = [];

	public static create(
		resource: URI,
		name: string,
		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, options, html, events, webviewContainer, undefined);
	}

	constructor(
		resource: URI,
		name: string,
		options: vscode.WebviewOptions,
		html: string,
		events: WebviewEvents,
		container: HTMLElement,
		webview: Webview | undefined
	) {
		super();
		this._resource = resource;
		this._name = name;
		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 html(): string {
		return this._html;
	}

	public setHtml(value: string): void {
		this._html = value;

		if (this._webview) {
			this._webview.contents = value;
		}
	}

	public get options(): vscode.WebviewOptions {
		return this._options;
	}

	public set options(value: vscode.WebviewOptions) {
		this._options = value;
	}

	public resolve(refresh?: boolean): TPromise<IEditorModel, any> {
		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) {
{'fraction_non_alphanumeric': 0.1432520325203252, 'fraction_numerical': 0.00016260162601626016, 'mean_word_length': 4.1168885191347755, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3630518', 'n_tokens_mistral': 3990, 'n_tokens_neox': 3736, 'n_words': 850}