Skip to content

Commit c5dc9d1

Browse files
committed
Finalize asWebviewUri api
Fixes microsoft#79242 As discussed, renames `toWebviewResource` to `asWebviewUri` to be consistent with the `asAbsolutePath` api naming
1 parent 7af2ebb commit c5dc9d1

File tree

10 files changed

+59
-66
lines changed

10 files changed

+59
-66
lines changed

extensions/markdown-language-features/src/features/preview.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,8 @@ export class MarkdownPreview extends Disposable {
439439
if (this._resource === markdownResource) {
440440
const self = this;
441441
const resourceProvider: WebviewResourceProvider = {
442-
toWebviewResource: (resource) => {
443-
return this.editor.webview.toWebviewResource(normalizeResource(markdownResource, resource));
442+
asWebviewUri: (resource) => {
443+
return this.editor.webview.asWebviewUri(normalizeResource(markdownResource, resource));
444444
},
445445
get cspSource() { return self.editor.webview.cspSource; }
446446
};

extensions/markdown-language-features/src/features/previewContentProvider.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class MarkdownContentProvider {
6565
scrollEditorWithPreview: config.scrollEditorWithPreview,
6666
doubleClickToSwitchToEditor: config.doubleClickToSwitchToEditor,
6767
disableSecurityWarnings: this.cspArbiter.shouldDisableSecurityWarnings(),
68-
webviewResourceRoot: resourceProvider.toWebviewResource(markdownDocument.uri).toString(),
68+
webviewResourceRoot: resourceProvider.asWebviewUri(markdownDocument.uri).toString(),
6969
};
7070

7171
this.logger.log('provideTextDocumentContent', initialData);
@@ -86,7 +86,7 @@ export class MarkdownContentProvider {
8686
data-state="${escapeAttribute(JSON.stringify(state || {}))}">
8787
<script src="${this.extensionResourcePath(resourceProvider, 'pre.js')}" nonce="${nonce}"></script>
8888
${this.getStyles(resourceProvider, sourceUri, config, state)}
89-
<base href="${resourceProvider.toWebviewResource(markdownDocument.uri)}">
89+
<base href="${resourceProvider.asWebviewUri(markdownDocument.uri)}">
9090
</head>
9191
<body class="vscode-body ${config.scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${config.wordWrap ? 'wordWrap' : ''} ${config.markEditorSelection ? 'showEditorSelection' : ''}">
9292
${body}
@@ -110,7 +110,7 @@ export class MarkdownContentProvider {
110110
}
111111

112112
private extensionResourcePath(resourceProvider: WebviewResourceProvider, mediaFile: string): string {
113-
const webviewResource = resourceProvider.toWebviewResource(
113+
const webviewResource = resourceProvider.asWebviewUri(
114114
vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile))));
115115
return webviewResource.toString();
116116
}
@@ -126,17 +126,17 @@ export class MarkdownContentProvider {
126126

127127
// Assume it must be a local file
128128
if (path.isAbsolute(href)) {
129-
return resourceProvider.toWebviewResource(vscode.Uri.file(href)).toString();
129+
return resourceProvider.asWebviewUri(vscode.Uri.file(href)).toString();
130130
}
131131

132132
// Use a workspace relative path if there is a workspace
133133
const root = vscode.workspace.getWorkspaceFolder(resource);
134134
if (root) {
135-
return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString();
135+
return resourceProvider.asWebviewUri(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString();
136136
}
137137

138138
// Otherwise look relative to the markdown file
139-
return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString();
139+
return resourceProvider.asWebviewUri(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString();
140140
}
141141

142142
private computeCustomStyleSheetIncludes(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration): string {
@@ -176,7 +176,7 @@ export class MarkdownContentProvider {
176176
private getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, state?: any): string {
177177
const baseStyles: string[] = [];
178178
for (const resource of this.contributionProvider.contributions.previewStyles) {
179-
baseStyles.push(`<link rel="stylesheet" type="text/css" href="${escapeAttribute(resourceProvider.toWebviewResource(resource))}">`);
179+
baseStyles.push(`<link rel="stylesheet" type="text/css" href="${escapeAttribute(resourceProvider.asWebviewUri(resource))}">`);
180180
}
181181

182182
return `${baseStyles.join('\n')}
@@ -188,7 +188,7 @@ export class MarkdownContentProvider {
188188
const out: string[] = [];
189189
for (const resource of this.contributionProvider.contributions.previewScripts) {
190190
out.push(`<script async
191-
src="${escapeAttribute(resourceProvider.toWebviewResource(resource))}"
191+
src="${escapeAttribute(resourceProvider.asWebviewUri(resource))}"
192192
nonce="${nonce}"
193193
charset="UTF-8"></script>`);
194194
}

extensions/markdown-language-features/src/util/resources.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import * as vscode from 'vscode';
77

88
export interface WebviewResourceProvider {
9-
toWebviewResource(resource: vscode.Uri): vscode.Uri;
9+
asWebviewUri(resource: vscode.Uri): vscode.Uri;
1010

1111
readonly cspSource: string;
1212
}
@@ -30,4 +30,4 @@ export function normalizeResource(
3030
}
3131
}
3232
return resource;
33-
}
33+
}

extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -251,18 +251,18 @@ suite('Webview tests', () => {
251251
});
252252
</script>`);
253253

254-
async function toWebviewResource(path: string) {
255-
const root = await webview.webview.toWebviewResource(vscode.Uri.file(vscode.workspace.rootPath!));
254+
async function asWebviewUri(path: string) {
255+
const root = await webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath!));
256256
return root.toString() + path;
257257
}
258258

259259
{
260-
const imagePath = await toWebviewResource('/image.png');
260+
const imagePath = await asWebviewUri('/image.png');
261261
const response = sendRecieveMessage(webview, { src: imagePath });
262262
assert.strictEqual((await response).value, true);
263263
}
264264
{
265-
const imagePath = await toWebviewResource('/no-such-image.png');
265+
const imagePath = await asWebviewUri('/no-such-image.png');
266266
const response = sendRecieveMessage(webview, { src: imagePath });
267267
assert.strictEqual((await response).value, false);
268268
}

src/vs/vscode.d.ts

+24
Original file line numberDiff line numberDiff line change
@@ -5923,6 +5923,30 @@ declare module 'vscode' {
59235923
* @param message Body of the message.
59245924
*/
59255925
postMessage(message: any): Thenable<boolean>;
5926+
5927+
/**
5928+
* Convert a uri for the local file system to one that can be used inside webviews.
5929+
*
5930+
* Webviews cannot directly load resoruces from the workspace or local file system using `file:` uris. The
5931+
* `asWebviewUri` function takes a local `file:` uri and converts it into a uri that can be used inside of
5932+
* a webview to load the same resource:
5933+
*
5934+
* ```ts
5935+
* webview.html = `<img src="${webview.asWebviewUri(vscode.Uri.file('/Users/codey/workspace/cat.gif'))}">`
5936+
* ```
5937+
*/
5938+
asWebviewUri(localResource: Uri): Uri;
5939+
5940+
/**
5941+
* Content security policy source for webview resources.
5942+
*
5943+
* This is the origin that should be used in a content security policy rule:
5944+
*
5945+
* ```
5946+
* img-src https: ${webview.cspSource} ...;
5947+
* ```
5948+
*/
5949+
readonly cspSource: string;
59265950
}
59275951

59285952
/**

src/vs/vscode.proposed.d.ts

-31
Original file line numberDiff line numberDiff line change
@@ -1141,35 +1141,4 @@ declare module 'vscode' {
11411141
}
11421142

11431143
//#endregion
1144-
1145-
//#region Webview Resource Roots
1146-
1147-
export interface Webview {
1148-
/**
1149-
* Convert a uri for the local file system to one that can be used inside webviews.
1150-
*
1151-
* Webviews cannot directly load resoruces from the workspace or local file system using `file:` uris. The
1152-
* `toWebviewResource` function takes a local `file:` uri and converts it into a uri that can be used inside of
1153-
* a webview to load the same resource:
1154-
*
1155-
* ```ts
1156-
* webview.html = `<img src="${webview.toWebviewResource(vscode.Uri.file('/Users/codey/workspace/cat.gif'))}">`
1157-
* ```
1158-
*/
1159-
toWebviewResource(localResource: Uri): Uri;
1160-
1161-
/**
1162-
* Content security policy source for webview resources.
1163-
*
1164-
* This is the origin that should be used in a content security policy rule:
1165-
*
1166-
* ```
1167-
* img-src https: ${webview.cspSource} ...;
1168-
* ```
1169-
*/
1170-
readonly cspSource: string;
1171-
}
1172-
1173-
//#endregion
1174-
11751144
}

src/vs/workbench/api/common/extHostCodeInsets.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor';
1010
import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors';
1111
import * as vscode from 'vscode';
1212
import { ExtHostEditorInsetsShape, MainThreadEditorInsetsShape } from './extHost.protocol';
13-
import { toWebviewResource, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
13+
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
1414
import { generateUuid } from 'vs/base/common/uuid';
1515

1616
export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
@@ -65,8 +65,8 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
6565
private _html: string = '';
6666
private _options: vscode.WebviewOptions = Object.create(null);
6767

68-
toWebviewResource(resource: vscode.Uri): vscode.Uri {
69-
return toWebviewResource(that._initData, this._uuid, resource);
68+
asWebviewUri(resource: vscode.Uri): vscode.Uri {
69+
return asWebviewUri(that._initData, this._uuid, resource);
7070
}
7171

7272
get cspSource(): string {

src/vs/workbench/api/common/extHostWebview.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShap
1212
import { Disposable } from './extHostTypes';
1313
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
1414
import * as modes from 'vs/editor/common/modes';
15-
import { WebviewInitData, toWebviewResource } from 'vs/workbench/api/common/shared/webview';
15+
import { WebviewInitData, asWebviewUri } from 'vs/workbench/api/common/shared/webview';
1616
import { generateUuid } from 'vs/base/common/uuid';
1717

1818
type IconPath = URI | { light: URI, dark: URI };
@@ -35,8 +35,8 @@ export class ExtHostWebview implements vscode.Webview {
3535
this._onMessageEmitter.dispose();
3636
}
3737

38-
public toWebviewResource(resource: vscode.Uri): vscode.Uri {
39-
return toWebviewResource(this._initData, this._handle, resource);
38+
public asWebviewUri(resource: vscode.Uri): vscode.Uri {
39+
return asWebviewUri(this._initData, this._handle, resource);
4040
}
4141

4242
public get cspSource(): string {

src/vs/workbench/api/common/shared/webview.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface WebviewInitData {
1111
readonly webviewCspSource: string;
1212
}
1313

14-
export function toWebviewResource(
14+
export function asWebviewUri(
1515
initData: WebviewInitData,
1616
uuid: string,
1717
resource: vscode.Uri

src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts

+12-12
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ suite('ExtHostWebview', () => {
4848
assert.strictEqual(lastInvokedDeserializer, serializerB);
4949
});
5050

51-
test('toWebviewResource for desktop vscode-resource scheme', () => {
51+
test('asWebviewUri for desktop vscode-resource scheme', () => {
5252
const shape = createNoopMainThreadWebviews();
5353
const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), {
5454
webviewCspSource: '',
@@ -57,37 +57,37 @@ suite('ExtHostWebview', () => {
5757
const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {});
5858

5959
assert.strictEqual(
60-
webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html')).toString(),
60+
webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString(),
6161
'vscode-resource:/Users/codey/file.html',
6262
'Unix basic'
6363
);
6464

6565
assert.strictEqual(
66-
webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString(),
66+
webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html#frag')).toString(),
6767
'vscode-resource:/Users/codey/file.html#frag',
6868
'Unix should preserve fragment'
6969
);
7070

7171
assert.strictEqual(
72-
webview.webview.toWebviewResource(URI.parse('file:///Users/codey/f%20ile.html')).toString(),
72+
webview.webview.asWebviewUri(URI.parse('file:///Users/codey/f%20ile.html')).toString(),
7373
'vscode-resource:/Users/codey/f%20ile.html',
7474
'Unix with encoding'
7575
);
7676

7777
assert.strictEqual(
78-
webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString(),
78+
webview.webview.asWebviewUri(URI.parse('file://localhost/Users/codey/file.html')).toString(),
7979
'vscode-resource://localhost/Users/codey/file.html',
8080
'Unix should preserve authority'
8181
);
8282

8383
assert.strictEqual(
84-
webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString(),
84+
webview.webview.asWebviewUri(URI.parse('file:///c:/codey/file.txt')).toString(),
8585
'vscode-resource:/c%3A/codey/file.txt',
8686
'Windows C drive'
8787
);
8888
});
8989

90-
test('toWebviewResource for web endpoint', () => {
90+
test('asWebviewUri for web endpoint', () => {
9191
const shape = createNoopMainThreadWebviews();
9292

9393
const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), {
@@ -101,31 +101,31 @@ suite('ExtHostWebview', () => {
101101
}
102102

103103
assert.strictEqual(
104-
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html')).toString()),
104+
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString()),
105105
'webview.contoso.com/commit///Users/codey/file.html',
106106
'Unix basic'
107107
);
108108

109109
assert.strictEqual(
110-
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString()),
110+
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html#frag')).toString()),
111111
'webview.contoso.com/commit///Users/codey/file.html#frag',
112112
'Unix should preserve fragment'
113113
);
114114

115115
assert.strictEqual(
116-
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/f%20ile.html')).toString()),
116+
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/f%20ile.html')).toString()),
117117
'webview.contoso.com/commit///Users/codey/f%20ile.html',
118118
'Unix with encoding'
119119
);
120120

121121
assert.strictEqual(
122-
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString()),
122+
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file://localhost/Users/codey/file.html')).toString()),
123123
'webview.contoso.com/commit//localhost/Users/codey/file.html',
124124
'Unix should preserve authority'
125125
);
126126

127127
assert.strictEqual(
128-
stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString()),
128+
stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///c:/codey/file.txt')).toString()),
129129
'webview.contoso.com/commit///c%3A/codey/file.txt',
130130
'Windows C drive'
131131
);

0 commit comments

Comments
 (0)