Merge remote-tracking branch 'upstream/mjbvz/webviewWidgetProto' into rebornix/review

This commit is contained in:
Peng Lyu
2018-04-06 16:22:01 -07:00
1410 changed files with 26175 additions and 13958 deletions

View File

@@ -368,7 +368,7 @@ export function createApiFactory(
showErrorMessage(message, first, ...rest) {
return extHostMessageService.showMessage(extension, Severity.Error, message, first, rest);
},
showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken) {
showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken): any {
return extHostQuickOpen.showQuickPick(items, options, token);
},
showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) {
@@ -420,6 +420,12 @@ export function createApiFactory(
}),
createWebview: proposedApiFunction(extension, (viewType: string, title: string, column: vscode.ViewColumn, options: vscode.WebviewOptions) => {
return extHostWebviews.createWebview(viewType, title, column, options, extension.extensionFolderPath);
}),
registerWebviewSerializer: proposedApiFunction(extension, (viewType: string, serializer: vscode.WebviewSerializer) => {
return extHostWebviews.registerWebviewSerializer(viewType, serializer);
}),
showWebviewWidget: proposedApiFunction(extension, (editor: vscode.TextEditor, position: vscode.Position, viewType: string, title: string, options: vscode.WebviewOptions) => {
return extHostWebviews.showWebviewWidget(editor, position, viewType, title, options);
})
};

View File

@@ -332,7 +332,7 @@ export interface MyQuickPickItems extends IPickOpenEntry {
handle: number;
}
export interface MainThreadQuickOpenShape extends IDisposable {
$show(options: IPickOptions): TPromise<number>;
$show(options: IPickOptions): TPromise<number | number[]>;
$setItems(items: MyQuickPickItems[]): TPromise<any>;
$setError(error: Error): TPromise<any>;
$input(options: vscode.InputBoxOptions, validateInput: boolean): TPromise<string>;
@@ -352,7 +352,7 @@ export interface MainThreadTelemetryShape extends IDisposable {
$publicLog(eventName: string, data?: any): void;
}
export type WebviewHandle = number;
export type WebviewHandle = string;
export interface MainThreadWebviewsShape extends IDisposable {
$createWebview(handle: WebviewHandle, viewType: string, title: string, column: EditorPosition, options: vscode.WebviewOptions, extensionFolderPath: string): void;
@@ -361,12 +361,19 @@ export interface MainThreadWebviewsShape extends IDisposable {
$setTitle(handle: WebviewHandle, value: string): void;
$setHtml(handle: WebviewHandle, value: string): void;
$sendMessage(handle: WebviewHandle, value: any): Thenable<boolean>;
$registerSerializer(viewType: string): void;
$unregisterSerializer(viewType: string): void;
$showWebviewWidget(handle: WebviewHandle, editorId: string, position: IPosition, viewType: string, options: vscode.WebviewOptions): void;
}
export interface ExtHostWebviewsShape {
$onMessage(handle: WebviewHandle, message: any): void;
$onDidChangeActiveWeview(handle: WebviewHandle | undefined): void;
$onDidChangeWeviewViewState(handle: WebviewHandle, active: boolean, position: EditorPosition): void;
$onDidDisposeWeview(handle: WebviewHandle): Thenable<void>;
$onDidChangePosition(handle: WebviewHandle, newPosition: EditorPosition): void;
$deserializeWebview(newWebviewHandle: WebviewHandle, viewType: string, state: any, position: EditorPosition, options: vscode.WebviewOptions): Thenable<void>;
$serializeWebview(webviewHandle: WebviewHandle): Thenable<any>;
}
export interface MainThreadWorkspaceShape extends IDisposable {
@@ -387,7 +394,7 @@ export interface MainThreadFileSystemShape extends IDisposable {
$unregisterProvider(handle: number): void;
$onFileSystemChange(handle: number, resource: IFileChangeDto[]): void;
$reportFileChunk(handle: number, session: number, chunk: number[] | null): void;
$reportFileChunk(handle: number, session: number, base64Encoded: string | null): void;
$handleFindMatch(handle: number, session, data: UriComponents | [UriComponents, ILineMatch]): void;
}
@@ -566,7 +573,7 @@ export interface ExtHostFileSystemShape {
$utimes(handle: number, resource: UriComponents, mtime: number, atime: number): TPromise<IStat>;
$stat(handle: number, resource: UriComponents): TPromise<IStat>;
$read(handle: number, session: number, offset: number, count: number, resource: UriComponents): TPromise<number>;
$write(handle: number, resource: UriComponents, content: number[]): TPromise<void>;
$write(handle: number, resource: UriComponents, base64Encoded: string): TPromise<void>;
$unlink(handle: number, resource: UriComponents): TPromise<void>;
$move(handle: number, resource: UriComponents, target: UriComponents): TPromise<IStat>;
$mkdir(handle: number, resource: UriComponents): TPromise<IStat>;

View File

@@ -10,6 +10,8 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import * as vscode from 'vscode';
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
import * as types from 'vs/workbench/api/node/extHostTypes';
import { IRawColorInfo } from 'vs/workbench/api/node/extHost.protocol';
import { ISingleEditOperation } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
@@ -177,7 +179,21 @@ export class ExtHostApiCommands {
args: [],
returns: 'An array of task handles'
});
this._register('vscode.executeDocumentColorProvider', this._executeDocumentColorProvider, {
description: 'Execute document color provider.',
args: [
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
],
returns: 'A promise that resolves to an array of ColorInformation objects.'
});
this._register('vscode.executeColorPresentationProvider', this._executeColorPresentationProvider, {
description: 'Execute color presentation provider.',
args: [
{ name: 'color', description: 'The color to show and insert', constraint: types.Color },
{ name: 'context', description: 'Context object with uri and range' }
],
returns: 'A promise that resolves to an array of ColorPresentation objects.'
});
this._register('vscode.previewHtml', (uri: URI, position?: vscode.ViewColumn, label?: string, options?: any) => {
return this._commands.executeCommand('_workbench.previewHtml',
uri,
@@ -391,6 +407,32 @@ export class ExtHostApiCommands {
});
}
private _executeDocumentColorProvider(resource: URI): Thenable<types.ColorInformation[]> {
const args = {
resource
};
return this._commands.executeCommand<IRawColorInfo[]>('_executeDocumentColorProvider', args).then(result => {
if (result) {
return result.map(ci => ({ range: typeConverters.toRange(ci.range), color: typeConverters.Color.to(ci.color) }));
}
return [];
});
}
private _executeColorPresentationProvider(color: types.Color, context: { uri: URI, range: types.Range }): Thenable<types.ColorPresentation[]> {
const args = {
resource: context.uri,
color: typeConverters.Color.from(color),
range: typeConverters.fromRange(context.range),
};
return this._commands.executeCommand<modes.IColorPresentation[]>('_executeColorPresentationProvider', args).then(result => {
if (result) {
return result.map(typeConverters.ColorPresentation.to);
}
return [];
});
}
private _executeDocumentSymbolProvider(resource: URI): Thenable<types.SymbolInformation[]> {
const args = {
resource

View File

@@ -107,12 +107,16 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
return isObject(target) ?
new Proxy(target, {
get: (target: any, property: string) => {
if (typeof property === 'string' && property.toLowerCase() === 'tojson') {
cloneTarget();
return () => clonedTarget;
}
if (clonedConfig) {
clonedTarget = clonedTarget ? clonedTarget : lookUp(clonedConfig, accessor);
return clonedTarget[property];
}
const result = target[property];
if (typeof property === 'string' && property.toLowerCase() !== 'tojson') {
if (typeof property === 'string') {
return cloneOnWriteProxy(result, `${accessor}.${property}`);
}
return result;

View File

@@ -43,6 +43,10 @@ export class ExtHostDecorations implements ExtHostDecorationsShape {
return TPromise.join(requests.map(request => {
const { handle, uri, id } = request;
const provider = this._provider.get(handle);
if (!provider) {
// might have been unregistered in the meantime
return void 0;
}
return asWinJsPromise(token => provider.provideDecoration(URI.revive(uri), token)).then(data => {
result[id] = data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source];
}, err => {

View File

@@ -137,6 +137,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
contentChanges: events.changes.map((change) => {
return {
range: TypeConverters.toRange(change.range),
rangeOffset: change.rangeOffset,
rangeLength: change.rangeLength,
text: change.text
};

View File

@@ -423,7 +423,7 @@ function getTelemetryActivationEvent(extensionDescription: IExtensionDescription
"TelemetryActivationEvent" : {
"id": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"publisherDisplayName": { "classification": "PublicPersonalData", "purpose": "FeatureInsight" },
"publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}

View File

@@ -15,6 +15,7 @@ import { IPatternInfo } from 'vs/platform/search/common/search';
import { values } from 'vs/base/common/map';
import { Range } from 'vs/workbench/api/node/extHostTypes';
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
import { IProgress } from 'vs/platform/progress/common/progress';
class FsLinkProvider implements vscode.DocumentLinkProvider {
@@ -109,15 +110,19 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
return asWinJsPromise(token => this._fsProvider.get(handle).stat(URI.revive(resource)));
}
$read(handle: number, session: number, offset: number, count: number, resource: UriComponents): TPromise<number> {
const progress = {
const progress: IProgress<Uint8Array> = {
report: chunk => {
this._proxy.$reportFileChunk(handle, session, [].slice.call(chunk));
let base64Chunk = Buffer.isBuffer(chunk)
? chunk.toString('base64')
: Buffer.from(chunk.buffer).toString('base64');
this._proxy.$reportFileChunk(handle, session, base64Chunk);
}
};
return asWinJsPromise(token => this._fsProvider.get(handle).read(URI.revive(resource), offset, count, progress));
}
$write(handle: number, resource: UriComponents, content: number[]): TPromise<void, any> {
return asWinJsPromise(token => this._fsProvider.get(handle).write(URI.revive(resource), Buffer.from(content)));
$write(handle: number, resource: UriComponents, base64Content: string): TPromise<void, any> {
return asWinJsPromise(token => this._fsProvider.get(handle).write(URI.revive(resource), Buffer.from(base64Content, 'base64')));
}
$unlink(handle: number, resource: UriComponents): TPromise<void, any> {
return asWinJsPromise(token => this._fsProvider.get(handle).unlink(URI.revive(resource)));

View File

@@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { mixin } from 'vs/base/common/objects';
import * as vscode from 'vscode';
import * as TypeConverters from 'vs/workbench/api/node/extHostTypeConverters';
import { Range, Disposable, CompletionList, SnippetString, Color, CodeActionKind } from 'vs/workbench/api/node/extHostTypes';
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind } from 'vs/workbench/api/node/extHostTypes';
import { ISingleEditOperation } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
@@ -780,7 +780,7 @@ class ColorProviderAdapter {
const colorInfos: IRawColorInfo[] = colors.map(ci => {
return {
color: [ci.color.red, ci.color.green, ci.color.blue, ci.color.alpha] as [number, number, number, number],
color: TypeConverters.Color.from(ci.color),
range: TypeConverters.fromRange(ci.range)
};
});
@@ -792,7 +792,7 @@ class ColorProviderAdapter {
provideColorPresentations(resource: URI, raw: IRawColorInfo): TPromise<modes.IColorPresentation[]> {
const document = this._documents.getDocumentData(resource).document;
const range = TypeConverters.toRange(raw.range);
const color = new Color(raw.color[0], raw.color[1], raw.color[2], raw.color[3]);
const color = TypeConverters.Color.to(raw.color);
return asWinJsPromise(token => this._provider.provideColorPresentations(color, { document, range }, token)).then(value => {
return value.map(TypeConverters.ColorPresentation.from);
});

View File

@@ -4,13 +4,14 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Progress, ProgressOptions } from 'vscode';
import { ProgressOptions } from 'vscode';
import { MainThreadProgressShape, ExtHostProgressShape } from './extHost.protocol';
import { ProgressLocation } from './extHostTypeConverters';
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
import { IProgressStep } from 'vs/platform/progress/common/progress';
import { IProgressStep, Progress } from 'vs/platform/progress/common/progress';
import { localize } from 'vs/nls';
import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation';
import { debounce } from 'vs/base/common/decorators';
export class ExtHostProgress implements ExtHostProgressShape {
@@ -37,12 +38,6 @@ export class ExtHostProgress implements ExtHostProgressShape {
this._mapHandleToCancellationSource.set(handle, source);
}
const progress = {
report: (p: IProgressStep) => {
this._proxy.$progressReport(handle, p);
}
};
const progressEnd = (handle: number): void => {
this._proxy.$progressEnd(handle);
this._mapHandleToCancellationSource.delete(handle);
@@ -54,7 +49,7 @@ export class ExtHostProgress implements ExtHostProgressShape {
let p: Thenable<R>;
try {
p = task(progress, cancellable ? source.token : CancellationToken.None);
p = task(new ProgressCallback(this._proxy, handle), cancellable ? source.token : CancellationToken.None);
} catch (err) {
progressEnd(handle);
throw err;
@@ -73,3 +68,23 @@ export class ExtHostProgress implements ExtHostProgressShape {
}
}
function mergeProgress(result: IProgressStep, currentValue: IProgressStep): IProgressStep {
result.message = currentValue.message;
if (typeof currentValue.increment === 'number' && typeof result.message === 'number') {
result.increment += currentValue.increment;
} else if (typeof currentValue.increment === 'number') {
result.increment = currentValue.increment;
}
return result;
}
class ProgressCallback extends Progress<IProgressStep> {
constructor(private _proxy: MainThreadProgressShape, private _handle: number) {
super(p => this.throttledReport(p));
}
@debounce(100, (result: IProgressStep, currentValue: IProgressStep) => mergeProgress(result, currentValue), () => Object.create(null))
throttledReport(p: IProgressStep): void {
this._proxy.$progressReport(this._handle, p);
}
}

View File

@@ -29,9 +29,10 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
this._commands = commands;
}
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Thenable<QuickPickItem[]>, options: QuickPickOptions & { canSelectMany: true; }, token?: CancellationToken): Thenable<QuickPickItem[] | undefined>;
showQuickPick(itemsOrItemsPromise: string[] | Thenable<string[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<string | undefined>;
showQuickPick(itemsOrItemsPromise: QuickPickItem[] | Thenable<QuickPickItem[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<QuickPickItem | undefined>;
showQuickPick(itemsOrItemsPromise: Item[] | Thenable<Item[]>, options?: QuickPickOptions, token: CancellationToken = CancellationToken.None): Thenable<Item | undefined> {
showQuickPick(itemsOrItemsPromise: Item[] | Thenable<Item[]>, options?: QuickPickOptions, token: CancellationToken = CancellationToken.None): Thenable<Item | Item[] | undefined> {
// clear state from last invocation
this._onDidSelectItem = undefined;
@@ -43,7 +44,8 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
placeHolder: options && options.placeHolder,
matchOnDescription: options && options.matchOnDescription,
matchOnDetail: options && options.matchOnDetail,
ignoreFocusLost: options && options.ignoreFocusOut
ignoreFocusLost: options && options.ignoreFocusOut,
canSelectMany: options && options.canPickMany
});
const promise = TPromise.any(<TPromise<number | Item[]>[]>[quickPickWidget, itemsPromise]).then(values => {
@@ -60,6 +62,7 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
let label: string;
let description: string;
let detail: string;
let picked: boolean;
if (typeof item === 'string') {
label = item;
@@ -67,12 +70,14 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
label = item.label;
description = item.description;
detail = item.detail;
picked = item.picked;
}
pickItems.push({
label,
description,
handle,
detail
detail,
picked
});
}
@@ -89,6 +94,8 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
return quickPickWidget.then(handle => {
if (typeof handle === 'number') {
return items[handle];
} else if (Array.isArray(handle)) {
return handle.map(h => items[h]);
}
return undefined;
});
@@ -98,7 +105,7 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
return TPromise.wrapError(err);
});
});
return wireCancellationToken<Item>(token, promise, true);
return wireCancellationToken<Item | Item[]>(token, promise, true);
}
$onItemSelected(handle: number): void {

View File

@@ -152,7 +152,7 @@ class ExtHostTreeView<T> extends Disposable {
private resolveTreeNode(element: T, parent?: TreeNode): TPromise<TreeNode> {
return asWinJsPromise(() => this.dataProvider.getTreeItem(element))
.then(extTreeItem => this.createHandle(element, extTreeItem, parent))
.then(extTreeItem => this.createHandle(element, extTreeItem, parent, true))
.then(handle => this.getChildren(parent ? parent.item.handle : null)
.then(() => {
const cachedElement = this.getExtensionElement(handle);
@@ -303,7 +303,7 @@ class ExtHostTreeView<T> extends Disposable {
return item;
}
private createHandle(element: T, { id, label, resourceUri }: vscode.TreeItem, parent?: TreeNode): TreeItemHandle {
private createHandle(element: T, { id, label, resourceUri }: vscode.TreeItem, parent: TreeNode, first?: boolean): TreeItemHandle {
if (id) {
return `${ExtHostTreeView.ID_HANDLE_PREFIX}/${id}`;
}
@@ -316,7 +316,7 @@ class ExtHostTreeView<T> extends Disposable {
for (let counter = 0; counter <= childrenNodes.length; counter++) {
const handle = `${prefix}/${counter}:${elementId}`;
if (!this.elements.has(handle) || existingHandle === handle) {
if (first || !this.elements.has(handle) || existingHandle === handle) {
return handle;
}
}

View File

@@ -83,7 +83,6 @@ export function fromPosition(position: types.Position): IPosition {
return { lineNumber: position.line + 1, column: position.character + 1 };
}
export function fromDiagnostic(value: vscode.Diagnostic): IMarkerData {
return {
...fromRange(value.range),
@@ -245,7 +244,7 @@ export const TextEdit = {
range: fromRange(edit.range)
};
},
to(edit: modes.TextEdit): vscode.TextEdit {
to(edit: modes.TextEdit): types.TextEdit {
let result = new types.TextEdit(toRange(edit.range), edit.text);
result.newEol = EndOfLine.to(edit.eol);
return result;
@@ -547,12 +546,15 @@ export namespace DocumentLink {
}
export namespace ColorPresentation {
export function to(colorPresentation: modes.IColorPresentation): vscode.ColorPresentation {
return {
label: colorPresentation.label,
textEdit: colorPresentation.textEdit ? TextEdit.to(colorPresentation.textEdit) : undefined,
additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => TextEdit.to(value)) : undefined
};
export function to(colorPresentation: modes.IColorPresentation): types.ColorPresentation {
let cp = new types.ColorPresentation(colorPresentation.label);
if (colorPresentation.textEdit) {
cp.textEdit = TextEdit.to(colorPresentation.textEdit);
}
if (colorPresentation.additionalTextEdits) {
cp.additionalTextEdits = colorPresentation.additionalTextEdits.map(value => TextEdit.to(value));
}
return cp;
}
export function from(colorPresentation: vscode.ColorPresentation): modes.IColorPresentation {
@@ -564,6 +566,15 @@ export namespace ColorPresentation {
}
}
export namespace Color {
export function to(c: [number, number, number, number]): types.Color {
return new types.Color(c[0], c[1], c[2], c[3]);
}
export function from(color: types.Color): [number, number, number, number] {
return [color.red, color.green, color.blue, color.alpha];
}
}
export namespace TextDocumentSaveReason {
export function to(reason: SaveReason): vscode.TextDocumentSaveReason {

View File

@@ -9,10 +9,14 @@ import { Event, Emitter } from 'vs/base/common/event';
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
import { Position } from 'vs/platform/editor/common/editor';
import { TPromise } from 'vs/base/common/winjs.base';
import * as types from './extHostTypes';
import { ExtHostTextEditor } from './extHostTextEditor';
export class ExtHostWebview implements vscode.Webview {
private readonly _handle: WebviewHandle;
private readonly _viewType: string;
private readonly _proxy: MainThreadWebviewsShape;
private _title: string;
private _html: string;
private _options: vscode.WebviewOptions;
@@ -30,12 +34,14 @@ export class ExtHostWebview implements vscode.Webview {
public readonly onDidChangeViewState: Event<vscode.WebViewOnDidChangeViewStateEvent> = this.onDidChangeViewStateEmitter.event;
constructor(
private readonly _handle: WebviewHandle,
private readonly _proxy: MainThreadWebviewsShape,
handle: WebviewHandle,
proxy: MainThreadWebviewsShape,
viewType: string,
viewColumn: vscode.ViewColumn,
options: vscode.WebviewOptions
) {
this._handle = handle;
this._proxy = proxy;
this._viewType = viewType;
this._viewColumn = viewColumn;
this._options = options;
@@ -128,16 +134,15 @@ export class ExtHostWebview implements vscode.Webview {
}
export class ExtHostWebviews implements ExtHostWebviewsShape {
private static handlePool = 1;
private static webviewHandlePool = 1;
private readonly _proxy: MainThreadWebviewsShape;
private readonly _webviews = new Map<WebviewHandle, ExtHostWebview>();
private _activeWebview: ExtHostWebview | undefined;
private readonly _serializers = new Map<string, vscode.WebviewSerializer>();
constructor(
mainContext: IMainContext
mainContext: IMainContext,
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadWebviews);
}
@@ -149,7 +154,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
options: vscode.WebviewOptions,
extensionFolderPath: string
): vscode.Webview {
const handle = ExtHostWebviews.handlePool++;
const handle = ExtHostWebviews.webviewHandlePool++ + '';
this._proxy.$createWebview(handle, viewType, title, typeConverters.fromViewColumn(viewColumn), options, extensionFolderPath);
const webview = new ExtHostWebview(handle, this._proxy, viewType, viewColumn, options);
@@ -157,6 +162,32 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
return webview;
}
registerWebviewSerializer(
viewType: string,
serializer: vscode.WebviewSerializer
): vscode.Disposable {
if (this._serializers.has(viewType)) {
throw new Error(`Serializer for '${viewType}' already registered`);
}
this._serializers.set(viewType, serializer);
this._proxy.$registerSerializer(viewType);
return new types.Disposable(() => {
this._serializers.delete(viewType);
this._proxy.$unregisterSerializer(viewType);
});
}
async showWebviewWidget(editor: vscode.TextEditor, position: vscode.Position, viewType: string, title: string, options: vscode.WebviewOptions) {
const handle = ExtHostWebviews.webviewHandlePool++ + '';
this._proxy.$showWebviewWidget(handle, (editor as ExtHostTextEditor).id, typeConverters.fromPosition(new types.Position(position.line, position.character)), viewType, options);
const webview = new ExtHostWebview(handle, this._proxy, viewType, undefined, options);
this._webviews.set(handle, webview);
return webview;
}
$onMessage(handle: WebviewHandle, message: any): void {
const webview = this.getWebview(handle);
if (webview) {
@@ -164,21 +195,14 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
}
}
$onDidChangeActiveWeview(handle: WebviewHandle | undefined): void {
if (handle) {
const webview = this.getWebview(handle);
if (webview) {
if (webview !== this._activeWebview) {
this._activeWebview = webview;
webview.active = true;
webview.onDidChangeViewStateEmitter.fire({ viewColumn: webview.viewColumn, active: true });
}
}
} else {
if (this._activeWebview) {
this._activeWebview.active = false;
this._activeWebview.onDidChangeViewStateEmitter.fire({ viewColumn: this._activeWebview.viewColumn, active: false });
this._activeWebview = undefined;
$onDidChangeWeviewViewState(handle: WebviewHandle, active: boolean, position: Position): void {
const webview = this.getWebview(handle);
if (webview) {
const viewColumn = typeConverters.toViewColumn(position);
if (webview.active !== active || webview.viewColumn !== viewColumn) {
webview.active = active;
webview.viewColumn = viewColumn;
webview.onDidChangeViewStateEmitter.fire({ active, viewColumn });
}
}
}
@@ -188,28 +212,44 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
if (webview) {
webview.onDisposeEmitter.fire();
this._webviews.delete(handle);
if (this._activeWebview === webview) {
this._activeWebview = undefined;
}
}
return TPromise.as(void 0);
}
$onDidChangePosition(handle: WebviewHandle, newPosition: Position): void {
const webview = this.getWebview(handle);
if (webview) {
const newViewColumn = typeConverters.toViewColumn(newPosition);
if (webview.viewColumn !== newViewColumn) {
webview.viewColumn = newViewColumn;
webview.onDidChangeViewStateEmitter.fire({ viewColumn: newViewColumn, active: webview.active });
}
$deserializeWebview(
webviewHandle: WebviewHandle,
viewType: string,
state: any,
position: Position,
options: vscode.WebviewOptions
): Thenable<void> {
const serializer = this._serializers.get(viewType);
if (!serializer) {
return TPromise.wrapError(new Error(`No serializer found for '${viewType}'`));
}
const revivedWebview = new ExtHostWebview(webviewHandle, this._proxy, viewType, typeConverters.toViewColumn(position), options);
this._webviews.set(webviewHandle, revivedWebview);
return serializer.deserializeWebview(revivedWebview, state);
}
private readonly _onDidChangeActiveWebview = new Emitter<ExtHostWebview | undefined>();
public readonly onDidChangeActiveWebview = this._onDidChangeActiveWebview.event;
$serializeWebview(
webviewHandle: WebviewHandle
): Thenable<any> {
const webview = this.getWebview(webviewHandle);
if (!webview) {
return TPromise.as(undefined);
}
private getWebview(handle: WebviewHandle) {
const serialzer = this._serializers.get(webview.viewType);
if (!serialzer) {
return TPromise.as(undefined);
}
return serialzer.serializeWebview(webview);
}
private getWebview(handle: WebviewHandle): ExtHostWebview | undefined {
return this._webviews.get(handle);
}
}