[FIX] web_editor: fix selectStyle with conflicting extraClass

Since [1] when `extraClass` was introduced, styles are wrongly applied
if an `extraClass` is defined on a `selectStyle` option, but both the
class and the option modify the same CSS property.

Typically, the "Round Corners" option sets the `border-radius` property
and uses the `rounded` extra class. But that extra class specifies
values for the `border-radius` properties.
Without the class, `applyCSS` determines that the style of some corners
is already `0px` and does therefore not need to be added to the inline
style.
But once the class is added, this is not true anymore - and the `0px`
should have been specified.

This commit avoids this issue by applying the CSS again once the
`extraClass` is added.

It also reverts [2] partially to remove the `extraClass` handling from
within the `applyCSS` function.

Steps to reproduce:
- Drop a "Text - Image" snippet.
- Select the image.
- Set the "Round Corners" to "50 0 0 0".
- Press tab to leave the field.

=> The entered field values was transformed.

[1]: https://github.com/odoo/odoo/commit/bf5b4b69330747af7b09d48e59218b78a29a4b14
[2]: https://github.com/odoo/odoo/commit/d3c3dab8950abc25b29937605091d8ce32305fa4

task-3800288

Part-of: odoo/odoo#159385
This commit is contained in:
Benoit Socias
2024-03-28 10:19:39 +00:00
parent 8837302941
commit e321791f84
@@ -3620,10 +3620,14 @@ const SnippetOptionWidget = Widget.extend({
}
let hasUserValue = false;
for (let i = cssProps.length - 1; i > 0; i--) {
hasUserValue = applyCSS.call(this, cssProps[i], values.pop(), styles) || hasUserValue;
const applyAllCSS = (values) => {
for (let i = cssProps.length - 1; i > 0; i--) {
hasUserValue = applyCSS.call(this, cssProps[i], values.pop(), styles) || hasUserValue;
}
hasUserValue = applyCSS.call(this, cssProps[0], values.join(' '), styles) || hasUserValue;
}
hasUserValue = applyCSS.call(this, cssProps[0], values.join(' '), styles) || hasUserValue;
applyAllCSS([...values]);
function applyCSS(cssProp, cssValue, styles) {
if (typeof params.forceStyle !== 'undefined') {
@@ -3631,36 +3635,14 @@ const SnippetOptionWidget = Widget.extend({
return true;
}
// This condition requires extraClass to NOT be set.
if (!weUtils.areCssValuesEqual(styles.getPropertyValue(cssProp), cssValue, cssProp, this.$target[0])) {
// Property must be set => extraClass will be enabled.
if (params.extraClass) {
// The extraClass is temporarily removed during selectStyle
// because it is enabled only if the element style is set
// by the option. (E.g. add the bootstrap border class only
// if there is a border width.) Unfortunately the
// extraClass might specify default !important properties,
// therefore determining whether !important is needed
// requires the class to be applied.
this.$target[0].classList.add(params.extraClass);
// Set inline style only if different from value defined
// with extraClass.
if (!weUtils.areCssValuesEqual(styles.getPropertyValue(cssProp), cssValue, cssProp, this.$target[0])) {
this.$target[0].style.setProperty(cssProp, cssValue);
}
} else {
// Inline style required.
this.$target[0].style.setProperty(cssProp, cssValue);
}
this.$target[0].style.setProperty(cssProp, cssValue);
// If change had no effect then make it important.
// This condition requires extraClass to be set.
if (!params.preventImportant && !weUtils.areCssValuesEqual(
styles.getPropertyValue(cssProp), cssValue, cssProp, this.$target[0])) {
this.$target[0].style.setProperty(cssProp, cssValue, 'important');
}
if (params.extraClass) {
this.$target[0].classList.remove(params.extraClass);
}
return true;
}
return false;
@@ -3668,6 +3650,13 @@ const SnippetOptionWidget = Widget.extend({
if (params.extraClass) {
this.$target.toggleClass(params.extraClass, hasUserValue);
if (hasUserValue) {
// Might have changed because of the class.
for (const cssProp of cssProps) {
this.$target[0].style.removeProperty(cssProp);
}
applyAllCSS(values);
}
}
_restoreTransitions();