[FIX] web: convert iframe_wrapper field to owl

This field has been forgotten in the PR converting all web fields
to wowl.

closes odoo/odoo#101661

X-original-commit: 2e1c78b3818cdcb97afe4cd1496e0da6f8bac1b7
Related: odoo/enterprise#32041
Signed-off-by: Géry Debongnie <ged@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Aaron Bohy
2022-09-29 20:51:07 +02:00
parent 98a5c543c7
commit f026c8a4d4
4 changed files with 181 additions and 0 deletions
@@ -0,0 +1,42 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { _lt } from "@web/core/l10n/translation";
import { standardFieldProps } from "../standard_field_props";
const { Component, useEffect, useRef } = owl;
export class IframeWrapperField extends Component {
setup() {
this.iframeRef = useRef("iframe");
useEffect(
(value) => {
/**
* The document.write is not recommended. It is better to manipulate the DOM through $.appendChild and
* others. In our case though, we deal with an iframe without src attribute and with metadata to put in
* head tag. If we use the usual dom methods, the iframe is automatically created with its document
* component containing html > head & body. Therefore, if we want to make it work that way, we would
* need to receive each piece at a time to append it to this document (with this.record.data and extra
* model fields or with an rpc). It also cause other difficulties getting attribute on the most parent
* nodes, parsing to HTML complex elements, etc.
* Therefore, document.write makes it much more trivial in our situation.
*/
const iframeDoc = this.iframeRef.el.contentDocument;
iframeDoc.open();
iframeDoc.write(value);
iframeDoc.close();
},
() => [this.props.value]
);
}
}
IframeWrapperField.template = "web.IframeWrapperField";
IframeWrapperField.props = {
...standardFieldProps,
};
IframeWrapperField.displayName = _lt("Wrap raw html within an iframe");
// If HTML, don't forget to adjust the sanitize options to avoid stripping most of the metadata
IframeWrapperField.supportedTypes = ["text", "html"];
registry.category("fields").add("iframe_wrapper", IframeWrapperField);
@@ -0,0 +1,43 @@
$preview_height: 1123 + 32;
$preview_width: 794;
$preview_scale: 0.50;
@mixin o_preview_iframe_styling($scale) {
.o_preview_iframe_wrapper {
padding: 0;
overflow: hidden;
width: ($preview_width * $scale) + 0px;
height: ($preview_height * $scale) + 0px;
position: relative;
}
.o_preview_iframe {
width: $preview_width + 0px;
height: $preview_height + 0px;
border: 2px solid lightgrey;
overflow: hidden;
padding-top: 16px;
padding-bottom: 16px;
-ms-zoom: 0.5;
-moz-transform: scale($scale);
-moz-transform-origin: 0 0;
-o-transform: scale($scale);
-o-transform-origin: 0 0;
-webkit-transform: scale($scale);
-webkit-transform-origin: 0 0;
}
}
@include o_preview_iframe_styling($preview_scale)
@media (max-width: 1488px) {
@include o_preview_iframe_styling($preview_scale * 0.80)
}
@media (max-width: 600px) {
@include o_preview_iframe_styling($preview_scale * 0.60)
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="web.IframeWrapperField" owl="1">
<div class="o_preview_iframe_wrapper">
<iframe src="about:blank" class="o_preview_iframe" t-ref="iframe"/>
</div>
</t>
</templates>
@@ -0,0 +1,86 @@
/** @odoo-module **/
import { editInput, getFixture } from "@web/../tests/helpers/utils";
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
let serverData;
let target;
QUnit.module("Fields", (hooks) => {
hooks.beforeEach(() => {
target = getFixture();
serverData = {
models: {
report: {
fields: {
int_field: { string: "Int Field", type: "integer" },
html_field: { string: "Content of report", type: "html" },
},
records: [
{
id: 1,
html_field: `
<html>
<head>
<style>
body { color : rgb(255, 0, 0); }
</style>
<head>
<body>
<div class="nice_div"><p>Some content</p></div>
</body>
</html>`,
},
],
},
},
};
setupViewRegistries();
});
QUnit.module("IframeWrapperField");
QUnit.test("IframeWrapperField in form view", async function (assert) {
await makeView({
type: "form",
resModel: "report",
serverData,
resId: 1,
arch: `
<form>
<field name="html_field" widget="iframe_wrapper"/>
</form>`,
});
const iframeDoc = target.querySelector("iframe").contentDocument;
assert.strictEqual(iframeDoc.querySelector(".nice_div").innerHTML, "<p>Some content</p>");
assert.strictEqual($(iframeDoc).find(".nice_div p").css("color"), "rgb(255, 0, 0)");
});
QUnit.test("IframeWrapperField in form view with onchange", async function (assert) {
serverData.models.report.onchanges = {
int_field(record) {
record.html_field = record.html_field.replace("Some content", "New content");
},
};
await makeView({
type: "form",
resModel: "report",
serverData,
resId: 1,
arch: `
<form>
<field name="int_field"/>
<field name="html_field" widget="iframe_wrapper"/>
</form>`,
});
const iframeDoc = target.querySelector("iframe").contentDocument;
assert.strictEqual(iframeDoc.querySelector(".nice_div").innerHTML, "<p>Some content</p>");
assert.strictEqual($(iframeDoc).find(".nice_div p").css("color"), "rgb(255, 0, 0)");
await editInput(target, ".o_field_widget[name=int_field] input", 264);
assert.strictEqual(iframeDoc.querySelector(".nice_div").innerHTML, "<p>New content</p>");
});
});