Introduce WebviewOptions.forms

Fixes #132157
This commit is contained in:
Matt Bierner 2021-09-02 13:24:31 -07:00
parent bad6e9309b
commit 0e52275271
No known key found for this signature in database
GPG key ID: 099C331567E11888
10 changed files with 34 additions and 2 deletions

View file

@ -93,6 +93,7 @@ class Preview extends Disposable {
webviewEditor.webview.options = {
enableScripts: true,
enableForms: false,
localResourceRoots: [
resourceRoot,
extensionRoot,

View file

@ -406,6 +406,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private getWebviewOptions(): vscode.WebviewOptions {
return {
enableScripts: true,
enableForms: false,
localResourceRoots: this.getLocalResourceRoots()
};
}

View file

@ -36,6 +36,7 @@ export class SimpleBrowserView extends Disposable {
preserveFocus: showOptions?.preserveFocus
}, {
enableScripts: true,
enableForms: true,
retainContextWhenHidden: true,
localResourceRoots: [
vscode.Uri.joinPath(extensionUri, 'media')

8
src/vs/vscode.d.ts vendored
View file

@ -7426,6 +7426,14 @@ declare module 'vscode' {
*/
readonly enableScripts?: boolean;
/**
* Controls whether forms are enabled in the webview content or not.
*
* Defaults to true if {@link enableScripts scripts are enabled}. Otherwise defaults to false.
* Explicitly setting this property to either true or false overrides the default.
*/
readonly enableForms?: boolean;
/**
* Controls whether command uris are enabled in webview content or not.
*

View file

@ -129,6 +129,7 @@ export function reviveWebviewExtension(extensionData: extHostProtocol.WebviewExt
export function reviveWebviewContentOptions(webviewOptions: extHostProtocol.IWebviewOptions): WebviewContentOptions {
return {
allowScripts: webviewOptions.enableScripts,
allowForms: webviewOptions.enableForms,
enableCommandUris: webviewOptions.enableCommandUris,
localResourceRoots: Array.isArray(webviewOptions.localResourceRoots) ? webviewOptions.localResourceRoots.map(r => URI.revive(r)) : undefined,
portMapping: webviewOptions.portMapping,

View file

@ -682,6 +682,7 @@ export interface IWebviewPortMapping {
export interface IWebviewOptions {
readonly enableScripts?: boolean;
readonly enableForms?: boolean;
readonly enableCommandUris?: boolean;
readonly localResourceRoots?: ReadonlyArray<UriComponents>;
readonly portMapping?: ReadonlyArray<IWebviewPortMapping>;

View file

@ -194,6 +194,7 @@ export function serializeWebviewOptions(
return {
enableCommandUris: options.enableCommandUris,
enableScripts: options.enableScripts,
enableForms: options.enableForms,
portMapping: options.portMapping,
localResourceRoots: options.localResourceRoots || getDefaultLocalResourceRoots(extension, workspace)
};
@ -203,6 +204,7 @@ export function reviveOptions(options: extHostProtocol.IWebviewOptions): vscode.
return {
enableCommandUris: options.enableCommandUris,
enableScripts: options.enableScripts,
enableForms: options.enableForms,
portMapping: options.portMapping,
localResourceRoots: options.localResourceRoots?.map(components => URI.from(components)),
};

View file

@ -642,6 +642,7 @@ function areServiceWorkersEnabled() {
* contents: string;
* options: {
* readonly allowScripts: boolean;
* readonly allowForms: boolean;
* readonly allowMultipleAPIAcquire: boolean;
* }
* state: any;
@ -800,7 +801,16 @@ onDomReady(() => {
const newFrame = document.createElement('iframe');
newFrame.setAttribute('id', 'pending-frame');
newFrame.setAttribute('frameborder', '0');
newFrame.setAttribute('sandbox', options.allowScripts ? 'allow-scripts allow-forms allow-same-origin allow-pointer-lock allow-downloads' : 'allow-same-origin allow-pointer-lock');
const sandboxRules = new Set(['allow-same-origin', 'allow-pointer-lock']);
if (options.allowScripts) {
sandboxRules.add('allow-scripts');
sandboxRules.add('allow-downloads');
}
if (options.allowForms) {
sandboxRules.add('allow-forms');
}
newFrame.setAttribute('sandbox', Array.from(sandboxRules).join(' '));
if (!isFirefox) {
newFrame.setAttribute('allow', options.allowScripts ? 'clipboard-read; clipboard-write;' : '');
}

View file

@ -86,6 +86,7 @@ export interface WebviewOptions {
export interface WebviewContentOptions {
readonly allowMultipleAPIAcquire?: boolean;
readonly allowScripts?: boolean;
readonly allowForms?: boolean;
readonly localResourceRoots?: ReadonlyArray<URI>;
readonly portMapping?: ReadonlyArray<IWebviewPortMapping>;
readonly enableCommandUris?: boolean;
@ -95,6 +96,7 @@ export function areWebviewContentOptionsEqual(a: WebviewContentOptions, b: Webvi
return (
a.allowMultipleAPIAcquire === b.allowMultipleAPIAcquire
&& a.allowScripts === b.allowScripts
&& a.allowForms === b.allowForms
&& equals(a.localResourceRoots, b.localResourceRoots, isEqual)
&& equals(a.portMapping, b.portMapping, (a, b) => a.extensionHostPort === b.extensionHostPort && a.webviewPort === b.webviewPort)
&& a.enableCommandUris === b.enableCommandUris

View file

@ -555,9 +555,14 @@ export class IFrameWebview extends Disposable implements Webview {
this.content = newContent;
const allowScripts = !!this.content.options.allowScripts;
this._send('content', {
contents: this.content.html,
options: this.content.options,
options: {
allowMultipleAPIAcquire: !!this.content.options.allowMultipleAPIAcquire,
allowScripts: allowScripts,
allowForms: this.content.options.allowForms ?? allowScripts, // For back compat, we allow forms by default when scripts are enabled
},
state: this.content.state,
cspSource: webviewGenericCspSource,
confirmBeforeClose: this._confirmBeforeClose,