diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts
index 704d2f115ed..d8951eeb6bd 100644
--- a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts
+++ b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts
@@ -196,7 +196,7 @@ suite('vscode API - webview', () => {
const firstResponse = getMesssage(webview);
- assert.strictEqual((await firstResponse).value, 100);
+ assert.strictEqual(Math.round((await firstResponse).value), 100);
// Swap away from the webview
const doc = await vscode.workspace.openTextDocument(testDocument);
@@ -207,7 +207,7 @@ suite('vscode API - webview', () => {
// We should still have old scroll pos
const secondResponse = await sendRecieveMessage(webview, { type: 'get' });
- assert.strictEqual(secondResponse.value, 100);
+ assert.strictEqual(Math.round(secondResponse.value), 100);
});
conditionalTest('webviews with retainContextWhenHidden should be able to recive messages while hidden', async () => {
@@ -252,29 +252,29 @@ suite('vscode API - webview', () => {
});
`);
- async function asWebviewUri(path: string) {
- const root = await webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath!));
+ function asWebviewUri(path: string) {
+ const root = webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath!));
return root.toString() + path;
}
{
- const imagePath = await asWebviewUri('/image.png');
+ const imagePath = asWebviewUri('/image.png');
const response = sendRecieveMessage(webview, { src: imagePath });
assert.strictEqual((await response).value, true);
}
{
- const imagePath = await asWebviewUri('/no-such-image.png');
+ const imagePath = asWebviewUri('/no-such-image.png');
const response = sendRecieveMessage(webview, { src: imagePath });
assert.strictEqual((await response).value, false);
}
{
- const imagePath = vscode.Uri.file(join(vscode.workspace.rootPath!, '..', '..', '..', 'resources', 'linux', 'code.png')).with({ scheme: 'vscode-resource' });
+ const imagePath = webview.webview.asWebviewUri(vscode.Uri.file(join(vscode.workspace.rootPath!, '..', '..', '..', 'resources', 'linux', 'code.png')));
const response = sendRecieveMessage(webview, { src: imagePath.toString() });
assert.strictEqual((await response).value, false);
}
});
- conditionalTest('webviews should allow overriding allowed resource paths using localResourceRoots', async () => {
+ test('webviews should allow overriding allowed resource paths using localResourceRoots', async () => {
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {
enableScripts: true,
localResourceRoots: [vscode.Uri.file(join(vscode.workspace.rootPath!, 'sub'))]
@@ -292,18 +292,38 @@ suite('vscode API - webview', () => {
});
`);
- const workspaceRootUri = vscode.Uri.file(vscode.workspace.rootPath!).with({ scheme: 'vscode-resource' });
-
{
- const response = sendRecieveMessage(webview, { src: workspaceRootUri.toString() + '/sub/image.png' });
+ const response = sendRecieveMessage(webview, { src: webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath! + '/sub/image.png')).toString() });
assert.strictEqual((await response).value, true);
}
{
- const response = sendRecieveMessage(webview, { src: workspaceRootUri.toString() + '/image.png' });
+ const response = sendRecieveMessage(webview, { src: webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath! + '/image.png')).toString() });
assert.strictEqual((await response).value, false);
}
});
+ conditionalTest('webviews using hard-coded old style vscode-resource uri should work', async () => {
+ const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {
+ enableScripts: true,
+ localResourceRoots: [vscode.Uri.file(join(vscode.workspace.rootPath!, 'sub'))]
+ }));
+
+ const imagePath = vscode.Uri.file(join(vscode.workspace.rootPath!, 'sub', 'image.png')).with({ scheme: 'vscode-resource' }).toString();
+
+ webview.webview.html = createHtmlDocumentWithBody(/*html*/`
+
+ `);
+
+ const firstResponse = getMesssage(webview);
+
+ assert.strictEqual((await firstResponse).value, true);
+ });
+
test('webviews should have real view column after they are created, #56097', async () => {
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.Active }, { enableScripts: true }));
diff --git a/src/vs/platform/webview/common/resourceLoader.ts b/src/vs/platform/webview/common/resourceLoader.ts
index b9f9fcb1c99..0873dcdd038 100644
--- a/src/vs/platform/webview/common/resourceLoader.ts
+++ b/src/vs/platform/webview/common/resourceLoader.ts
@@ -114,8 +114,11 @@ function normalizeRequestPath(requestUri: URI) {
return requestUri;
}
- // The `vscode-webview-resource` schemes encodes both the scheme and uri:
- const resourceUri = URI.parse(requestUri.path.replace(/\/+(\w+)\/\//, '$1://'));
+ // The `vscode-webview-resource` scheme has the following format:
+ //
+ // vscode-webview-resource://id/scheme//authority?/path
+ //
+ const resourceUri = URI.parse(requestUri.path.replace(/^\/(\w+)\/{1,2}/, '$1://'));
return resourceUri.with({
query: requestUri.query,
fragment: requestUri.fragment
diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts
index 6d3c9f7cdc5..863d7efe3a8 100644
--- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts
+++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts
@@ -390,9 +390,13 @@ export class ElectronWebviewBasedWebview extends BaseWebview impleme
return value
.replace(/(["'])vscode-resource:(\/\/([^\s\/'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (match, startQuote, _1, scheme, path, endQuote) => {
if (scheme) {
- return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}//${scheme}${path}${endQuote}`;
+ return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}/${scheme}${path}${endQuote}`;
}
- return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}//file${path}${endQuote}`;
+ if (!path.startsWith('//')) {
+ // Add an empty authority if we don't already have one
+ path = '//' + path;
+ }
+ return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}/file${path}${endQuote}`;
});
}