Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/website/static/src/core/colibri.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export class Colibri {
destroy() {
// restore t-att to their initial values
for (const dynAttrs of this.dynamicAttrs) {
const { nodes, attr, definition, initialValues } = dynAttrs;
const { nodes, attr, initialValues } = dynAttrs;
if (!initialValues) {
continue;
}
Expand Down
1 change: 0 additions & 1 deletion addons/website/static/src/interactions/animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ export class Animation extends Interaction {
const windowsHeight = window.innerHeight;
const elHeight = el.offsetHeight;
let elOffset = this.isAnimateOnScroll ? 0 : Math.max((elHeight * this.offsetRatio), this.offsetMin);
const elStyle = window.getComputedStyle(el);

// We need to offset for the change in position from some animation.
// So we get the top value by not taking CSS transforms into calculations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,6 @@ import { Interaction } from "@website/core/interaction";

const CAROUSEL_SLIDING_CLASS = "o_carousel_sliding";

/**
* @param {HTMLElement} carouselEl
* @returns {Promise<void>}
*/
async function waitForCarouselToFinishSliding(carouselEl) {
if (!carouselEl.classList.contains(CAROUSEL_SLIDING_CLASS)) {
return;
}
return new Promise(resolve => {
carouselEl.addEventListener("slid.bs.carousel", () => resolve(), {once: true});
});
}

/**
* This class is used to fix carousel auto-slide behavior in Odoo 17.4 and up.
* It handles upgrade cases from lower versions.
Expand Down
8 changes: 6 additions & 2 deletions addons/website/static/src/interactions/footer_slideout.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ export class FooterSlideout extends Interaction {
}),
},
};
// TODO Support edit mode.
static disabledInEditableMode = false;

setup() {
const mainEl = this.el.querySelector(":scope > main");
Expand Down Expand Up @@ -40,3 +38,9 @@ export class FooterSlideout extends Interaction {
registry
.category("website.active_elements")
.add("website.footer_slideout", FooterSlideout);

registry
.category("website.editable_active_elements_builders")
.add("website.footer_slideout", {
Interaction: FooterSlideout,
});
1 change: 0 additions & 1 deletion addons/website/static/src/interactions/popup/popup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { cookie } from "@web/core/browser/cookie";
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { utils as uiUtils, SIZES } from "@web/core/ui/ui_service";
import { getTabableElements } from "@web/core/utils/ui";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { getScrollingElement } from "@web/core/utils/scrolling";
import { Interaction } from "@website/core/interaction";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Interaction } from "@website/core/interaction";
import { registry } from "@web/core/registry";

import { _t } from "@web/core/l10n/translation";
import { uniqueId } from "@web/core/utils/functions";
import { renderToElement } from "@web/core/utils/render";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { isVisible } from "@html_editor/utils/dom_info";

export class GallerySlider extends Interaction {
static selector = ".o_slideshow";
// TODO Support edit-mode enabled.
static disabledInEditableMode = false;

setup() {
this.carouselEl = this.el.classList.contains("carousel") ? this.el : this.el.querySelector(".carousel");
Expand Down Expand Up @@ -69,7 +67,7 @@ export class GallerySlider extends Interaction {
}
this.page += dispatchedEl.classList.contains("o_indicators_left") ? -1 : 1;
this.page = Math.max(0, Math.min(this.nbPages - 1, this.page)); // should not be necessary
Carousel.getOrCreateInstance(this.carouselEl).to(this.page * this.realNbPerPage);
window.Carousel.getOrCreateInstance(this.carouselEl).to(this.page * this.realNbPerPage);
// We dont use hide() before the slide animation in the editor because there is a traceback
// TO DO: fix this traceback
if (!this.editableMode) {
Expand Down Expand Up @@ -114,3 +112,9 @@ export class GallerySlider extends Interaction {
}

registry.category("website.active_elements").add("website.gallery_slider", GallerySlider);

registry
.category("website.editable_active_elements_builders")
.add("website.gallery_slider", {
Interaction: GallerySlider,
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@ export class InstagramPage extends Interaction {
}

setup() {
const iframeEl = document.createElement("iframe");
iframeEl.setAttribute("scrolling", "no");
iframeEl.setAttribute("aria-label", _t("Instagram"));
iframeEl.classList.add("w-100");
this.iframeEl = document.createElement("iframe");
this.iframeEl.setAttribute("scrolling", "no");
this.iframeEl.setAttribute("aria-label", _t("Instagram"));
this.iframeEl.classList.add("w-100");

// In the meantime Instagram doesn't send us a message with the height,
// we use a formula to estimate the height of the iframe (the formula
// has been found with a linear regression).
const iframeWidth = parseInt(getComputedStyle(iframeEl).width);
const iframeWidth = parseInt(getComputedStyle(this.iframeEl).width);
// The profile picture is smaller when width < 432px.
iframeEl.height = 0.659 * iframeWidth + (iframeWidth < 432 ? 156 : 203);
this.iframeEl.height = 0.659 * iframeWidth + (iframeWidth < 432 ? 156 : 203);

// TODO : Check if the next lines can be replace by `this.insert(iframeEl, this.el.querySelector(".o_instagram_container"));`
// TODO : Check if the next lines can be replace by `this.insert(this.iframeEl, this.el.querySelector(".o_instagram_container"));`

this.el.querySelector(".o_instagram_container").appendChild(iframeEl);
this.el.querySelector(".o_instagram_container").appendChild(this.iframeEl);
// TODO : ...observerUnactive() / ...observerActive()
this.registerCleanup(() => { iframeEl.remove(); });
this.registerCleanup(() => { this.iframeEl.remove(); });
}

start() {
const src = `https://www.instagram.com/${this.el.dataset.instagramPage}/embed`;
this.services.website_cookies.manageIframeSrc(iframeEl, src);
this.services.website_cookies.manageIframeSrc(this.iframeEl, src);
}

/**
Expand All @@ -47,10 +47,9 @@ export class InstagramPage extends Interaction {
* @param {Event} ev
*/
onMessage(ev) {
const iframeEl = this.el.querySelector(".o_instagram_container iframe");
// TODO Check if this issue is fixed with the new editor
/*
if (!iframeEl) {
if (!this.iframeEl) {
// TODO: fix this case. We should never end up here. It happens when
// - Drop Instagram snippet
// - Undo
Expand All @@ -61,7 +60,7 @@ export class InstagramPage extends Interaction {
return;
}
*/
if (ev.origin !== "https://www.instagram.com" || iframeEl.contentWindow !== ev.source) {
if (ev.origin !== "https://www.instagram.com" || this.iframeEl.contentWindow !== ev.source) {
return;
}
const evDataJSON = JSON.parse(ev.data);
Expand All @@ -73,7 +72,7 @@ export class InstagramPage extends Interaction {
// Instagram can return a height of 0 before the real height.
if (height) {
// this.options.wysiwyg?.odooEditor.observerUnactive();
iframeEl.height = height;
this.iframeEl.height = height;
// this.options.wysiwyg?.odooEditor.observerActive();
}
}
Expand Down
1 change: 0 additions & 1 deletion addons/website/static/src/snippets/s_website_form/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { registry } from "@web/core/registry";
import { Interaction } from "@website/core/interaction";
import { user } from "@web/core/user";
import { delay } from "@web/core/utils/concurrency";
import { debounce } from "@web/core/utils/timing";
import { _t } from "@web/core/l10n/translation";
import { renderToElement } from "@web/core/utils/render";
import { post } from "@web/core/network/http_service";
Expand Down
4 changes: 2 additions & 2 deletions addons/website/static/tests/core/interaction.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ describe("adding listeners", () => {
},
};
}
const { el } = await startInteraction(Test, TemplateTest);
await startInteraction(Test, TemplateTest);
expect(clicked).toBe(0);
await dblclick("span");
expect(clicked).toBe(3); // event dblclick = click + click + dblclick
Expand Down Expand Up @@ -230,7 +230,7 @@ describe("using selectors", () => {
"_myselector": { "t-att-animal": () => "colibri" },
};
}
const { el } = await startInteraction(Test, `
await startInteraction(Test, `
<div class="test">
<span class="my-selector">coucou</span>
</div>`);
Expand Down
10 changes: 7 additions & 3 deletions addons/website/static/tests/core/interaction_util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Interaction } from "@website/core/interaction";
import { buildEditableInteractions } from "@website/core/website_edit_service";

test("buildEditableInteractions concrete", async () => {
const doStuff = () => {};

class Base extends Interaction {
stuff() {
doStuff();
Expand All @@ -13,7 +15,7 @@ test("buildEditableInteractions concrete", async () => {
};
class Specific extends Base {
otherStuff() {
doOtherStuff();
doStuff("other");
}
}
const builders = [
Expand All @@ -31,6 +33,8 @@ test("buildEditableInteractions concrete", async () => {
});

test("buildEditableInteractions abstract", async () => {
const doStuff = () => {};

class AbstractBase extends Interaction {
stuff() {
doStuff();
Expand All @@ -41,12 +45,12 @@ test("buildEditableInteractions abstract", async () => {
};
class AbstractIntermediate extends AbstractBase {
moreStuff() {
doMoreStuff();
doStuff("more");
}
}
class Specific extends AbstractIntermediate {
otherStuff() {
doOtherStuff();
doStuff("other");
}
}
const builders = [
Expand Down
6 changes: 1 addition & 5 deletions addons/website/static/tests/core/website_core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { animationFrame } from "@odoo/hoot-mock";
import { Component, xml } from "@odoo/owl";
import { makeMockEnv } from "@web/../tests/web_test_helpers";
import { Interaction } from "@website/core/interaction";
import { startInteraction, startInteractions } from "./helpers";
import { registry } from "@web/core/registry";
import { startInteraction } from "./helpers";

test("properly handles case where we have no match for wrapwrap", async () => {
const env = await makeMockEnv();
Expand All @@ -15,13 +14,10 @@ test("properly handles case where we have no match for wrapwrap", async () => {


test("wait for translation before starting interactions", async () => {
let flag = false;

class Test extends Interaction {
static selector = ".test";

setup() {
flag = true;
expect("localization" in this.services).toBe(true);
}
}
Expand Down
2 changes: 0 additions & 2 deletions addons/website/static/tests/interactions/anchor_slide.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { expect, test } from "@odoo/hoot";
import { animationFrame, click } from "@odoo/hoot-dom";
import { advanceTime } from "@odoo/hoot-mock";
import { patchWithCleanup } from "@web/../tests/web_test_helpers";
import { AnchorSlide } from "@website/interactions/anchor_slide";
import {
isElementInViewport,
startInteractions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ test("plausible push interaction notifies plausible if .js_plausible_push", asyn
<input type='hidden' class='js_plausible_push' data-event-name='Lead Generation' data-event-params='{"CTA": "Contact Us"}' />
</div>`);
expect(core.interactions.length).toBe(1);
expect(plausible.q[0][0]).toBe("Lead Generation");
expect(plausible.q[0][1]).toEqual({ props: '{"CTA": "Contact Us"}' });
expect(window.plausible.q[0][0]).toBe("Lead Generation");
expect(window.plausible.q[0][1]).toEqual({ props: '{"CTA": "Contact Us"}' });
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { expect, test } from "@odoo/hoot";
import { animationFrame, click, scroll } from "@odoo/hoot-dom";
import { advanceTime } from "@odoo/hoot-mock";
import { onRpc } from "@web/../tests/web_test_helpers";
import { registry } from "@web/core/registry";
import { Interaction } from "@website/core/interaction";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ test("form formats date in edit mode", async () => {
const { core, el } = await startInteractions(formXml, { waitForStart: true, editMode: true });
expect(core.interactions.length).toBe(1);
const formEl = el.querySelector("form");
const dateEl = el.querySelector("input[name=When]");
const dateEl = formEl.querySelector("input[name=When]");
expect(dateEl.value).toBe("01/01/2025 10:00:00");
// Verify that non-edit code did not run.
const dateField = dateEl.closest(".s_website_form_datetime");
Expand All @@ -79,7 +79,7 @@ test("form is NOT prefilled in edit mode", async () => {
const { core, el } = await startInteractions(formXml, { waitForStart: true, editMode: true });
expect(core.interactions.length).toBe(1);
const formEl = el.querySelector("form");
const companyEl = el.querySelector("input[name=company]");
const companyEl = formEl.querySelector("input[name=company]");
expect(companyEl.value).toBe("");
});

Expand All @@ -89,6 +89,6 @@ test("form is NOT prefilled in translate mode", async () => {
const { core, el } = await startInteractions(formXml, { waitForStart: true, translateMode: true });
expect(core.interactions.length).toBe(1);
const formEl = el.querySelector("form");
const companyEl = el.querySelector("input[name=company]");
const companyEl = formEl.querySelector("input[name=company]");
expect(companyEl.value).toBe("");
});
24 changes: 8 additions & 16 deletions addons/website/static/tests/interactions/snippets/form.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, test } from "@odoo/hoot";
import { click, fill } from "@odoo/hoot-dom";
import { advanceTime, Deferred } from "@odoo/hoot-mock";
import { MockServer, onRpc, patchWithCleanup, webModels } from "@web/../tests/web_test_helpers";
import { MockServer, onRpc, patchWithCleanup } from "@web/../tests/web_test_helpers";
import {
startInteractions,
setupInteractionWhiteList,
Expand Down Expand Up @@ -89,11 +89,11 @@ test("form checks conditions", async () => {
`);
expect(core.interactions.length).toBe(1);
const formEl = el.querySelector("form");
const nameEl = el.querySelector("input[name=name]");
const mailEl = el.querySelector("input[name=email_from]");
const subjectEl = el.querySelector("input[name=subject]");
const questionEl = el.querySelector("textarea[name=description]");
const submitEl = el.querySelector("a.s_website_form_send");
const nameEl = formEl.querySelector("input[name=name]");
const mailEl = formEl.querySelector("input[name=email_from]");
const subjectEl = formEl.querySelector("input[name=subject]");
const questionEl = formEl.querySelector("textarea[name=description]");
const submitEl = formEl.querySelector("a.s_website_form_send");

function checkVisibility(
isNameVisible,
Expand Down Expand Up @@ -241,17 +241,9 @@ test("form prefilled conditional", async () => {
`);
expect(core.interactions.length).toBe(1);
const formEl = el.querySelector("form");
const nameEl = el.querySelector("input[name=name]");
const phoneEl = el.querySelector("input[name=phone]");
const nameEl = formEl.querySelector("input[name=name]");
const phoneEl = formEl.querySelector("input[name=phone]");

function checkPhoneVisibility(isVisible) {
const fieldEl = field(el);
if (isVisible) {
expect(fieldEl).not.toHaveClass("d-none");
} else {
expect(fieldEl).toHaveClass("d-none");
}
}
expect(nameEl).not.toBe(undefined);
expect(nameEl.value).toBe("Mitchell Admin");
expect(phoneEl).not.toBe(undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ test("searchbar triggers a search when text is entered", async () => {

test("searchbar selects first result on cursor down", async () => {
supportAutocomplete();
const { core, el } = await startInteractions(searchTemplate);
const { el } = await startInteractions(searchTemplate);
const formEl = el.querySelector("form");
const inputEl = formEl.querySelector("input[type=search]");
await click(inputEl);
Expand All @@ -107,7 +107,7 @@ test("searchbar selects first result on cursor down", async () => {

test("searchbar selects last result on cursor up", async () => {
supportAutocomplete();
const { core, el } = await startInteractions(searchTemplate);
const { el } = await startInteractions(searchTemplate);
const formEl = el.querySelector("form");
const inputEl = formEl.querySelector("input[type=search]");
await click(inputEl);
Expand All @@ -124,7 +124,7 @@ test("searchbar selects last result on cursor up", async () => {

test("searchbar removes results on escape", async () => {
supportAutocomplete();
const { core, el } = await startInteractions(searchTemplate);
const { el } = await startInteractions(searchTemplate);
const formEl = el.querySelector("form");
const inputEl = formEl.querySelector("input[type=search]");
await click(inputEl);
Expand Down
Loading