Simplify logic for webview resource uris (#123740)

* Simplify logic for webview resource uris

This change attempts to simplify the logic around webview resource uris by doing the following:

- Hard code the resource origin. We always will be hitting a service worker for these paths so they don't need to be dynamic (although in the future we may want to pull them from `product.json`)

    This lets us remove these properties from the environment service

- Move remote handling from the resource loader in `asWebviewUri`.

- Remove the handling of http and https paths from the resource loader.

    I don't think these cases can be hit any longer (although I need to confirm this with more testing for the web case). Instead I added a check to `asWebviewUri` so that we return the original uri if a http(s) uri is passed in

* Restore normalizeResourcePath

We still need to convert between a remote uri and one that our remote file system can read

* Fix test

* Restore passing in remote on extension side

* Remove only
This commit is contained in:
Matt Bierner
2021-05-19 17:26:51 -07:00
committed by GitHub
parent 93be0a6fa0
commit 1ddc623e58
21 changed files with 131 additions and 194 deletions

View File

@@ -3,16 +3,26 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import type * as vscode from 'vscode';
export interface WebviewInitData {
readonly isExtensionDevelopmentDebug: boolean;
readonly webviewResourceRoot: string;
readonly webviewCspSource: string;
readonly remote: { readonly authority: string | undefined };
}
/**
* Location where we load resources from
*
* There endpoints can be hardcoded because we never expect to actually hit them. Instead these requests
* should always go to a service worker.
*/
export const webviewResourceOrigin = (id: string) => `https://${id}.vscode-webview-test.com`;
export const webviewResourceRoot = (id: string) => `${webviewResourceOrigin(id)}/vscode-resource/{{resource}}`;
export const webviewGenericCspSource = 'https://*.vscode-webview-test.com';
/**
* Construct a uri that can load resources inside a webview
*
@@ -20,16 +30,32 @@ export interface WebviewInitData {
* we know where to load the resource from (remote or truly local):
*
* ```txt
* /remote-authority?/scheme/resource-authority/path...
* scheme/resource-authority/path...
* ```
*
* @param uuid Unique id of the webview.
* @param resource Uri of the resource to load.
* @param fromAuthority Optional remote authority that specifies where `resource` should be resolved from.
*/
export function asWebviewUri(
initData: WebviewInitData,
uuid: string,
resource: vscode.Uri,
fromAuthority: string | undefined
): vscode.Uri {
const uri = initData.webviewResourceRoot
.replace('{{resource}}', (initData.remote.authority ?? '') + '/' + resource.scheme + '/' + encodeURIComponent(resource.authority) + resource.path)
if (resource.scheme === Schemas.http || resource.scheme === Schemas.https) {
return resource;
}
if (fromAuthority && resource.scheme === Schemas.file) {
resource = URI.from({
scheme: Schemas.vscodeRemote,
authority: fromAuthority,
path: resource.path,
});
}
const uri = webviewResourceRoot(uuid)
.replace('{{resource}}', resource.scheme + '/' + encodeURIComponent(resource.authority) + resource.path)
.replace('{{uuid}}', uuid);
return URI.parse(uri).with({
fragment: resource.fragment,