diff --git a/addons/html_builder/static/src/core/building_blocks/builder_colorpicker.js b/addons/html_builder/static/src/core/building_blocks/builder_colorpicker.js index fa2cf871efb4d..1adb4480da43e 100644 --- a/addons/html_builder/static/src/core/building_blocks/builder_colorpicker.js +++ b/addons/html_builder/static/src/core/building_blocks/builder_colorpicker.js @@ -78,12 +78,14 @@ export class BuilderColorPicker extends Component { static props = { ...basicContainerBuilderComponentProps, noTransparency: { type: Boolean, optional: true }, + withGradient: { type: Boolean, optional: true }, unit: { type: String, optional: true }, title: { type: String, optional: true }, getUsedCustomColors: { type: Function, optional: true }, }; static defaultProps = { getUsedCustomColors: () => [], + withGradient: true, }; static components = { ColorSelector: ColorSelector, @@ -105,6 +107,7 @@ export class BuilderColorPicker extends Component { getUsedCustomColors: this.props.getUsedCustomColors, colorPrefix: "color-prefix-", noTransparency: this.props.noTransparency, + withGradient: this.props.withGradient, }, { onClose: onPreviewRevert, diff --git a/addons/html_builder/static/src/plugins/dynamic_svg_option.js b/addons/html_builder/static/src/plugins/dynamic_svg_option.js new file mode 100644 index 0000000000000..706b7a6db822f --- /dev/null +++ b/addons/html_builder/static/src/plugins/dynamic_svg_option.js @@ -0,0 +1,25 @@ +import { Component } from "@odoo/owl"; +import { defaultBuilderComponents } from "../core/default_builder_components"; +import { useDomState } from "@html_builder/core/building_blocks/utils"; + +export class DynamicSvgOption extends Component { + static template = "html_builder.DynamicSvgOption"; + static components = { ...defaultBuilderComponents }; + static props = {}; + + setup() { + this.domState = useDomState((imgEl) => { + const colors = {}; + const searchParams = new URL(imgEl.src, window.location.origin).searchParams; + for (const colorName of ["c1", "c2", "c3", "c4", "c5"]) { + const color = searchParams.get(colorName); + if (color) { + colors[colorName] = color; + } + } + return { + colors: colors, + }; + }); + } +} diff --git a/addons/html_builder/static/src/plugins/dynamic_svg_option.xml b/addons/html_builder/static/src/plugins/dynamic_svg_option.xml new file mode 100644 index 0000000000000..fdd9f6bd8d708 --- /dev/null +++ b/addons/html_builder/static/src/plugins/dynamic_svg_option.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/addons/html_builder/static/src/plugins/dynamic_svg_option_plugin.js b/addons/html_builder/static/src/plugins/dynamic_svg_option_plugin.js new file mode 100644 index 0000000000000..7964333f3b800 --- /dev/null +++ b/addons/html_builder/static/src/plugins/dynamic_svg_option_plugin.js @@ -0,0 +1,51 @@ +import { registry } from "@web/core/registry"; +import { Plugin } from "@html_editor/plugin"; +import { DynamicSvgOption } from "./dynamic_svg_option"; +import { normalizeCSSColor } from "@web/core/utils/colors"; +import { loadImage } from "@html_editor/utils/image_processing"; + +class DynamicSvgOptionPlugin extends Plugin { + static id = "DynamicSvgOption"; + resources = { + builder_options: [ + { + OptionComponent: DynamicSvgOption, + props: {}, + selector: "img[src^='/html_editor/shape/'], img[src^='/web_editor/shape/']", + }, + ], + builder_actions: this.getActions(), + }; + + getActions() { + return { + svgColor: { + getValue: ({ editingElement: imgEl, param: { mainParam: colorName } }) => { + const searchParams = new URL(imgEl.src, window.location.origin).searchParams; + return searchParams.get(colorName); + }, + load: async ({ + editingElement: imgEl, + param: { mainParam: colorName }, + value: color, + }) => { + const newURL = new URL(imgEl.src, window.location.origin); + newURL.searchParams.set(colorName, normalizeCSSColor(color)); + const src = newURL.pathname + newURL.search; + await loadImage(src); + return src; + }, + apply: ({ + editingElement: imgEl, + param: { mainParam: colorName }, + value: color, + loadResult: newSrc, + }) => { + imgEl.setAttribute("src", newSrc); + }, + }, + }; + } +} + +registry.category("website-plugins").add(DynamicSvgOptionPlugin.id, DynamicSvgOptionPlugin); diff --git a/addons/html_editor/models/ir_attachment.py b/addons/html_editor/models/ir_attachment.py index 4f504d2a15055..be9aacf0cb02f 100644 --- a/addons/html_editor/models/ir_attachment.py +++ b/addons/html_editor/models/ir_attachment.py @@ -37,7 +37,7 @@ def _compute_local_url(self): def _compute_image_src(self): for attachment in self: # Only add a src for supported images - if attachment.mimetype not in SUPPORTED_IMAGE_MIMETYPES: + if not attachment.mimetype or attachment.mimetype.split(';')[0] not in SUPPORTED_IMAGE_MIMETYPES: attachment.image_src = False continue diff --git a/addons/web/static/src/core/color_picker/color_picker.js b/addons/web/static/src/core/color_picker/color_picker.js index 063dc5fead687..ab4fbf2c08fd6 100644 --- a/addons/web/static/src/core/color_picker/color_picker.js +++ b/addons/web/static/src/core/color_picker/color_picker.js @@ -43,10 +43,12 @@ export class ColorPicker extends Component { applyColorResetPreview: Function, colorPrefix: { type: String }, noTransparency: { type: Boolean, optional: true }, + withGradient: { type: Boolean, optional: true }, close: { type: Function, optional: true }, }; static defaultProps = { close: () => {}, + withGradient: true, }; setup() { diff --git a/addons/web/static/src/core/color_picker/color_picker.xml b/addons/web/static/src/core/color_picker/color_picker.xml index 28fd4b86caddb..ed8a56add9db3 100644 --- a/addons/web/static/src/core/color_picker/color_picker.xml +++ b/addons/web/static/src/core/color_picker/color_picker.xml @@ -13,6 +13,7 @@ Custom