mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-26 11:38:51 +01:00
Merge remote-tracking branch 'upstream/mjbvz/webviewWidgetProto' into rebornix/review
This commit is contained in:
@@ -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);
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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" }
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user