From 9b11abda493500cc79ce6f6f8df3f2e3855900b0 Mon Sep 17 00:00:00 2001
From: "Louis (loco)" <loco@odoo.com>
Date: Mon, 22 May 2023 10:22:19 +0000
Subject: [PATCH] [FIX] web_editor: show background image options after save

Steps to reproduce the bug:
- Add a cover snippet on the website.
- Change the background image with one of your own.
- Save and edit again.
=> Options such as "Filter", "Width" and "Quality" do not appear
anymore.

The problem is that the `src` attribute of the background image is not
correctly updated when initializing the image. This is because the
target used to recover the URL of the background image is the snippet
and not the image itself. This problem is resolved by ensuring that the
argument of the function `getBgImageURL` is the background image. Now
that the `src` attribute is correctly updated, the `computeVisibility`
function of the the `BackgroundOptimize` option works properly and the
options "Filter", "Width" and "Quality" are displayed as wanted.

Note that now, the dataset of the target is filtered with a "white list"
(BACKGROUND_IMAGE_ATTRIBUTES) before being copied in the dataset of
`this.img`. Indeed, if the parallax is set to "None" for example, we do
not want data attributes such as `data-snippet` to be copied in the
dataset of `this.img`.

task-3287330

X-original-commit: https://github.com/odoo/odoo/commit/31ba9060723f365d16d51d3de0acf42c5e95f63b
Part-of: odoo/odoo#121682
---
 .../web_editor/static/src/js/common/utils.js  | 27 +++++++++++++++++++
 .../static/src/js/editor/snippets.options.js  | 22 ++++++++-------
 2 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/addons/web_editor/static/src/js/common/utils.js b/addons/web_editor/static/src/js/common/utils.js
index 110ab83add4c..4b9b7c3d5a47 100644
--- a/addons/web_editor/static/src/js/common/utils.js
+++ b/addons/web_editor/static/src/js/common/utils.js
@@ -47,6 +47,13 @@ const DEFAULT_PALETTE = {
     '4': '#FFFFFF',
     '5': '#383E45',
 };
+/**
+ * Set of all the data attributes relative to the background images.
+ */
+const BACKGROUND_IMAGE_ATTRIBUTES = new Set([
+    "originalId", "originalSrc", "mimetype", "resizeWidth", "glFilter", "quality", "bgSrc",
+    "filterOptions",
+]);
 
 /**
  * Computes the number of "px" needed to make a "rem" unit. Subsequent calls
@@ -350,6 +357,24 @@ function _getColorClass(el, colorNames, prefix) {
     const prefixedColorNames = _computeColorClasses(colorNames, prefix);
     return el.classList.value.split(' ').filter(cl => prefixedColorNames.includes(cl)).join(' ');
 }
+/**
+ * Add one or more new attributes related to background images in the
+ * BACKGROUND_IMAGE_ATTRIBUTES set.
+ *
+ * @param {...string} newAttributes The new attributes to add in the
+ * BACKGROUND_IMAGE_ATTRIBUTES set.
+ */
+function _addBackgroundImageAttributes(...newAttributes) {
+    BACKGROUND_IMAGE_ATTRIBUTES.add(...newAttributes);
+}
+/**
+ * Check if an attribute is in the BACKGROUND_IMAGE_ATTRIBUTES set.
+ *
+ * @param {string} attribute The attribute that has to be checked.
+ */
+function _isBackgroundImageAttribute(attribute) {
+    return BACKGROUND_IMAGE_ATTRIBUTES.has(attribute);
+}
 
 return {
     CSS_SHORTHANDS: CSS_SHORTHANDS,
@@ -369,5 +394,7 @@ return {
     backgroundImageCssToParts: _backgroundImageCssToParts,
     backgroundImagePartsToCss: _backgroundImagePartsToCss,
     getColorClass: _getColorClass,
+    addBackgroundImageAttributes: _addBackgroundImageAttributes,
+    isBackgroundImageAttribute: _isBackgroundImageAttribute,
 };
 });
diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js
index f87dbf81e4d5..324cd5822498 100644
--- a/addons/web_editor/static/src/js/editor/snippets.options.js
+++ b/addons/web_editor/static/src/js/editor/snippets.options.js
@@ -17,6 +17,7 @@ const {
     backgroundImageCssToParts,
     backgroundImagePartsToCss,
     DEFAULT_PALETTE,
+    isBackgroundImageAttribute,
 } = weUtils;
 var weWidgets = require('wysiwyg.widgets');
 const {
@@ -5919,15 +5920,18 @@ registry.BackgroundOptimize = ImageHandlerOption.extend({
      */
     async _loadImageInfo() {
         this.img = new Image();
-        Object.entries(this.$target[0].dataset).filter(([key]) =>
-            // Avoid copying dynamic editor attributes
-            !['oeId','oeModel', 'oeField', 'oeXpath', 'noteId'].includes(key)
-        ).forEach(([key, value]) => {
-            this.img.dataset[key] = value;
-        });
-        const src = getBgImageURL(this.$target[0]);
-        // Don't set the src if not relative (ie, not local image: cannot be modified)
-        this.img.src = src.startsWith('/') ? src : '';
+        const targetEl = this.$target[0].classList.contains("oe_img_bg")
+            ? this.$target[0] : this.$target[0].querySelector(".oe_img_bg");
+        if (targetEl) {
+            Object.entries(targetEl.dataset).filter(([key]) =>
+                isBackgroundImageAttribute(key)).forEach(([key, value]) => {
+                this.img.dataset[key] = value;
+            });
+            const src = getBgImageURL(targetEl);
+            // Don't set the src if not relative (ie, not local image: cannot be
+            // modified)
+            this.img.src = src.startsWith("/") ? src : "";
+        }
         return await this._super(...arguments);
     },
     /**
-- 
GitLab