提交 2d1f6d42 编写于 作者: M Matt Bierner

Add localResourceRoots to webview options

Fixes #44039

Add a new option that lets extensions override which root folders a webview can load local resources from. Defaults to allowing any resource in the workspace
上级 bcbd3395
......@@ -354,7 +354,10 @@ export class MarkdownPreviewWebviewManager {
const view = vscode.window.createWebview(
localize('previewTitle', 'Preview {0}', path.basename(resource.fsPath)),
viewColumn,
{ enableScripts: true });
{
enableScripts: true,
localResourceRoots: this.getLocalResourceRoots(resource)
});
this.contentProvider.provideTextDocumentContent(resource, this.previewConfigurations).then(x => view.html = x);
......@@ -373,4 +376,19 @@ export class MarkdownPreviewWebviewManager {
this.webviews.set(resource.fsPath, view);
return view;
}
private getLocalResourceRoots(
resource: vscode.Uri
): vscode.Uri[] {
const folder = vscode.workspace.getWorkspaceFolder(resource);
if (folder) {
return [folder.uri];
}
if (!resource.scheme || resource.scheme === 'file') {
return [vscode.Uri.parse(path.dirname(resource.fsPath))];
}
return [];
}
}
\ No newline at end of file
......@@ -396,7 +396,7 @@ declare module 'vscode' {
*/
export interface WebviewOptions {
/**
* Should scripts be enabled in the webview contetn?
* Should scripts be enabled in the webview content?
*
* Defaults to false (scripts-disabled).
*/
......@@ -423,6 +423,15 @@ declare module 'vscode' {
* webview content cannot be quickly saved and restored.
*/
readonly keepAlive?: boolean;
/**
* Root paths from which the webview can load local (filesystem) resources using the `vscode-workspace-resource:` scheme.
*
* Default to the root folders of the current workspace.
*
* Pass in an empty array to disallow access to any local resources.
*/
readonly localResourceRoots?: Uri[];
}
/**
......
......@@ -201,7 +201,9 @@ class WebviewEditor extends BaseWebviewEditor {
this.webview.options = {
allowScripts: input.options.enableScripts,
enableWrappedPostMessage: true
enableWrappedPostMessage: true,
useSameOriginForRoot: false,
localResourceRoots: (input && input.options.localResourceRoots) || this._contextService.getWorkspace().folders.map(x => x.uri)
};
this.webview.contents = input.html;
}
......@@ -215,7 +217,6 @@ class WebviewEditor extends BaseWebviewEditor {
this._partService.getContainer(Parts.EDITOR_PART),
this.themeService,
this._environmentService,
this._contextService,
this._contextViewService,
this.contextKey,
this.findInputFocusContextKey,
......
......@@ -52,7 +52,6 @@ import { Color } from 'vs/base/common/color';
import { WorkbenchTree } from 'vs/platform/list/browser/listService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { assign } from 'vs/base/common/objects';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { INotificationService } from 'vs/platform/notification/common/notification';
/** A context key that is set when an extension editor webview has focus. */
......@@ -194,8 +193,7 @@ export class ExtensionEditor extends BaseEditor {
@IContextViewService private readonly contextViewService: IContextViewService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IExtensionTipsService private readonly extensionTipsService: IExtensionTipsService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService
@IEnvironmentService private readonly environmentService: IEnvironmentService
) {
super(ExtensionEditor.ID, telemetryService, themeService);
......@@ -421,7 +419,7 @@ export class ExtensionEditor extends BaseEditor {
.then<void>(body => {
const allowedBadgeProviders = this.extensionsWorkbenchService.allowedBadgeProviders;
const webViewOptions = allowedBadgeProviders.length > 0 ? { allowScripts: false, allowSvgs: false, svgWhiteList: allowedBadgeProviders } : {};
this.activeWebview = new Webview(this.content, this.partService.getContainer(Parts.EDITOR_PART), this.themeService, this.environmentService, this.contextService, this.contextViewService, this.contextKey, this.findInputFocusContextKey, webViewOptions);
this.activeWebview = new Webview(this.content, this.partService.getContainer(Parts.EDITOR_PART), this.themeService, this.environmentService, this.contextViewService, this.contextKey, this.findInputFocusContextKey, webViewOptions);
const removeLayoutParticipant = arrays.insert(this.layoutParticipants, this.activeWebview);
this.contentDisposables.push(toDisposable(removeLayoutParticipant));
this.activeWebview.contents = body;
......
......@@ -30,6 +30,7 @@ function getActivePreviewsForResource(accessor: ServicesAccessor, resource: URI
}
// --- Register Editor
(<IEditorRegistry>Registry.as(EditorExtensions.Editors)).registerEditor(new EditorDescriptor(
HtmlPreviewPart,
HtmlPreviewPart.ID,
......
......@@ -26,7 +26,6 @@ import { Webview, WebviewOptions } from './webview';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { WebviewEditor } from './webviewEditor';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
/**
......@@ -55,8 +54,7 @@ export class HtmlPreviewPart extends WebviewEditor {
@IOpenerService private readonly openerService: IOpenerService,
@IPartService private readonly partService: IPartService,
@IContextViewService private readonly _contextViewService: IContextViewService,
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
@IWorkspaceContextService private readonly _contextService: IWorkspaceContextService
@IEnvironmentService private readonly _environmentService: IEnvironmentService
) {
super(HtmlPreviewPart.ID, telemetryService, themeService, storageService, contextKeyService);
}
......@@ -93,7 +91,6 @@ export class HtmlPreviewPart extends WebviewEditor {
this.partService.getContainer(Parts.EDITOR_PART),
this.themeService,
this._environmentService,
this._contextService,
this._contextViewService,
this.contextKey,
this.findInputFocusContextKey,
......
......@@ -17,7 +17,6 @@ import { IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { normalize, nativeSep } from 'vs/base/common/paths';
import { startsWith } from 'vs/base/common/strings';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
export interface WebviewOptions {
readonly allowScripts?: boolean;
......@@ -25,6 +24,7 @@ export interface WebviewOptions {
readonly svgWhiteList?: string[];
readonly enableWrappedPostMessage?: boolean;
readonly useSameOriginForRoot?: boolean;
readonly localResourceRoots?: URI[];
}
export class Webview {
......@@ -41,7 +41,6 @@ export class Webview {
private readonly _styleElement: Element,
private readonly _themeService: IThemeService,
private readonly _environmentService: IEnvironmentService,
private readonly _contextService: IWorkspaceContextService,
private readonly _contextViewService: IContextViewService,
private readonly _contextKey: IContextKey<boolean>,
private readonly _findInputContextKey: IContextKey<boolean>,
......@@ -321,16 +320,16 @@ export class Webview {
return;
}
registerFileProtocol(contents, 'vscode-core-resource', [
registerFileProtocol(contents, 'vscode-core-resource', () => [
this._environmentService.appRoot
]);
registerFileProtocol(contents, 'vscode-extension-resource', [
registerFileProtocol(contents, 'vscode-extension-resource', () => [
this._environmentService.extensionsPath,
this._environmentService.appRoot,
this._environmentService.extensionDevelopmentPath
]);
registerFileProtocol(contents, 'vscode-workspace-resource',
this._contextService.getWorkspace().folders.map(folder => folder.uri.fsPath)
registerFileProtocol(contents, 'vscode-workspace-resource', () =>
this._options.localResourceRoots.map(uri => uri.fsPath)
);
}
......@@ -352,7 +351,6 @@ export class Webview {
this._findStarted = true;
this._webview.findInPage(value, findOptions);
return;
}
/**
......@@ -425,11 +423,11 @@ namespace ApiThemeClassName {
function registerFileProtocol(
contents: Electron.WebContents,
protocol: string,
roots: string[]
getRoots: () => string[]
) {
contents.session.protocol.registerFileProtocol(protocol, (request, callback: any) => {
const requestPath = URI.parse(request.url).fsPath;
for (const root of roots) {
for (const root of getRoots()) {
const normalizedPath = normalize(requestPath, true);
if (startsWith(normalizedPath, root + nativeSep)) {
callback({ path: normalizedPath });
......
......@@ -28,7 +28,6 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { onUnexpectedError } from 'vs/base/common/errors';
import { addGAParameters } from 'vs/platform/telemetry/node/telemetryNodeUtils';
import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/tokenization';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
function renderBody(
body: string,
......@@ -64,8 +63,7 @@ export class ReleaseNotesEditor extends WebviewEditor {
@IOpenerService private readonly openerService: IOpenerService,
@IModeService private readonly modeService: IModeService,
@IPartService private readonly partService: IPartService,
@IContextViewService private readonly _contextViewService: IContextViewService,
@IWorkspaceContextService private readonly _contextService: IWorkspaceContextService
@IContextViewService private readonly _contextViewService: IContextViewService
) {
super(ReleaseNotesEditor.ID, telemetryService, themeService, storageService, contextKeyService);
}
......@@ -93,7 +91,6 @@ export class ReleaseNotesEditor extends WebviewEditor {
this.partService.getContainer(Parts.EDITOR_PART),
this.themeService,
this.environmentService,
this._contextService,
this._contextViewService,
this.contextKey,
this.findInputFocusContextKey,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册