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
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
25 changes: 25 additions & 0 deletions addons/html_builder/static/src/plugins/dynamic_svg_option.js
Original file line number Diff line number Diff line change
@@ -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,
};
});
}
}
12 changes: 12 additions & 0 deletions addons/html_builder/static/src/plugins/dynamic_svg_option.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">

<t t-name="html_builder.DynamicSvgOption">
<BuilderRow label.translate="Dynamic Colors" action="'svgColor'">
<t t-foreach="Object.keys(domState.colors)" t-as="colorName" t-key="colorName">
<BuilderColorPicker actionParam="colorName" withGradient="false"/>
</t>
</BuilderRow>
</t>

</templates>
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion addons/html_editor/models/ir_attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions addons/web/static/src/core/color_picker/color_picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
3 changes: 2 additions & 1 deletion addons/web/static/src/core/color_picker/color_picker.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Custom
</button>
<button class="btn btn-sm btn-light"
t-if="props.withGradient"
t-att-class="{active: state.activeTab === 'gradient'}"
t-on-click="() => this.setTab('gradient')">
Gradient
Expand Down Expand Up @@ -74,7 +75,7 @@
noTransparency="props.noTransparency" />
</div>
</t>
<t t-if="state.activeTab==='gradient'">
<t t-if="state.activeTab==='gradient' and props.withGradient">
<div class="o_colorpicker_sections p-2" t-on-click="onColorApply" t-on-mouseover="onColorHover" t-on-mouseout="onColorHoverOut" t-on-focusin="onColorHover" t-on-focusout="onColorHoverOut">
<t t-foreach="this.DEFAULT_GRADIENT_COLORS" t-as="gradient" t-key="gradient">
<button class="w-50 m-0 o_color_button btn" t-attf-style="background-image: #{gradient};" t-att-data-color="gradient"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,8 @@ export class ImageSelector extends FileSelector {
const mediaUrl = imgEl.src;
try {
const response = await fetch(mediaUrl);
if (response.headers.get('content-type') === 'image/svg+xml') {
const contentType = response.headers.get("content-type");
if (contentType && contentType.startsWith("image/svg+xml")) {
let svg = await response.text();
const dynamicColors = {};
const combinedColorsRegex = new RegExp(Object.values(weUtils.DEFAULT_PALETTE).join('|'), 'gi');
Expand Down