[FIX] web_editor: fix media dialog's svg upload

Before this commit, the media dialog was not handling properly the
upload of svg files from the media library: a whole part of the original
ImageWidget was missing in the converted media dialog from [1], which
was converting the svg with the appropriate color codes from the color
palette, to allow for color customization.
See original file from 15.4: web_editor/static/src/js/widgets/media.js.

Also, it was not displaying those svg correctly with the appropriate
background.

This commit fixes those issues by adding back the code handling the
dynamic colors detection and the background css rule.

[1]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b

task-2687506

Part-of: odoo/odoo#95955
This commit is contained in:
Younn Olivier
2022-07-18 18:41:29 +02:00
parent 72051ad58a
commit f2111cb37a
3 changed files with 44 additions and 5 deletions
@@ -1,7 +1,7 @@
/** @odoo-module */
import { useService } from '@web/core/utils/hooks';
import { getCSSVariableValue } from 'web_editor.utils';
import { getCSSVariableValue, DEFAULT_PALETTE } from 'web_editor.utils';
import { Attachment, FileSelector, IMAGE_MIMETYPES, IMAGE_EXTENSIONS } from './file_selector';
const { useRef, useState, useEffect } = owl;
@@ -23,7 +23,10 @@ export class AutoResizeImage extends Attachment {
}, () => []);
}
onImageLoaded() {
async onImageLoaded() {
if (this.props.onLoaded) {
await this.props.onLoaded(this.image.el);
}
const aspectRatio = this.image.el.offsetWidth / this.image.el.offsetHeight;
const width = aspectRatio * this.props.minRowHeight;
this.container.el.style.flexGrow = width;
@@ -254,6 +257,37 @@ export class ImageSelector extends FileSelector {
return imageEl;
}));
}
/**
* This converts the colors of an svg coming from the media library to
* the palette's ones, and make them dynamic.
*
* @param {HTMLElement} imgEl
* @param {Object} media
* @returns
*/
async onLibraryImageLoaded(imgEl, media) {
const mediaUrl = imgEl.src;
try {
const response = await fetch(mediaUrl);
if (response.headers.get('content-type') === 'image/svg+xml') {
const svg = await response.text();
const dynamicColors = {};
const combinedColorsRegex = new RegExp(Object.values(DEFAULT_PALETTE).join('|'), 'gi');
svg.replace(combinedColorsRegex, match => {
const colorId = Object.keys(DEFAULT_PALETTE).find(key => DEFAULT_PALETTE[key] === match.toUpperCase());
const colorKey = 'c' + colorId
dynamicColors[colorKey] = getCSSVariableValue('o-color-' + colorId);
});
if (Object.keys(dynamicColors).length) {
media.isDynamicSVG = true;
media.dynamicColors = dynamicColors;
}
}
} catch (_e) {
console.error('CORS is misconfigured on the API server, image will be treated as non-dynamic.');
}
}
}
ImageSelector.mediaSpecificClasses = ['img', 'img-fluid', 'o_we_custom_image'];
@@ -49,7 +49,8 @@
altDescription="media.tooltip"
minRowHeight="MIN_ROW_HEIGHT"
selected="this.selectedMediaIds.includes(media.id)"
onImageClick="() => this.onClickMedia(media)"/>
onImageClick="() => this.onClickMedia(media)"
onLoaded="(imgEl) => this.onLibraryImageLoaded(imgEl, media)"/>
</t>
</t>
<!-- 20 placeholders is just enough for a 5K screen, change this if ImageWidget.MIN_ROW_HEIGHT changes -->
@@ -38,8 +38,12 @@ $min-row-height: 128;
opacity: 1;
}
img {
width: 100%;
.o_we_media_dialog_img_wrapper {
@extend %o-preview-alpha-background;
img {
width: 100%;
}
}
}