Skip to content

Commit 60ad945

Browse files
sobo-odooFrancoisGe
authored andcommitted
Fix conditional visibility option + make DOM consistent at editor start
1 parent 01df2cf commit 60ad945

File tree

6 files changed

+69
-3
lines changed

6 files changed

+69
-3
lines changed

addons/html_builder/static/src/builder.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export class Builder extends Component {
162162
});
163163

164164
onMounted(() => {
165+
this.editor.document.body.classList.add("editor_enable");
165166
this.setCSSVariables();
166167
// TODO: onload editor
167168
this.updateInvisibleEls();

addons/html_builder/static/src/core/visibility_plugin.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,31 @@ export class VisibilityPlugin extends Plugin {
99
"cleanForSaveVisibility",
1010
"onOptionVisibilityUpdate",
1111
];
12-
1312
resources = {
1413
on_mobile_preview_clicked: this.onMobilePreviewClicked.bind(this),
1514
system_attributes: ["data-invisible"],
1615
system_classes: ["o_snippet_override_invisible"],
1716
};
1817

18+
setup() {
19+
// Add the `data-invisible="1"` attribute on the elements that are
20+
// really hidden, and remove it from the ones that are in fact visible,
21+
// depending on if we are in mobile preview or not, so the DOM is
22+
// consistent.
23+
const isMobilePreview = isMobileView(this.editable);
24+
this.editable
25+
.querySelectorAll(".o_snippet_mobile_invisible, .o_snippet_desktop_invisible")
26+
.forEach((invisibleEl) => {
27+
const isMobileHidden = invisibleEl.matches(".o_snippet_mobile_invisible");
28+
const isDesktopHidden = invisibleEl.matches(".o_snippet_desktop_invisible");
29+
if ((isMobileHidden && isMobilePreview) || (isDesktopHidden && !isMobilePreview)) {
30+
invisibleEl.setAttribute("data-invisible", "1");
31+
} else {
32+
invisibleEl.removeAttribute("data-invisible");
33+
}
34+
});
35+
}
36+
1937
cleanForSaveVisibility(editingEl) {
2038
const show =
2139
!editingEl.classList.contains("o_snippet_invisible") &&
@@ -29,6 +47,16 @@ export class VisibilityPlugin extends Plugin {
2947
for (const overrideInvisibleEl of overrideInvisibleEls) {
3048
overrideInvisibleEl.classList.remove("o_snippet_override_invisible");
3149
}
50+
51+
// Remove data-invisible attribute from condtionally hidden elements.
52+
// TODO do it for all invisible elements in general ?
53+
const conditionalHiddenEls = [
54+
...editingEl.querySelectorAll("[data-visibility='conditional']"),
55+
];
56+
if (editingEl.matches("[data-visibility='conditional']")) {
57+
conditionalHiddenEls.unshift(editingEl);
58+
}
59+
conditionalHiddenEls.forEach((el) => el.removeAttribute("data-invisible"));
3260
}
3361

3462
onMobilePreviewClicked() {

addons/html_builder/static/src/sidebar/invisible_elements.inside.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// e.g. Useful if "Height" option (50% or 100%) is enabled.
88
display: flex !important;
99
}
10+
1011
&::before {
1112
position: absolute;
1213
// Content is 0px wide => use available width.
@@ -19,12 +20,18 @@
1920
pointer-events: none;
2021
content: "."; // Content is mandatory.
2122
}
23+
2224
&.d-md-none::before, &.d-lg-none::before {
2325
height: 50px;
2426
-webkit-mask: url("/html_builder/static/img/options/desktop_invisible.svg") no-repeat 100% 100%;
2527
}
28+
2629
&:not(.d-md-none):not(.d-lg-none)::before {
2730
height: 30px;
2831
-webkit-mask: url("/html_builder/static/img/options/mobile_invisible.svg") no-repeat 100% 100%;
2932
}
3033
}
34+
35+
.o_conditional_hidden {
36+
display: none !important;
37+
}

addons/html_builder/static/src/website_builder/plugins/visibility_option.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<t t-call="html_builder.DeviceVisibility"></t>
4040
<BuilderSelect dataAttributeAction="'visibility'" action="'forceVisible'">
4141
<BuilderSelectItem dataAttributeActionValue="null">No condition</BuilderSelectItem>
42-
<BuilderSelectItem dataAttributeActionValue="'conditional'" id="'visibility_conditional'">Conditionally</BuilderSelectItem>
42+
<BuilderSelectItem dataAttributeActionValue="'conditional'" classAction="'o_snippet_invisible'" id="'visibility_conditional'">Conditionally</BuilderSelectItem>
4343
</BuilderSelect>
4444
<t t-set-slot="collapse">
4545
<t t-if="geoip_country_code">

addons/html_builder/static/src/website_builder/plugins/visibility_option_plugin.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,12 @@ class VisibilityOptionPlugin extends Plugin {
151151
editingEl.matches(visibilityOptionSelector)
152152
) {
153153
editingEl.classList.remove("o_snippet_override_invisible");
154+
155+
const isConditionalHidden = editingEl.matches("[data-visibility='conditional']");
156+
if (isConditionalHidden) {
157+
editingEl.classList.add("o_conditional_hidden");
158+
}
154159
}
155-
// TODO o_conditional_hidden class for conditionalVisibility ?
156160
}
157161

158162
onTargetShow(editingEl) {
@@ -166,6 +170,8 @@ class VisibilityOptionPlugin extends Plugin {
166170
if ((isMobileHidden && isMobilePreview) || (isDesktopHidden && !isMobilePreview)) {
167171
editingEl.classList.add("o_snippet_override_invisible");
168172
}
173+
174+
editingEl.classList.remove("o_conditional_hidden");
169175
}
170176
}
171177

addons/html_builder/static/tests/custom_tab/invisibily_options.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,27 @@ test("hide on mobile and toggle mobile view", async () => {
143143
await contains("button[data-action='mobile']").click();
144144
expect(".o_we_invisible_el_panel").not.toBeDisplayed();
145145
});
146+
147+
test("Hide element conditionally", async () => {
148+
await setupWebsiteBuilder(websiteContent);
149+
150+
await contains(":iframe section").click();
151+
await contains("[data-label='Visibility'] button.dropdown").click();
152+
await contains("div[data-action-id='forceVisible']:contains(Conditionally)").click();
153+
expect(":iframe section").toHaveClass("o_snippet_invisible");
154+
expect(".o_we_invisible_el_panel .o_we_invisible_entry").toHaveCount(1);
155+
expect(".o_we_invisible_el_panel .o_we_invisible_entry i").toHaveClass("fa-eye");
156+
157+
await contains(".o_we_invisible_el_panel .o_we_invisible_entry").click();
158+
expect(":iframe section.o_snippet_invisible").toHaveClass("o_conditional_hidden");
159+
expect(":iframe section").toHaveAttribute("data-invisible", "1");
160+
expect(".o_we_invisible_el_panel .o_we_invisible_entry i").toHaveClass("fa-eye-slash");
161+
162+
await contains(".o_we_invisible_el_panel .o_we_invisible_entry").click();
163+
expect(":iframe section.o_snippet_invisible").not.toHaveClass("o_conditional_hidden");
164+
expect(":iframe section").not.toHaveAttribute("data-invisible");
165+
166+
await contains("[data-label='Visibility'] button.dropdown").click();
167+
await contains("div[data-action-id='forceVisible']").click();
168+
expect(":iframe section").not.toHaveClass("o_snippet_invisible");
169+
});

0 commit comments

Comments
 (0)