Skip to content

Commit 0af3fc7

Browse files
committed
Fixing rewriting of some old-style vscode-resource uris that don't have explicit authorities
1 parent 8536102 commit 0af3fc7

3 files changed

Lines changed: 43 additions & 16 deletions

File tree

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

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ suite('vscode API - webview', () => {
196196

197197
const firstResponse = getMesssage(webview);
198198

199-
assert.strictEqual((await firstResponse).value, 100);
199+
assert.strictEqual(Math.round((await firstResponse).value), 100);
200200

201201
// Swap away from the webview
202202
const doc = await vscode.workspace.openTextDocument(testDocument);
@@ -207,7 +207,7 @@ suite('vscode API - webview', () => {
207207

208208
// We should still have old scroll pos
209209
const secondResponse = await sendRecieveMessage(webview, { type: 'get' });
210-
assert.strictEqual(secondResponse.value, 100);
210+
assert.strictEqual(Math.round(secondResponse.value), 100);
211211
});
212212

213213
conditionalTest('webviews with retainContextWhenHidden should be able to recive messages while hidden', async () => {
@@ -252,29 +252,29 @@ suite('vscode API - webview', () => {
252252
});
253253
</script>`);
254254

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

260260
{
261-
const imagePath = await asWebviewUri('/image.png');
261+
const imagePath = asWebviewUri('/image.png');
262262
const response = sendRecieveMessage(webview, { src: imagePath });
263263
assert.strictEqual((await response).value, true);
264264
}
265265
{
266-
const imagePath = await asWebviewUri('/no-such-image.png');
266+
const imagePath = asWebviewUri('/no-such-image.png');
267267
const response = sendRecieveMessage(webview, { src: imagePath });
268268
assert.strictEqual((await response).value, false);
269269
}
270270
{
271-
const imagePath = vscode.Uri.file(join(vscode.workspace.rootPath!, '..', '..', '..', 'resources', 'linux', 'code.png')).with({ scheme: 'vscode-resource' });
271+
const imagePath = webview.webview.asWebviewUri(vscode.Uri.file(join(vscode.workspace.rootPath!, '..', '..', '..', 'resources', 'linux', 'code.png')));
272272
const response = sendRecieveMessage(webview, { src: imagePath.toString() });
273273
assert.strictEqual((await response).value, false);
274274
}
275275
});
276276

277-
conditionalTest('webviews should allow overriding allowed resource paths using localResourceRoots', async () => {
277+
test('webviews should allow overriding allowed resource paths using localResourceRoots', async () => {
278278
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {
279279
enableScripts: true,
280280
localResourceRoots: [vscode.Uri.file(join(vscode.workspace.rootPath!, 'sub'))]
@@ -292,18 +292,38 @@ suite('vscode API - webview', () => {
292292
});
293293
</script>`);
294294

295-
const workspaceRootUri = vscode.Uri.file(vscode.workspace.rootPath!).with({ scheme: 'vscode-resource' });
296-
297295
{
298-
const response = sendRecieveMessage(webview, { src: workspaceRootUri.toString() + '/sub/image.png' });
296+
const response = sendRecieveMessage(webview, { src: webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath! + '/sub/image.png')).toString() });
299297
assert.strictEqual((await response).value, true);
300298
}
301299
{
302-
const response = sendRecieveMessage(webview, { src: workspaceRootUri.toString() + '/image.png' });
300+
const response = sendRecieveMessage(webview, { src: webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath! + '/image.png')).toString() });
303301
assert.strictEqual((await response).value, false);
304302
}
305303
});
306304

305+
conditionalTest('webviews using hard-coded old style vscode-resource uri should work', async () => {
306+
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {
307+
enableScripts: true,
308+
localResourceRoots: [vscode.Uri.file(join(vscode.workspace.rootPath!, 'sub'))]
309+
}));
310+
311+
const imagePath = vscode.Uri.file(join(vscode.workspace.rootPath!, 'sub', 'image.png')).with({ scheme: 'vscode-resource' }).toString();
312+
313+
webview.webview.html = createHtmlDocumentWithBody(/*html*/`
314+
<img src="${imagePath}">
315+
<script>
316+
const vscode = acquireVsCodeApi();
317+
const img = document.getElementsByTagName('img')[0];
318+
img.addEventListener('load', () => { vscode.postMessage({ value: true }); });
319+
img.addEventListener('error', () => { vscode.postMessage({ value: false }); });
320+
</script>`);
321+
322+
const firstResponse = getMesssage(webview);
323+
324+
assert.strictEqual((await firstResponse).value, true);
325+
});
326+
307327
test('webviews should have real view column after they are created, #56097', async () => {
308328
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.Active }, { enableScripts: true }));
309329

src/vs/platform/webview/common/resourceLoader.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,11 @@ function normalizeRequestPath(requestUri: URI) {
114114
return requestUri;
115115
}
116116

117-
// The `vscode-webview-resource` schemes encodes both the scheme and uri:
118-
const resourceUri = URI.parse(requestUri.path.replace(/\/+(\w+)\/\//, '$1://'));
117+
// The `vscode-webview-resource` scheme has the following format:
118+
//
119+
// vscode-webview-resource://id/scheme//authority?/path
120+
//
121+
const resourceUri = URI.parse(requestUri.path.replace(/^\/(\w+)\/{1,2}/, '$1://'));
119122
return resourceUri.with({
120123
query: requestUri.query,
121124
fragment: requestUri.fragment

src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,13 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
390390
return value
391391
.replace(/(["'])vscode-resource:(\/\/([^\s\/'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (match, startQuote, _1, scheme, path, endQuote) => {
392392
if (scheme) {
393-
return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}//${scheme}${path}${endQuote}`;
393+
return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}/${scheme}${path}${endQuote}`;
394394
}
395-
return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}//file${path}${endQuote}`;
395+
if (!path.startsWith('//')) {
396+
// Add an empty authority if we don't already have one
397+
path = '//' + path;
398+
}
399+
return `${startQuote}${Schemas.vscodeWebviewResource}:${this.id}/file${path}${endQuote}`;
396400
});
397401
}
398402

0 commit comments

Comments
 (0)