diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa4febd586bd6..89c8de7ec92d0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
## v1.33.0 - unreleased
- [scripts] integrated start-up performance scripts into nightly master build [#10463](https://github.com/eclipse-theia/theia/pull/10463) - Contributed on behalf of STMicroelectronics
+- [plugin] added `enableForms` field to `WebviewOptions` [#11983](https://github.com/eclipse-theia/theia/pull/11983) - Contributed on behalf of STMicroelectronics
[Breaking Changes:](#breaking_changes_1.33.0)
diff --git a/packages/plugin-ext/src/main/browser/custom-editors/custom-editors-main.ts b/packages/plugin-ext/src/main/browser/custom-editors/custom-editors-main.ts
index 73511bf102426..6886ab2faab1e 100644
--- a/packages/plugin-ext/src/main/browser/custom-editors/custom-editors-main.ts
+++ b/packages/plugin-ext/src/main/browser/custom-editors/custom-editors-main.ts
@@ -223,11 +223,12 @@ export class CustomEditorsMainImpl implements CustomEditorsMain, Disposable {
const view = await this.widgetManager.getOrCreateWidget(CustomEditorWidget.FACTORY_ID, { id: panelId });
this.webviewsMain.hookWebview(view);
view.title.label = title;
- const { enableFindWidget, retainContextWhenHidden, enableScripts, localResourceRoots, ...contentOptions } = options;
+ const { enableFindWidget, retainContextWhenHidden, enableScripts, enableForms, localResourceRoots, ...contentOptions } = options;
view.viewColumn = ViewColumn.One; // behaviour might be overridden later using widgetOpenerOptions (if available)
view.options = { enableFindWidget, retainContextWhenHidden };
view.setContentOptions({
allowScripts: enableScripts,
+ allowForms: enableForms,
localResourceRoots: localResourceRoots && localResourceRoots.map(root => root.toString()),
...contentOptions,
...view.contentOptions
diff --git a/packages/plugin-ext/src/main/browser/webview/pre/main.js b/packages/plugin-ext/src/main/browser/webview/pre/main.js
index b7b1e2eef71e4..ec05c6a3663d0 100644
--- a/packages/plugin-ext/src/main/browser/webview/pre/main.js
+++ b/packages/plugin-ext/src/main/browser/webview/pre/main.js
@@ -479,7 +479,14 @@
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-downloads' : 'allow-same-origin');
+ const sandboxOptions = ['allow-same-origin'];
+ if (options.allowScripts) {
+ sandboxOptions.push('allow-scripts', 'allow-downloads');
+ }
+ if (options.allowForms || (options.allowScripts && options.allowForms === undefined)) {
+ sandboxOptions.push('allow-forms');
+ }
+ newFrame.setAttribute('sandbox', sandboxOptions.join(' '));
if (host.fakeLoad) {
// We should just be able to use srcdoc, but I wasn't
// seeing the service worker applying properly.
diff --git a/packages/plugin-ext/src/main/browser/webview/webview.ts b/packages/plugin-ext/src/main/browser/webview/webview.ts
index 1461e2ebfcb43..b40dde18dc422 100644
--- a/packages/plugin-ext/src/main/browser/webview/webview.ts
+++ b/packages/plugin-ext/src/main/browser/webview/webview.ts
@@ -73,6 +73,7 @@ export const enum WebviewMessageChannels {
export interface WebviewContentOptions {
readonly allowScripts?: boolean;
+ readonly allowForms?: boolean;
readonly localResourceRoots?: ReadonlyArray;
readonly portMapping?: ReadonlyArray;
readonly enableCommandUris?: boolean;
diff --git a/packages/plugin-ext/src/main/browser/webviews-main.ts b/packages/plugin-ext/src/main/browser/webviews-main.ts
index 12d80739d7715..904d5efc4fcf7 100644
--- a/packages/plugin-ext/src/main/browser/webviews-main.ts
+++ b/packages/plugin-ext/src/main/browser/webviews-main.ts
@@ -67,10 +67,11 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
this.hookWebview(view);
view.viewType = viewType;
view.title.label = title;
- const { enableFindWidget, retainContextWhenHidden, enableScripts, localResourceRoots, ...contentOptions } = options;
+ const { enableFindWidget, retainContextWhenHidden, enableScripts, enableForms, localResourceRoots, ...contentOptions } = options;
view.options = { enableFindWidget, retainContextWhenHidden };
view.setContentOptions({
allowScripts: enableScripts,
+ allowForms: enableForms,
localResourceRoots: localResourceRoots && localResourceRoots.map(root => root.toString()),
...contentOptions
});
@@ -171,9 +172,10 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
async $setOptions(handle: string, options: WebviewOptions): Promise {
const webview = await this.getWebview(handle);
- const { enableScripts, localResourceRoots, ...contentOptions } = options;
+ const { enableScripts, enableForms, localResourceRoots, ...contentOptions } = options;
webview.setContentOptions({
allowScripts: enableScripts,
+ allowForms: enableForms,
localResourceRoots: localResourceRoots && localResourceRoots.map(root => root.toString()),
...contentOptions
});
@@ -210,10 +212,11 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
}
const options = widget.options;
- const { allowScripts, localResourceRoots, ...contentOptions } = widget.contentOptions;
+ const { allowScripts, allowForms, localResourceRoots, ...contentOptions } = widget.contentOptions;
this.updateViewState(widget);
await this.proxy.$deserializeWebviewPanel(handle, widget.viewType, title, state, widget.viewState, {
enableScripts: allowScripts,
+ enableForms: allowForms,
localResourceRoots: localResourceRoots && localResourceRoots.map(root => URI.parse(root)),
...contentOptions,
...options
diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts
index 0422b0d005d7f..788364a80ca39 100644
--- a/packages/plugin/src/theia.d.ts
+++ b/packages/plugin/src/theia.d.ts
@@ -3768,6 +3768,14 @@ export module '@theia/plugin' {
*/
readonly enableScripts?: boolean;
+ /**
+ * Controls whether forms are enabled in the webview content or not.
+ *
+ * Defaults to true if {@link WebviewOptions.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.
*