[IMP] web_editor: render inline svg icons, apply css style

Render inline SVG inside buttons in order to allow CSS styling.

Define SVG icons design for normal/hover status applying the same colors
as default text buttons.

In order to support multi-colors SVGs, this commits will affect inner
shapes in different ways:
- '.o_graphic' shapes: will gets the UI btns colors (default/hover)
- '.o_subdle' shapes: will gets a slightly reduced default text color

Shapes without '.o_graphic/.o_subdle' classes will be rendered normally,
as defined in the svg code.

Part of https://github.com/odoo/odoo/pull/54913
task-2157252

Co-authored-by: qsm-odoo <qsm@odoo.com>
This commit is contained in:
stefanorigano (SRI)
2020-07-30 11:12:03 +00:00
committed by qsm-odoo
co-authored by qsm-odoo
parent 26e146644b
commit a1c9044ff7
3 changed files with 53 additions and 7 deletions
@@ -77,7 +77,14 @@ function _buildTitleElement(title) {
* @param {string} src
* @returns {HTMLElement}
*/
function _buildImgElement(src) {
async function _buildImgElement(src) {
if (src.split('.').pop() === 'svg') {
const response = await window.fetch(src);
const text = await response.text();
const parser = new window.DOMParser();
const xmlDoc = parser.parseFromString(text, 'text/xml');
return xmlDoc.getElementsByTagName('svg')[0];
}
const imgEl = document.createElement('img');
imgEl.src = src;
return imgEl;
@@ -153,6 +160,15 @@ const UserValueWidget = Widget.extend({
this._value = '';
this.$target = $target;
},
/**
* @override
*/
async willStart() {
await this._super(...arguments);
if (this.options.dataAttributes.img) {
this.imgEl = await _buildImgElement(this.options.dataAttributes.img);
}
},
/**
* @override
*/
@@ -162,9 +178,8 @@ const UserValueWidget = Widget.extend({
_addTitleAndAllowedAttributes(el, this.title, this.options);
this.containerEl = document.createElement('div');
if (el.dataset.img) {
const imgEl = _buildImgElement(el.dataset.img);
this.containerEl.appendChild(imgEl);
if (this.imgEl) {
this.containerEl.appendChild(this.imgEl);
}
el.appendChild(this.containerEl);
@@ -192,7 +207,13 @@ const UserValueWidget = Widget.extend({
* @override
*/
destroy() {
this.$el.off('.img_animate');
// Check if $el exists in case the widget is destroyed before it has
// been fully initialized.
// TODO there is probably better to do. This case was found only in
// tours, where the editor is left before the widget icon is loaded.
if (this.$el) {
this.$el.off('.img_animate');
}
this._super(...arguments);
},
@@ -2280,6 +2301,13 @@ const SnippetOptionWidget = Widget.extend({
await this._renderXMLWidgets(uiFragment);
await this._renderCustomWidgets(uiFragment);
if (this.isDestroyed()) {
// TODO there is probably better to do. This case was found only in
// tours, where the editor is left before the widget are fully
// loaded (loadMethodsData doesn't work if the widget is destroyed).
return uiFragment;
}
const validMethodNames = [];
for (const key in this) {
validMethodNames.push(key);
@@ -54,7 +54,7 @@ $o-we-item-border-color: $o-we-bg-darkest !default;
$o-we-item-border-radius: 1px !default;
$o-we-item-clickable-bg: linear-gradient($o-we-bg-light, $o-we-bg-darker) !default;
$o-we-item-pressed-bg: linear-gradient($o-we-bg-darkest, $o-we-bg-darker) !default;
$o-we-item-pressed-color: $o-we-fg-light !default;
$o-we-item-pressed-color: $o-we-fg-lighter !default;
$o-we-dropdown-spacing: 5px !default;
$o-we-dropdown-bg: $o-we-bg-darker !default;
@@ -254,6 +254,20 @@ body.editor_enable.editor_has_snippets {
width: $o-we-sidebar-width / 2; // TODO maybe there is a better way to implement this
}
@mixin we-svg-icon(
$graphic: $o-we-sidebar-content-field-color,
$subdle: $o-we-sidebar-content-field-color,
$subdle-opacity: 0.5) {
svg {
.o_graphic {
fill: $graphic;
}
.o_subdle {
fill: rgba($subdle, $subdle-opacity);
}
}
}
we-button, we-toggler {
cursor: pointer;
@include o-text-overflow(block);
@@ -264,10 +278,14 @@ body.editor_enable.editor_has_snippets {
color: $o-we-sidebar-content-field-color;
line-height: $o-we-sidebar-content-field-height - 2 * $o-we-sidebar-content-field-border-width;
text-align: left;
@include we-svg-icon();
&.active, &:hover {
color: $o-we-sidebar-content-field-pressed-color;
@include we-svg-icon($o-we-sidebar-content-field-pressed-color, $subdle-opacity: .75);
}
&.active {
background: $o-we-sidebar-content-field-pressed-bg;
color: $o-we-sidebar-content-field-pressed-color;
}
&.fa {