diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 763f946d9a3..2d8d4487f17 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -8,7 +8,7 @@ "license": "MIT", "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", "engines": { - "vscode": "^1.20.0" + "vscode": "^1.70.0" }, "main": "./out/extension", "browser": "./dist/browser/extension", diff --git a/extensions/media-preview/package.json b/extensions/media-preview/package.json index b82a4eef836..384ab75f58b 100644 --- a/extensions/media-preview/package.json +++ b/extensions/media-preview/package.json @@ -12,7 +12,7 @@ "license": "MIT", "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", "engines": { - "vscode": "^1.39.0" + "vscode": "^1.70.0" }, "main": "./out/extension", "browser": "./dist/browser/extension.js", diff --git a/extensions/simple-browser/package.json b/extensions/simple-browser/package.json index 2db456cb387..bcd83d483d3 100644 --- a/extensions/simple-browser/package.json +++ b/extensions/simple-browser/package.json @@ -11,7 +11,7 @@ "license": "MIT", "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", "engines": { - "vscode": "^1.53.0" + "vscode": "^1.70.0" }, "main": "./out/extension", "browser": "./dist/browser/extension", diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index db22cb7fc13..11359a68969 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -33,7 +33,8 @@ export class ExtHostWebview implements vscode.Webview { #isDisposed: boolean = false; #hasCalledAsWebviewUri = false; - #serializeBuffersForPostMessage = false; + #serializeBuffersForPostMessage: boolean; + #shouldRewriteOldResourceUris: boolean; constructor( handle: extHostProtocol.WebviewHandle, @@ -51,6 +52,7 @@ export class ExtHostWebview implements vscode.Webview { this.#workspace = workspace; this.#extension = extension; this.#serializeBuffersForPostMessage = shouldSerializeBuffersForPostMessage(extension); + this.#shouldRewriteOldResourceUris = shouldTryRewritingOldResourceUris(extension); this.#deprecationService = deprecationService; } @@ -98,12 +100,12 @@ export class ExtHostWebview implements vscode.Webview { this.assertNotDisposed(); if (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.#deprecationService.report('Webview vscode-resource: uris', this.#extension, `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'); } } + + 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 { @@ -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 { private readonly _webviewProxy: extHostProtocol.MainThreadWebviewsShape; diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index bb38d8b1756..45e735a28ed 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -11,7 +11,7 @@ import { streamToBuffer, VSBufferReadableStream } from 'vs/base/common/buffer'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; 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 { generateUuid } from 'vs/base/common/uuid'; 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 { WebviewPortMappingManager } from 'vs/platform/webview/common/webviewPortMapping'; 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 { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/browser/themeing'; 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) { - const rewrittenHtml = this.rewriteVsCodeResourceUrls(value); this.doUpdateContent({ - html: rewrittenHtml, + html: value, options: this.content.options, state: this.content.state, }); 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) { this._logService.debug(`Webview(${this.id}): will update content options`);