提交 f963c9a2 编写于 作者: M Matt Bierner

Adding tests and changing how toWebviewResource works

- Allow placeholders in the webviewEndpoint. This is required to support serving each webview from its own origin
- Add tests for toWebviewResource
上级 9a76b14f
...@@ -278,7 +278,7 @@ export class EnvironmentService implements IEnvironmentService { ...@@ -278,7 +278,7 @@ export class EnvironmentService implements IEnvironmentService {
get driverHandle(): string | undefined { return this._args['driver']; } get driverHandle(): string | undefined { return this._args['driver']; }
get driverVerbose(): boolean { return !!this._args['driver-verbose']; } get driverVerbose(): boolean { return !!this._args['driver-verbose']; }
readonly webviewResourceRoot = 'vscode-resource:'; readonly webviewResourceRoot = 'vscode-resource:{{resource}}';
readonly webviewCspRule = 'vscode-resource:'; readonly webviewCspRule = 'vscode-resource:';
constructor(private _args: ParsedArgs, private _execPath: string) { constructor(private _args: ParsedArgs, private _execPath: string) {
......
...@@ -11,6 +11,7 @@ import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; ...@@ -11,6 +11,7 @@ import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { ExtHostEditorInsetsShape, MainThreadEditorInsetsShape } from './extHost.protocol'; import { ExtHostEditorInsetsShape, MainThreadEditorInsetsShape } from './extHost.protocol';
import { toWebviewResource, WebviewInitData } from 'vs/workbench/api/common/shared/webview'; import { toWebviewResource, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import { generateUuid } from 'vs/base/common/uuid';
export class ExtHostEditorInsets implements ExtHostEditorInsetsShape { export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
...@@ -60,11 +61,12 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape { ...@@ -60,11 +61,12 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
const webview = new class implements vscode.Webview { const webview = new class implements vscode.Webview {
private readonly _uuid = generateUuid();
private _html: string = ''; private _html: string = '';
private _options: vscode.WebviewOptions; private _options: vscode.WebviewOptions;
toWebviewResource(resource: vscode.Uri): vscode.Uri { toWebviewResource(resource: vscode.Uri): vscode.Uri {
return toWebviewResource(that._initData, resource); return toWebviewResource(that._initData, this._uuid, resource);
} }
get cspRule(): string { get cspRule(): string {
......
...@@ -13,40 +13,36 @@ import { Disposable } from './extHostTypes'; ...@@ -13,40 +13,36 @@ import { Disposable } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as modes from 'vs/editor/common/modes'; import * as modes from 'vs/editor/common/modes';
import { WebviewInitData, toWebviewResource } from 'vs/workbench/api/common/shared/webview'; import { WebviewInitData, toWebviewResource } from 'vs/workbench/api/common/shared/webview';
import { generateUuid } from 'vs/base/common/uuid';
type IconPath = URI | { light: URI, dark: URI }; type IconPath = URI | { light: URI, dark: URI };
export class ExtHostWebview implements vscode.Webview { export class ExtHostWebview implements vscode.Webview {
private readonly _handle: WebviewPanelHandle; private readonly _uuid: string = generateUuid();
private readonly _proxy: MainThreadWebviewsShape;
private _html: string; private _html: string;
private _options: vscode.WebviewOptions;
private _isDisposed: boolean = false; private _isDisposed: boolean = false;
public readonly _onMessageEmitter = new Emitter<any>(); public readonly _onMessageEmitter = new Emitter<any>();
public readonly onDidReceiveMessage: Event<any> = this._onMessageEmitter.event; public readonly onDidReceiveMessage: Event<any> = this._onMessageEmitter.event;
constructor( constructor(
handle: WebviewPanelHandle, private readonly _handle: WebviewPanelHandle,
proxy: MainThreadWebviewsShape, private readonly _proxy: MainThreadWebviewsShape,
options: vscode.WebviewOptions, private _options: vscode.WebviewOptions,
private readonly initData: WebviewInitData private readonly _initData: WebviewInitData
) { ) { }
this._handle = handle;
this._proxy = proxy;
this._options = options;
}
public dispose() { public dispose() {
this._onMessageEmitter.dispose(); this._onMessageEmitter.dispose();
} }
public toWebviewResource(resource: vscode.Uri): vscode.Uri { public toWebviewResource(resource: vscode.Uri): vscode.Uri {
return toWebviewResource(this.initData, resource); return toWebviewResource(this._initData, this._uuid, resource);
} }
public get cspRule(): string { public get cspRule(): string {
return this.initData.webviewCspRule; return this._initData.webviewCspRule;
} }
public get html(): string { public get html(): string {
......
...@@ -13,12 +13,12 @@ export interface WebviewInitData { ...@@ -13,12 +13,12 @@ export interface WebviewInitData {
export function toWebviewResource( export function toWebviewResource(
initData: WebviewInitData, initData: WebviewInitData,
uuid: string,
resource: vscode.Uri resource: vscode.Uri
): vscode.Uri { ): vscode.Uri {
const rootUri = URI.parse(initData.webviewResourceRoot); const uri = initData.webviewResourceRoot
return rootUri.with({ .replace('{{resource}}', resource.toString().replace(/^\S+?:/, ''))
path: rootUri.path + resource.path, .replace('{{uuid}}', uuid);
query: resource.query,
fragment: resource.fragment, return URI.parse(uri);
});
} }
...@@ -147,7 +147,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { ...@@ -147,7 +147,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService {
webviewEndpoint?: string; webviewEndpoint?: string;
get webviewResourceRoot(): string { get webviewResourceRoot(): string {
return this.webviewEndpoint ? this.webviewEndpoint + '/vscode-resource' : 'vscode-resource:'; return this.webviewEndpoint ? this.webviewEndpoint + '/vscode-resource{{resource}}' : 'vscode-resource:{{resource}}';
} }
get webviewCspRule(): string { get webviewCspRule(): string {
......
...@@ -50,7 +50,10 @@ suite('ExtHostWebview', () => { ...@@ -50,7 +50,10 @@ suite('ExtHostWebview', () => {
test('toWebviewResource for desktop vscode-resource scheme', () => { test('toWebviewResource for desktop vscode-resource scheme', () => {
const shape = createNoopMainThreadWebviews(); const shape = createNoopMainThreadWebviews();
const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), { webviewCspRule: '', webviewResourceRoot: 'vscode-resource:' }); const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), {
webviewCspRule: '',
webviewResourceRoot: 'vscode-resource:{{resource}}'
});
const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {}); const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {});
assert.strictEqual( assert.strictEqual(
...@@ -58,6 +61,7 @@ suite('ExtHostWebview', () => { ...@@ -58,6 +61,7 @@ suite('ExtHostWebview', () => {
'vscode-resource:/Users/codey/file.html', 'vscode-resource:/Users/codey/file.html',
'Unix basic' 'Unix basic'
); );
assert.strictEqual( assert.strictEqual(
webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString(), webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString(),
'vscode-resource:/Users/codey/file.html#frag', 'vscode-resource:/Users/codey/file.html#frag',
...@@ -70,12 +74,11 @@ suite('ExtHostWebview', () => { ...@@ -70,12 +74,11 @@ suite('ExtHostWebview', () => {
'Unix with encoding' 'Unix with encoding'
); );
// TODO: Fix for #48403 assert.strictEqual(
// assert.strictEqual( webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString(),
// webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString(), 'vscode-resource://localhost/Users/codey/file.html',
// 'vscode-resource:/Users/codey/file.html', 'Unix should preserve authority'
// 'Unix should preserve authority' );
// );
assert.strictEqual( assert.strictEqual(
webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString(), webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString(),
...@@ -83,6 +86,50 @@ suite('ExtHostWebview', () => { ...@@ -83,6 +86,50 @@ suite('ExtHostWebview', () => {
'Windows C drive' 'Windows C drive'
); );
}); });
test('toWebviewResource for web endpoint', () => {
const shape = createNoopMainThreadWebviews();
const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), {
webviewCspRule: '',
webviewResourceRoot: `https://{{uuid}}.webview.contoso.com/commit{{resource}}`
});
const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {});
function stripEndpointUuid(input: string) {
return input.replace(/^https:\/\/[^\.]+?\./, '');
}
assert.strictEqual(
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html')).toString()),
'webview.contoso.com/commit///Users/codey/file.html',
'Unix basic'
);
assert.strictEqual(
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString()),
'webview.contoso.com/commit///Users/codey/file.html#frag',
'Unix should preserve fragment'
);
assert.strictEqual(
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/f%20ile.html')).toString()),
'webview.contoso.com/commit///Users/codey/f%20ile.html',
'Unix with encoding'
);
assert.strictEqual(
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString()),
'webview.contoso.com/commit//localhost/Users/codey/file.html',
'Unix should preserve authority'
);
assert.strictEqual(
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString()),
'webview.contoso.com/commit///c%3A/codey/file.txt',
'Windows C drive'
);
});
}); });
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册