mirror of
https://github.com/Microsoft/vscode
synced 2024-08-24 11:36:01 +00:00
Move html rewriting for old webviews to (#163367)
The `asWebviewUri` methods was introduced in VS Code 1.38. It's silly that we still force every single webview to pay the cost of trying to rewrite the old style uris we supported in very old versions of VS Code Instead I've moved this logic into the extension host and disabled it for all extensions that target VS Code 1.60+ or newer. This means it never applies to internal webviews, notebooks, webview views, or custom editors (these public apis were all introduced after the switch to `asWebviewUri`)
This commit is contained in:
parent
0abb1e99c2
commit
d05d85a78b
|
@ -8,7 +8,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.20.0"
|
"vscode": "^1.70.0"
|
||||||
},
|
},
|
||||||
"main": "./out/extension",
|
"main": "./out/extension",
|
||||||
"browser": "./dist/browser/extension",
|
"browser": "./dist/browser/extension",
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.39.0"
|
"vscode": "^1.70.0"
|
||||||
},
|
},
|
||||||
"main": "./out/extension",
|
"main": "./out/extension",
|
||||||
"browser": "./dist/browser/extension.js",
|
"browser": "./dist/browser/extension.js",
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.53.0"
|
"vscode": "^1.70.0"
|
||||||
},
|
},
|
||||||
"main": "./out/extension",
|
"main": "./out/extension",
|
||||||
"browser": "./dist/browser/extension",
|
"browser": "./dist/browser/extension",
|
||||||
|
|
|
@ -33,7 +33,8 @@ export class ExtHostWebview implements vscode.Webview {
|
||||||
#isDisposed: boolean = false;
|
#isDisposed: boolean = false;
|
||||||
#hasCalledAsWebviewUri = false;
|
#hasCalledAsWebviewUri = false;
|
||||||
|
|
||||||
#serializeBuffersForPostMessage = false;
|
#serializeBuffersForPostMessage: boolean;
|
||||||
|
#shouldRewriteOldResourceUris: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
handle: extHostProtocol.WebviewHandle,
|
handle: extHostProtocol.WebviewHandle,
|
||||||
|
@ -51,6 +52,7 @@ export class ExtHostWebview implements vscode.Webview {
|
||||||
this.#workspace = workspace;
|
this.#workspace = workspace;
|
||||||
this.#extension = extension;
|
this.#extension = extension;
|
||||||
this.#serializeBuffersForPostMessage = shouldSerializeBuffersForPostMessage(extension);
|
this.#serializeBuffersForPostMessage = shouldSerializeBuffersForPostMessage(extension);
|
||||||
|
this.#shouldRewriteOldResourceUris = shouldTryRewritingOldResourceUris(extension);
|
||||||
this.#deprecationService = deprecationService;
|
this.#deprecationService = deprecationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,12 +100,12 @@ export class ExtHostWebview implements vscode.Webview {
|
||||||
this.assertNotDisposed();
|
this.assertNotDisposed();
|
||||||
if (this.#html !== value) {
|
if (this.#html !== value) {
|
||||||
this.#html = value;
|
this.#html = value;
|
||||||
if (!this.#hasCalledAsWebviewUri && /(["'])vscode-resource:([^\s'"]+?)(["'])/i.test(value)) {
|
if (this.#shouldRewriteOldResourceUris && !this.#hasCalledAsWebviewUri && /(["'])vscode-resource:([^\s'"]+?)(["'])/i.test(value)) {
|
||||||
this.#hasCalledAsWebviewUri = true;
|
this.#hasCalledAsWebviewUri = true;
|
||||||
this.#deprecationService.report('Webview vscode-resource: uris', this.#extension,
|
this.#deprecationService.report('Webview vscode-resource: uris', this.#extension,
|
||||||
`Please migrate to use the 'webview.asWebviewUri' api instead: https://aka.ms/vscode-webview-use-aswebviewuri`);
|
`Please migrate to use the 'webview.asWebviewUri' api instead: https://aka.ms/vscode-webview-use-aswebviewuri`);
|
||||||
}
|
}
|
||||||
this.#proxy.$setHtml(this.#handle, value);
|
this.#proxy.$setHtml(this.#handle, this.rewriteOldResourceUrlsIfNeeded(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +133,32 @@ export class ExtHostWebview implements vscode.Webview {
|
||||||
throw new Error('Webview is disposed');
|
throw new Error('Webview is disposed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private rewriteOldResourceUrlsIfNeeded(value: string): string {
|
||||||
|
if (!this.#shouldRewriteOldResourceUris) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isRemote = this.#extension.extensionLocation?.scheme === Schemas.vscodeRemote;
|
||||||
|
const remoteAuthority = this.#extension.extensionLocation.scheme === Schemas.vscodeRemote ? this.#extension.extensionLocation.authority : undefined;
|
||||||
|
return value
|
||||||
|
.replace(/(["'])(?:vscode-resource):(\/\/([^\s\/'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (_match, startQuote, _1, scheme, path, endQuote) => {
|
||||||
|
const uri = URI.from({
|
||||||
|
scheme: scheme || 'file',
|
||||||
|
path: decodeURIComponent(path),
|
||||||
|
});
|
||||||
|
const webviewUri = asWebviewUri(uri, { isRemote, authority: remoteAuthority }).toString();
|
||||||
|
return `${startQuote}${webviewUri}${endQuote}`;
|
||||||
|
})
|
||||||
|
.replace(/(["'])(?:vscode-webview-resource):(\/\/[^\s\/'"]+\/([^\s\/'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (_match, startQuote, _1, scheme, path, endQuote) => {
|
||||||
|
const uri = URI.from({
|
||||||
|
scheme: scheme || 'file',
|
||||||
|
path: decodeURIComponent(path),
|
||||||
|
});
|
||||||
|
const webviewUri = asWebviewUri(uri, { isRemote, authority: remoteAuthority }).toString();
|
||||||
|
return `${startQuote}${webviewUri}${endQuote}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldSerializeBuffersForPostMessage(extension: IExtensionDescription): boolean {
|
export function shouldSerializeBuffersForPostMessage(extension: IExtensionDescription): boolean {
|
||||||
|
@ -142,6 +170,19 @@ export function shouldSerializeBuffersForPostMessage(extension: IExtensionDescri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldTryRewritingOldResourceUris(extension: IExtensionDescription): boolean {
|
||||||
|
try {
|
||||||
|
const version = normalizeVersion(parseVersion(extension.engines.vscode));
|
||||||
|
if (!version) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return version.majorBase < 1 || (version.majorBase === 1 && version.minorBase < 60);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
|
export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
|
||||||
|
|
||||||
private readonly _webviewProxy: extHostProtocol.MainThreadWebviewsShape;
|
private readonly _webviewProxy: extHostProtocol.MainThreadWebviewsShape;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { streamToBuffer, VSBufferReadableStream } from 'vs/base/common/buffer';
|
||||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { COI, Schemas } from 'vs/base/common/network';
|
import { COI } from 'vs/base/common/network';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { generateUuid } from 'vs/base/common/uuid';
|
import { generateUuid } from 'vs/base/common/uuid';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
|
@ -30,7 +30,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
|
import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
|
||||||
import { WebviewPortMappingManager } from 'vs/platform/webview/common/webviewPortMapping';
|
import { WebviewPortMappingManager } from 'vs/platform/webview/common/webviewPortMapping';
|
||||||
import { parentOriginHash } from 'vs/workbench/browser/webview';
|
import { parentOriginHash } from 'vs/workbench/browser/webview';
|
||||||
import { asWebviewUri, decodeAuthority, webviewGenericCspSource, webviewRootResourceAuthority } from 'vs/workbench/common/webview';
|
import { decodeAuthority, webviewGenericCspSource, webviewRootResourceAuthority } from 'vs/workbench/common/webview';
|
||||||
import { loadLocalResource, WebviewResourceResponse } from 'vs/workbench/contrib/webview/browser/resourceLoading';
|
import { loadLocalResource, WebviewResourceResponse } from 'vs/workbench/contrib/webview/browser/resourceLoading';
|
||||||
import { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/browser/themeing';
|
import { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/browser/themeing';
|
||||||
import { areWebviewContentOptionsEqual, IWebview, WebviewContentOptions, WebviewExtensionDescription, WebviewMessageReceivedEvent, WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview';
|
import { areWebviewContentOptionsEqual, IWebview, WebviewContentOptions, WebviewExtensionDescription, WebviewMessageReceivedEvent, WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview';
|
||||||
|
@ -645,37 +645,14 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||||
}
|
}
|
||||||
|
|
||||||
public set html(value: string) {
|
public set html(value: string) {
|
||||||
const rewrittenHtml = this.rewriteVsCodeResourceUrls(value);
|
|
||||||
this.doUpdateContent({
|
this.doUpdateContent({
|
||||||
html: rewrittenHtml,
|
html: value,
|
||||||
options: this.content.options,
|
options: this.content.options,
|
||||||
state: this.content.state,
|
state: this.content.state,
|
||||||
});
|
});
|
||||||
this._onDidHtmlChange.fire(value);
|
this._onDidHtmlChange.fire(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private rewriteVsCodeResourceUrls(value: string): string {
|
|
||||||
const isRemote = this.extension?.location?.scheme === Schemas.vscodeRemote;
|
|
||||||
const remoteAuthority = this.extension?.location?.scheme === Schemas.vscodeRemote ? this.extension.location.authority : undefined;
|
|
||||||
return value
|
|
||||||
.replace(/(["'])(?:vscode-resource):(\/\/([^\s\/'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (_match, startQuote, _1, scheme, path, endQuote) => {
|
|
||||||
const uri = URI.from({
|
|
||||||
scheme: scheme || 'file',
|
|
||||||
path: decodeURIComponent(path),
|
|
||||||
});
|
|
||||||
const webviewUri = asWebviewUri(uri, { isRemote, authority: remoteAuthority }).toString();
|
|
||||||
return `${startQuote}${webviewUri}${endQuote}`;
|
|
||||||
})
|
|
||||||
.replace(/(["'])(?:vscode-webview-resource):(\/\/[^\s\/'"]+\/([^\s\/'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (_match, startQuote, _1, scheme, path, endQuote) => {
|
|
||||||
const uri = URI.from({
|
|
||||||
scheme: scheme || 'file',
|
|
||||||
path: decodeURIComponent(path),
|
|
||||||
});
|
|
||||||
const webviewUri = asWebviewUri(uri, { isRemote, authority: remoteAuthority }).toString();
|
|
||||||
return `${startQuote}${webviewUri}${endQuote}`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public set contentOptions(options: WebviewContentOptions) {
|
public set contentOptions(options: WebviewContentOptions) {
|
||||||
this._logService.debug(`Webview(${this.id}): will update content options`);
|
this._logService.debug(`Webview(${this.id}): will update content options`);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue