diff --git a/awesome_website/__manifest__.py b/awesome_website/__manifest__.py index 9f34d035002..9c0fe0b3bb8 100644 --- a/awesome_website/__manifest__.py +++ b/awesome_website/__manifest__.py @@ -1,31 +1,52 @@ { - 'name': "Awesome Website", - - 'summary': """ + "name": "Awesome Website", + "summary": """ Companion addon for the Odoo JS Framework Training """, - - 'description': """ + "description": """ Companion addon for the Odoo JS Framework Training """, - - 'author': "Odoo", - 'website': "https://www.odoo.com", - + "author": "Odoo", + "website": "https://www.odoo.com", # Categories can be used to filter modules in modules listing # Check https://github.com/odoo/odoo/blob/19.0/odoo/addons/base/data/ir_module_category_data.xml # for the full list - 'category': 'Tutorials', - 'version': '0.2', - + "category": "Tutorials", + "version": "0.2", # any module necessary for this one to work correctly - 'depends': ['website'], - 'application': True, - 'installable': True, - 'data': [ - 'data/images.xml', + "depends": ["website"], + "application": True, + "installable": True, + "data": [ + "data/images.xml", + "views/snippets/snippets.xml", + "views/snippets/s_image_comparison.xml", + "views/snippets/static_banner.xml", ], - 'assets': { + "assets": { + "web.assets_frontend": [ + "awesome_website/static/src/interactions/**/*", + "awesome_website/static/src/snippets/**/*", + "awesome_website/static/src/components/**/*", + ("remove", "awesome_website/static/src/interactions/**/*.edit.*"), + ("remove", "awesome_website/static/src/snippets/**/*.edit.*"), + ], + "website.assets_inside_builder_iframe": [ + "awesome_website/static/src/snippets/**/*.edit.*", + ], + "website.website_builder_assets": [ + "awesome_website/static/src/builder/**/*", + ], + "web.assets_unit_tests": [ + "website/static/tests/builder/website_helpers.js", + "awesome_website/static/tests/interactions/**/*", + "awesome_website/static/tests/builder/**/*", + ], + "web.assets_unit_tests_setup": [ + "awesome_website/static/src/interactions/**/*", + "awesome_website/static/src/snippets/**/*", + "awesome_website/static/src/builder/**/*", + ], }, - 'license': 'AGPL-3' + "license": "AGPL-3", } diff --git a/awesome_website/static/src/builder/image_comparison_colorslide.xml b/awesome_website/static/src/builder/image_comparison_colorslide.xml new file mode 100644 index 00000000000..05998f0dba9 --- /dev/null +++ b/awesome_website/static/src/builder/image_comparison_colorslide.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/awesome_website/static/src/components/static_banner.js b/awesome_website/static/src/components/static_banner.js new file mode 100644 index 00000000000..729bc1d5bdb --- /dev/null +++ b/awesome_website/static/src/components/static_banner.js @@ -0,0 +1,14 @@ +import { Component, xml } from "@odoo/owl"; +import { registry } from "@web/core/registry"; + + +export class StaticBanner extends Component { + static template = xml`

Hello, !

` + static props = { + name: { + type: String, + }, + }; +} + +registry.category("public_components").add("static_banner", StaticBanner); diff --git a/awesome_website/static/src/interactions/main.js b/awesome_website/static/src/interactions/main.js index fbcfe5f773b..b8923999c75 100644 --- a/awesome_website/static/src/interactions/main.js +++ b/awesome_website/static/src/interactions/main.js @@ -2,14 +2,16 @@ import { registry } from "@web/core/registry"; import { Interaction } from "@web/public/interaction"; class Main extends Interaction { - /* Interaction's lifecycle methods: + static selector = "main"; - setup() { } - async willStart() { } - start() { } - destroy() { } - - */ + dynamicContent = { + _root: { + "t-out": () => { + const now = new Date(); + return now.toLocaleString('en-US'); + } + } + }; } -registry.category("public.interactions").add("awesome_website.main", Main); +// registry.category("public.interactions").add("awesome_website.main", Main); diff --git a/awesome_website/static/src/interactions/mouse_follower.js b/awesome_website/static/src/interactions/mouse_follower.js new file mode 100644 index 00000000000..5d4e5facc68 --- /dev/null +++ b/awesome_website/static/src/interactions/mouse_follower.js @@ -0,0 +1,41 @@ +import { registry } from "@web/core/registry"; +import { Interaction } from "@web/public/interaction"; + +export class MouseFollower extends Interaction { + static selector = "#wrapwrap"; + + dynamicSelectors = { + ...this.dynamicSelectors, + _highlighter: () => this.highlighter, + } + + dynamicContent = { + _root: { + "t-on-pointermove": this.debounced(this.onPointerMove, 5), + }, + _highlighter: { + "t-att-style": () => ({ + top: `${this.my}px`, + left: `${this.mx}px`, + }), + }, + }; + + setup() { + this.mx = 0; + this.my = 0; + this.highlighter = document.createElement("div"); + this.highlighter.classList.add("x_mouse_follower"); + } + + start() { + this.insert(this.highlighter); + } + + onPointerMove(ev) { + this.mx = ev.clientX; + this.my = ev.clientY; + } +} + +registry.category("public.interactions").add("awesome_website.mouse_follower", MouseFollower); diff --git a/awesome_website/static/src/snippets/s_image_comparison/000.edit.scss b/awesome_website/static/src/snippets/s_image_comparison/000.edit.scss index d01a0fe645b..2a36d221cce 100644 --- a/awesome_website/static/src/snippets/s_image_comparison/000.edit.scss +++ b/awesome_website/static/src/snippets/s_image_comparison/000.edit.scss @@ -1,5 +1,23 @@ .o_image_comparison_container { + .o_image_comparison_horizontal & { + --slider-left: var(--slider-img-left); + --slider-right: calc(var(--slider-left) + 1%); + --slider-top: 0; + --slider-bottom: 100%; + + .o_rtl & { + --slider-right: var(--slider-img-right); + --slider-left: calc(var(--slider-right) - 1%); + } + } + .o_image_comparison_vertical & { + --slider-top: var(--slider-img-top); + --slider-bottom: calc(var(--slider-top) + 1%); + --slider-left: var(--slider-img-left); + --slider-right: var(--slider-img-right); + } .o_image_comparison_slider { + pointer-events: none; clip-path: rect(0 calc(var(--slider-position) + 1%) 100% var(--slider-position)); .o_rtl & { diff --git a/awesome_website/static/src/snippets/s_image_comparison/000.scss b/awesome_website/static/src/snippets/s_image_comparison/000.scss index 10edad69f8d..5886e865f1e 100644 --- a/awesome_website/static/src/snippets/s_image_comparison/000.scss +++ b/awesome_website/static/src/snippets/s_image_comparison/000.scss @@ -1,6 +1,41 @@ .o_image_comparison_container { --slider-position: 50%; + .o_image_comparison_horizontal & { + --handle-left: var(--slider-position); + --handle-top: 50%; + --slider-img-left: var(--slider-position); + --slider-img-right: 100%; + --slider-img-top: 0; + --slider-cursor: ew-resize; + --slider-height: 100vh; + --slider-width: 4px; + --slider-margin-inline: -2px; + --slider-margin-block: 0; + --slider-writing-mode: horizontal-tb; + --slider-transform: unset; + + .o_rtl & { + --slider-img-left: 0; + --slider-img-right: calc(100% - var(--slider-position)); + } + } + .o_image_comparison_vertical & { + --handle-left: 50%; + --handle-top: var(--slider-position); + --slider-img-top: var(--slider-position); + --slider-img-left: 0; + --slider-img-right: 100%; + --slider-cursor: ns-resize; + --slider-height: 4px; + --slider-width: 100vw; + --slider-margin-inline: 0; + --slider-margin-block: -2px; + --slider-writing-mode: vertical-rl; + --slider-transform: scaleY(-1); + } + + img { grid-area: 1 / 1; width: 100%; diff --git a/awesome_website/static/src/snippets/s_image_comparison/image_comparison.edit.js b/awesome_website/static/src/snippets/s_image_comparison/image_comparison.edit.js new file mode 100644 index 00000000000..f49fc567483 --- /dev/null +++ b/awesome_website/static/src/snippets/s_image_comparison/image_comparison.edit.js @@ -0,0 +1,12 @@ +import { registry } from "@web/core/registry"; +import { ImageComparison } from "./image_comparison"; + +const ImageComparisonEdit = (I) => + class extends I { + onSliderSlide() { } + }; + +registry.category("public.interactions.edit").add("awesome_website.image_comparison", { + Interaction: ImageComparison, + mixin: ImageComparisonEdit, +}); diff --git a/awesome_website/static/src/snippets/s_image_comparison/image_comparison.js b/awesome_website/static/src/snippets/s_image_comparison/image_comparison.js new file mode 100644 index 00000000000..4c18ba0808c --- /dev/null +++ b/awesome_website/static/src/snippets/s_image_comparison/image_comparison.js @@ -0,0 +1,28 @@ +import { registry } from "@web/core/registry"; +import { Interaction } from "@web/public/interaction"; + +export class ImageComparison extends Interaction { + static selector = ".s_image_comparison"; + + dynamicContent = { + ".o_image_comparison_slider": { + "t-on-input": this.debounced(this.onSliderSlide, 5) + }, + ".o_image_comparison_container": { + "t-att-style": () => ({ + "--slider-position": this.sliderPosition, + }), + }, + }; + + setup() { + this.sliderPosition = "50%"; + } + + onSliderSlide() { + let value = document.querySelector(".o_image_comparison_slider").value; + this.sliderPosition = `${value}%`; + } +} + +registry.category("public.interactions").add("awesome_website.image_comparison", ImageComparison); diff --git a/awesome_website/static/tests/builder/image_comparison_colorslide.test.js b/awesome_website/static/tests/builder/image_comparison_colorslide.test.js new file mode 100644 index 00000000000..f2bc067b296 --- /dev/null +++ b/awesome_website/static/tests/builder/image_comparison_colorslide.test.js @@ -0,0 +1,30 @@ +import { expect, manuallyDispatchProgrammaticEvent, test } from "@odoo/hoot"; +import { defineWebsiteModels, setupWebsiteBuilderWithSnippet } from "@website/../tests/builder/website_helpers"; +import { contains, defineStyle } from "@web/../tests/web_test_helpers"; +import { animationFrame, queryOne } from "@odoo/hoot-dom"; + +defineWebsiteModels(); + +test("Change slider handle color using the custom builder option", async () => { + defineStyle(`* { transition: none !important; }`); + await setupWebsiteBuilderWithSnippet("s_image_comparison", { loadIframeBundles: true }); + + await contains(":iframe .s_image_comparison").click(); + + expect("[data-label='Pick Slider Color']").toHaveCount(1); + + await contains("[data-label='Pick Slider Color'] .o_we_color_preview").click(); + + await contains(".o-hb-colorpicker-popover .custom-tab").click(); + await animationFrame(); + + const hexInput = queryOne(".o-hb-colorpicker-popover input[data-color-method='hex']"); + expect(hexInput).toBeDisplayed(); + hexInput.value = "#ff0000"; + await manuallyDispatchProgrammaticEvent(hexInput, "input", { bubbles: true }); + await animationFrame(); + + expect(":iframe .s_image_comparison .o_image_comparison_handle").toHaveStyle({ + "background-color": "rgb(255, 0, 0)", + }); +}); diff --git a/awesome_website/static/tests/interactions/image_comparison.test.js b/awesome_website/static/tests/interactions/image_comparison.test.js new file mode 100644 index 00000000000..fe7189e625d --- /dev/null +++ b/awesome_website/static/tests/interactions/image_comparison.test.js @@ -0,0 +1,34 @@ +import { advanceTime, expect, manuallyDispatchProgrammaticEvent, queryOne, test } from "@odoo/hoot"; +import { setupInteractionWhiteList, startInteractions } from "@web/../tests/public/helpers"; +import { defineStyle } from "@web/../tests/web_test_helpers"; + +setupInteractionWhiteList("awesome_website.image_comparison"); + +test("image comparison slider should update the value of the input.", async () => { + defineStyle(`* { transition: none !important; }`); + const { core } = await startInteractions(` +
+
+
+ + + +
+
+
+
+ `); + + expect(core.interactions).toHaveLength(1); + expect("input").toHaveStyle({ "--slider-position": "50%" }); + + for (var input_value = 10; input_value <= 100; input_value += 10) { + let input = queryOne("input"); + input.value = `${input_value}`; + await manuallyDispatchProgrammaticEvent(input, "input", { bubbles: true }); + await advanceTime(5); + + expect("input").toHaveStyle({ "--slider-position": `${input_value}%` }); + } + +}); diff --git a/awesome_website/views/snippets/s_image_comparison.xml b/awesome_website/views/snippets/s_image_comparison.xml index a946cc01a03..38e2f7fe30d 100644 --- a/awesome_website/views/snippets/s_image_comparison.xml +++ b/awesome_website/views/snippets/s_image_comparison.xml @@ -1,8 +1,15 @@ - - - + diff --git a/awesome_website/views/snippets/snippets.xml b/awesome_website/views/snippets/snippets.xml new file mode 100644 index 00000000000..4be06cc6151 --- /dev/null +++ b/awesome_website/views/snippets/snippets.xml @@ -0,0 +1,15 @@ + + + + diff --git a/awesome_website/views/snippets/static_banner.xml b/awesome_website/views/snippets/static_banner.xml new file mode 100644 index 00000000000..be29fde2a4f --- /dev/null +++ b/awesome_website/views/snippets/static_banner.xml @@ -0,0 +1,8 @@ + + + +