From ef37dce5fadb0dfbf144bcd29c9f7a9877905d18 Mon Sep 17 00:00:00 2001 From: Renaud Thiry Date: Thu, 8 Jun 2023 10:05:47 +0000 Subject: [PATCH] [FIX] web_editor: _blank href for readonlyIframe The "readonly iframe" mode of html_editor does not do the processing required to ensure all links target a new tab when the setup is called more than once. As this happens often, links effectively did not redirect to a new tab. Additionally sandboxedIframe did not allow new tabs to open. We add `allow-popups` and `allow-popups-to-escape-sandbox` to the sandbox attributes. This is safe as the popup will not have access to the odoo window. Which should mean it's as safe as opening a link without the sandbox. opw-3337670 closes odoo/odoo#124395 X-original-commit: 61b6b6bf6181fe703cd3d455dba9004e1fad7135 Signed-off-by: David Monjoie (dmo) Signed-off-by: Thiry Renaud (reth) --- addons/web_editor/static/src/js/backend/html_field.js | 1 + addons/web_editor/static/src/js/backend/html_field.xml | 3 ++- addons/web_editor/static/tests/html_field_tests.js | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/addons/web_editor/static/src/js/backend/html_field.js b/addons/web_editor/static/src/js/backend/html_field.js index e61e07a84aa..5ba5e514834 100644 --- a/addons/web_editor/static/src/js/backend/html_field.js +++ b/addons/web_editor/static/src/js/backend/html_field.js @@ -439,6 +439,7 @@ export class HtmlField extends Component { if (this.iframePromise && iframeTarget) { if (iframeTarget.innerHTML !== this.props.record.data[this.props.name]) { iframeTarget.innerHTML = this.props.record.data[this.props.name]; + retargetLinks(iframeTarget); } return this.iframePromise; } diff --git a/addons/web_editor/static/src/js/backend/html_field.xml b/addons/web_editor/static/src/js/backend/html_field.xml index 26eff3eea55..470756d02af 100644 --- a/addons/web_editor/static/src/js/backend/html_field.xml +++ b/addons/web_editor/static/src/js/backend/html_field.xml @@ -4,7 +4,8 @@ - +
diff --git a/addons/web_editor/static/tests/html_field_tests.js b/addons/web_editor/static/tests/html_field_tests.js index 12b4a2e5b85..ee6ebb26c59 100644 --- a/addons/web_editor/static/tests/html_field_tests.js +++ b/addons/web_editor/static/tests/html_field_tests.js @@ -72,7 +72,7 @@ QUnit.module("WebEditor.HtmlField", ({ beforeEach }) => { `, }); - assert.containsOnce(target, '.o_field_html[name="txt"] iframe[sandbox="allow-same-origin"]'); + assert.containsOnce(target, '.o_field_html[name="txt"] iframe[sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"]'); }); QUnit.test("readonly sandboxed preview", async (assert) => { @@ -107,7 +107,7 @@ QUnit.module("WebEditor.HtmlField", ({ beforeEach }) => { `, }); - const readonlyIframe = target.querySelector('.o_field_html[name="txt"] iframe[sandbox="allow-same-origin"]'); + const readonlyIframe = target.querySelector('.o_field_html[name="txt"] iframe[sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"]'); assert.ok(readonlyIframe); await iframeReady(readonlyIframe); assert.strictEqual(readonlyIframe.contentDocument.body.innerText, 'Hello'); @@ -174,7 +174,7 @@ QUnit.module("WebEditor.HtmlField", ({ beforeEach }) => { }); // check original displayed content - let iframe = target.querySelector('.o_field_html[name="txt"] iframe[sandbox="allow-same-origin"]'); + let iframe = target.querySelector('.o_field_html[name="txt"] iframe[sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"]'); assert.ok(iframe, 'Should use a sanboxed iframe'); await iframeReady(iframe); assert.strictEqual(iframe.contentDocument.body.textContent.trim(), 'Hello'); @@ -192,7 +192,7 @@ QUnit.module("WebEditor.HtmlField", ({ beforeEach }) => { await click(target, '#codeview-btn-group > button'); await togglePromises[togglePromiseId]; // check dispayed content after edit - iframe = target.querySelector('.o_field_html[name="txt"] iframe[sandbox="allow-same-origin"]'); + iframe = target.querySelector('.o_field_html[name="txt"] iframe[sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"]'); await iframeReady(iframe); assert.strictEqual(iframe.contentDocument.body.textContent.trim(), 'Hi'); assert.strictEqual(iframe.contentDocument.head.querySelector('style').textContent.trim().replace(/\s/g, ''), @@ -249,7 +249,7 @@ QUnit.module("WebEditor.HtmlField", ({ beforeEach }) => { `, }); - assert.containsOnce(target, '.o_field_html[name="txt"] iframe[sandbox="allow-same-origin"]'); + assert.containsOnce(target, '.o_field_html[name="txt"] iframe[sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"]'); }); });