diff --git a/addons/html_builder/static/src/builder/options/image_gallery_option.js b/addons/html_builder/static/src/builder/options/image_gallery_option.js index 370172757cb75..470e50907eaa7 100644 --- a/addons/html_builder/static/src/builder/options/image_gallery_option.js +++ b/addons/html_builder/static/src/builder/options/image_gallery_option.js @@ -1,5 +1,6 @@ import { registry } from "@web/core/registry"; import { Plugin } from "@html_editor/plugin"; +import { applyModifications, loadImageInfo } from "@html_editor/utils/image_processing"; class ImageGalleryOption extends Plugin { static id = "ImageGalleryOption"; @@ -17,18 +18,21 @@ class ImageGalleryOption extends Plugin { getActions() { return { addImage: { - load: async () => - new Promise((resolve) => { + load: async ({ editingElement }) => { + let selectedImages; + await new Promise((resolve) => { this.dependencies.media.openMediaDialog({ onlyImages: true, multiImages: true, save: (images) => { - resolve(images); + selectedImages = images; + resolve(); }, }); - }), - apply: ({ editingElement, loadResult: images }) => { - addImages(images, editingElement); + }); + await addImages(selectedImages, editingElement); + }, + apply: () => { this.dependencies.history.addStep(); }, }, @@ -43,7 +47,7 @@ class ImageGalleryOption extends Plugin { /** * Add the images selected in the media dialog in the gallery */ -function addImages(images, imageGalleryElement) { +async function addImages(images, imageGalleryElement) { const container = getContainer(imageGalleryElement); if (!container) { return; @@ -52,6 +56,7 @@ function addImages(images, imageGalleryElement) { const lastImage = getImages(imageGalleryElement).at(-1); let lastIndex = lastImage ? getIndex(lastImage) : -1; + const imagePromises = []; for (const image of images) { image.classList.add( "d-block", @@ -62,9 +67,28 @@ function addImages(images, imageGalleryElement) { "object-fit-cover" ); image.dataset.index = ++lastIndex; - // TODO: Change mimetype + imagePromises.push(transformImageToWebp(image)); + } + await Promise.all(imagePromises); + if (images.length > 0) { + relayout(imageGalleryElement); + } +} + +async function transformImageToWebp(image) { + await loadImageInfo(image); + if ( + image.dataset.mimetype && + !["image/gif", "image/svg+xml", "image/webp"].includes(image.dataset.mimetype) + ) { + // Convert to webp but keep original width. + image.dataset.mimetype = "image/webp"; + const src = await applyModifications(image, { + mimetype: "image/webp", + }); + image.src = src; + image.classList.add("o_modified_image_to_save"); } - relayout(imageGalleryElement); } /** diff --git a/addons/html_builder/static/tests/options/image_gallery.test.js b/addons/html_builder/static/tests/options/image_gallery.test.js index 0cc092798b0fc..a990c2167b76f 100644 --- a/addons/html_builder/static/tests/options/image_gallery.test.js +++ b/addons/html_builder/static/tests/options/image_gallery.test.js @@ -9,7 +9,7 @@ const base64Img = "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA\n AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO\n 9TXL0Y4OHwAAAABJRU5ErkJggg=="; test("Add image in gallery", async () => { - onRpc("/web/dataset/call_kw/ir.attachment/search_read", (test) => [ + onRpc("/web/dataset/call_kw/ir.attachment/search_read", () => [ { id: 1, name: "logo", @@ -19,6 +19,12 @@ test("Add image in gallery", async () => { public: true, }, ]); + + onRpc("/html_editor/get_image_info", () => { + expect.step("get_image_info"); + return {}; + }); + await setupWebsiteBuilder( `