v || 'null'),
+ 'values': _.mapObject(values, v => v || defaultValue),
},
});
},
@@ -700,6 +709,7 @@ options.registry.BackgroundToggler.include({
*/
toggleBgVideo(previewMode, widgetValue, params) {
if (!widgetValue) {
+ this.$target.find('> .o_we_bg_filter').remove();
// TODO: use setWidgetValue instead of calling background directly when possible
const [bgVideoWidget] = this._requestUserValueWidgets('bg_video_opt');
const bgVideoOpt = bgVideoWidget.getParent();
@@ -1946,6 +1956,54 @@ options.registry.collapse = options.Class.extend({
},
});
+options.registry.WebsiteLevelColor = options.Class.extend({
+ specialCheckAndReloadMethodsNames: options.Class.prototype.specialCheckAndReloadMethodsNames
+ .concat(['customizeWebsiteLayer2Color']),
+
+ /**
+ * @see this.selectClass for parameters
+ */
+ async customizeWebsiteLayer2Color(previewMode, widgetValue, params) {
+ if (previewMode) {
+ return;
+ }
+ params.color = params.layerColor;
+ params.variable = params.layerGradient;
+ let color = undefined;
+ let gradient = undefined;
+ if (weUtils.isColorGradient(widgetValue)) {
+ color = '';
+ gradient = widgetValue;
+ } else {
+ color = widgetValue;
+ gradient = '';
+ }
+ await this.customizeWebsiteVariable(previewMode, gradient, params);
+ params.noBundleReload = false;
+ return this.customizeWebsiteColor(previewMode, color, params);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ async _computeWidgetState(methodName, params) {
+ if (methodName === 'customizeWebsiteLayer2Color') {
+ params.variable = params.layerGradient;
+ const gradient = await this._computeWidgetState('customizeWebsiteVariable', params);
+ if (gradient) {
+ return gradient.substring(1, gradient.length - 1); // Unquote
+ }
+ params.color = params.layerColor;
+ return this._computeWidgetState('customizeWebsiteColor', params);
+ }
+ return this._super(...arguments);
+ },
+});
+
options.registry.HeaderNavbar = options.Class.extend({
/**
* Particular case: we want the option to be associated on the header navbar
@@ -2633,10 +2691,23 @@ options.registry.CoverProperties = options.Class.extend({
name: 'bg_color_opt',
onSuccess: _widget => colorPickerWidget = _widget,
});
- const color = colorPickerWidget._value;
- const isCSSColor = ColorpickerWidget.isCSSColor(color);
- this.$target[0].dataset.bgColorClass = isCSSColor ? '' : weUtils.computeColorClasses([color])[0];
- this.$target[0].dataset.bgColorStyle = isCSSColor ? `background-color: ${color};` : '';
+ // TODO there is probably a better way and this should be refactored to
+ // use more standard colorpicker+imagepicker structure
+ const ccValue = colorPickerWidget._ccValue;
+ const colorOrGradient = colorPickerWidget._value;
+ const isGradient = weUtils.isColorGradient(colorOrGradient);
+ const isCSSColor = !isGradient && ColorpickerWidget.isCSSColor(colorOrGradient);
+ const colorNames = [];
+ if (ccValue) {
+ colorNames.push(ccValue);
+ }
+ if (!isGradient && !isCSSColor) {
+ colorNames.push(colorOrGradient);
+ }
+ this.$target[0].dataset.bgColorClass = weUtils.computeColorClasses(colorNames).join(' ');
+ this.$target[0].dataset.bgColorStyle =
+ isCSSColor ? `background-color: ${colorOrGradient};` :
+ isGradient ? `background-color: rgba(0, 0, 0, 0); background-image: ${colorOrGradient};` : '';
},
//--------------------------------------------------------------------------
diff --git a/addons/website/static/src/scss/primary_variables.scss b/addons/website/static/src/scss/primary_variables.scss
index 1652d53f2f1..2b85ef6056b 100644
--- a/addons/website/static/src/scss/primary_variables.scss
+++ b/addons/website/static/src/scss/primary_variables.scss
@@ -6,10 +6,14 @@
$o-base-color-palette: map-merge($o-base-color-palette, (
'body': $o-portal-default-body-bg,
'menu': 1, // o_cc1
+ 'menu-custom': null,
'menu-border-color': null, // Default to classes used on the template
- 'header-boxed': '200',
+ 'header-boxed': null,
+ 'header-boxed-custom': '200',
'footer': 5, // o_cc5
- 'copyright': 'black-15',
+ 'footer-custom': null,
+ 'copyright': null,
+ 'copyright-custom': null,
));
// By default, all user color palette values are null. Each null value is
@@ -42,6 +46,14 @@ $o-theme-figcaption-opacity: 0.6;
$o-color-palettes: map-merge($o-color-palettes,
(
+ 'base-1': map-merge(map-get($o-color-palettes, 'base-1'), (
+ 'copyright-custom': 'black-15',
+ )),
+ 'base-2': map-merge(map-get($o-color-palettes, 'base-2'), (
+ 'menu': 2,
+ 'footer': 2,
+ 'copyright': 5,
+ )),
'generic-1': (
'o-color-1': #984c46,
'o-color-2': #23323b,
@@ -51,6 +63,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 3,
'footer': 3,
+ 'copyright-custom': 'black-15',
),
'generic-2': (
'o-color-1': #B99932,
@@ -68,6 +81,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-3': #fdf8ef,
'o-color-4': #FFFFFF,
'o-color-5': #212c39,
+
+ 'copyright-custom': 'black-15',
),
'generic-4': (
'o-color-1': #6E7993,
@@ -77,6 +92,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #313347,
'menu': 5,
+ 'copyright-custom': 'black-15',
),
'generic-5': (
'o-color-1': #F7CF41,
@@ -87,6 +103,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 3,
'footer': 3,
+ 'copyright-custom': 'black-15',
),
'generic-6': (
'o-color-1': #45859A,
@@ -139,6 +156,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #000000,
'menu': 5,
+ 'copyright-custom': 'black-15',
),
'generic-10': (
'o-color-1': #b56355,
@@ -148,6 +166,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #343733,
'footer': 2,
+ 'copyright-custom': 'black-15',
),
'generic-11': (
'o-color-1': #01ACAB,
@@ -157,6 +176,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #000000,
'footer': 1,
+ 'copyright-custom': 'black-15',
),
'generic-12': (
'o-color-1': #926190,
@@ -172,6 +192,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc5-headings': 'o-color-4',
'o-cc5-link': 'o-color-4',
'o-cc5-text': rgba(#fff, .6),
+
+ 'copyright-custom': 'black-15',
),
'generic-13': (
'o-color-1': #478FA2,
@@ -240,6 +262,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 5,
'footer': 5,
+ 'copyright-custom': 'black-15',
),
'anelusia-1': (
'o-color-1': #000000,
@@ -284,6 +307,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc5-link': #218bdf,
'o-cc5-btn-primary': #218bdf,
+
+ 'copyright-custom': 'black-15',
),
'anelusia-4': (
'o-color-1': #dc143c,
@@ -291,6 +316,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-3': #faf7e1,
'o-color-4': #ffffff,
'o-color-5': #222222,
+
+ 'copyright-custom': 'black-15',
),
'anelusia-5': (
'o-color-1': #32c0c9,
@@ -300,6 +327,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #2e2e2e,
'footer': 1,
+ 'copyright-custom': 'black-15',
),
'anelusia-6': (
'o-color-1': #e27b92,
@@ -313,6 +341,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 2,
'footer': 2,
+ 'copyright-custom': 'black-15',
),
'artists-1': (
'o-color-1': #ab44ff,
@@ -324,6 +353,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc5-text': 'o-color-3',
'menu': 5,
+ 'copyright-custom': 'black-15',
),
'artists-2': (
'o-color-1': #1ad68f,
@@ -333,6 +363,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #000000,
'menu': 2,
+ 'copyright-custom': 'black-15',
),
'artists-3': (
'o-color-1': #007882,
@@ -355,6 +386,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 2,
'footer': 2,
+ 'copyright-custom': 'black-15',
),
'artists-5': (
'o-color-1': #f48847,
@@ -364,6 +396,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #000000,
'footer': 3,
+ 'copyright-custom': 'black-15',
),
'artists-6': (
'o-color-1': #95d2e5,
@@ -374,6 +407,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 2,
'footer': 2,
+ 'copyright-custom': 'black-15',
),
'avantgarde-1': (
'o-color-1': #ee4980,
@@ -403,6 +437,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 4,
'footer': 4,
+ 'copyright-custom': 'black-15',
),
'avantgarde-3': (
'o-color-1': #f08e80,
@@ -465,6 +500,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc2-headings': 'o-color-2',
'o-cc3-headings': 'o-color-3',
'o-cc5-headings': 'o-color-1',
+
+ 'copyright-custom': 'black-15',
),
'avantgarde-7': (
'o-color-1': #f48847,
@@ -475,6 +512,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc2-headings': 'o-color-1',
'o-cc5-headings': 'o-color-1',
+
+ 'copyright-custom': 'black-15',
),
'avantgarde-8': (
'o-color-1': #278f84,
@@ -485,6 +524,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc2-headings': 'o-color-1',
'o-cc5-headings': 'o-color-1',
+
+ 'copyright-custom': 'black-15',
),
'beauty-1': (
'o-color-1': #df699c,
@@ -553,6 +594,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #112625,
'o-cc2-link': 'o-color-5',
+
+ 'copyright-custom': 'black-15',
),
'bewise-1': (
'o-color-1': #162238,
@@ -861,7 +904,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'header': 1,
'footer': 3,
- 'copyright': 'black-15',
+ 'copyright-custom': 'black-15',
),
'enark-1': (
'o-color-1': #7b97af,
@@ -873,6 +916,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc1-text': 'o-color-2',
'o-cc1-btn-primary': 'o-color-2',
'o-cc5-link': 'o-color-4',
+
+ 'copyright-custom': 'black-15',
),
'enark-2': (
'o-color-1': #41cb7a,
@@ -936,7 +981,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'body': 'black-15',
'menu': 1,
'footer': 5,
- 'copyright': 'black-25',
+ 'copyright-custom': 'black-25',
),
'graphene-2': (
'o-color-1': #c8a47e,
@@ -950,6 +995,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc3-headings': 'o-color-4',
'o-cc4-headings': 'o-color-5',
'o-cc5-text': #b2b2b2,
+
+ 'copyright-custom': 'black-15',
),
'graphene-3': (
'o-color-1': #39588e,
@@ -962,6 +1009,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'menu': 2,
'footer': 2,
+ 'copyright-custom': 'black-15',
),
'graphene-4': (
'o-color-1': #f48747,
@@ -971,6 +1019,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-5': #282d30,
'menu': 5,
+ 'copyright-custom': 'black-15',
),
'kea-1': (
'o-color-1': #e991a3,
@@ -1137,6 +1186,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-3': #f5f5f5,
'o-color-4': #ffffff,
'o-color-5': #111111,
+
+ 'copyright-custom': 'black-15',
),
'monglia-2': (
'o-color-1': #8f8747,
@@ -1144,6 +1195,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-3': #f0ecdb,
'o-color-4': #ffffff,
'o-color-5': #21263a,
+
+ 'copyright-custom': 'black-15',
),
'monglia-3': (
'o-color-1': #c0ce75,
@@ -1151,6 +1204,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-3': #dedede,
'o-color-4': #ffffff,
'o-color-5': #3e3e3e,
+
+ 'copyright-custom': 'black-15',
),
'monglia-4': (
'o-color-1': #1ad68f,
@@ -1158,6 +1213,8 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-color-3': #cfcfcf,
'o-color-4': #ffffff,
'o-color-5': #000000,
+
+ 'copyright-custom': 'black-15',
),
'monglia-5': (
'o-color-1': #c5ca60,
@@ -1506,6 +1563,7 @@ $o-color-palettes: map-merge($o-color-palettes,
'o-cc5-link': #70c7cf,
'menu': 5,
+ 'copyright-custom': 'black-15',
),
'treehouse-1': (
'o-color-1': #68b581,
@@ -1868,6 +1926,12 @@ $o-base-website-values-palette: (
'navbar-font': null,
'buttons-font': null,
+ // Gradients
+ 'menu-gradient': null,
+ 'header-boxed-gradient': null,
+ 'footer-gradient': null,
+ 'copyright-gradient': null,
+
'header-template': 'default', // 'default' / 'hamburger' / 'vertical' / 'sidebar'
'header-font-size': null, // Default to BS (normal font-size)
'header-links-style': 'default', // 'default' / 'fill' / 'outline' / 'pills' / 'block' / 'border-bottom'
@@ -1985,3 +2049,11 @@ $o-theme-font-configs: (
@include o-position-absolute($top: 0, $left: 0);
padding: 0.25rem 1rem;
};
+
+@mixin o-add-gradient($key) {
+ $-gradient: o-website-value($key);
+ @if $-gradient {
+ background-color: rgba(0, 0, 0, 0);
+ background-image: $-gradient;
+ }
+};
diff --git a/addons/website/static/src/scss/secondary_variables.scss b/addons/website/static/src/scss/secondary_variables.scss
index a8ca40bc8f3..f3e48ff02c2 100644
--- a/addons/website/static/src/scss/secondary_variables.scss
+++ b/addons/website/static/src/scss/secondary_variables.scss
@@ -67,7 +67,7 @@ $o-website-values-palettes: append($o-website-values-palettes, $-actual-user-web
// Enable last website values palette, which is now the user customized one
$o-website-values-palette-number: length($o-website-values-palettes);
-$o-website-values: $-actual-user-website-values-palette !default;
+$o-website-values: o-map-force-nulls($-actual-user-website-values-palette) !default;
@function o-website-value($key) {
@return map-get($o-website-values, $key);
}
@@ -134,6 +134,27 @@ $o-has-customized-colors:
// palette.
$-palette-default: map-get($o-color-palettes, $o-color-palette-name) or ();
$-actual-user-color-palette: map-merge($-palette-default, o-map-omit($o-user-color-palette));
+// Compatibility with old values in old names
+@each $name, $custom-name in (
+ // Each of those values were either a number for a color combination, a
+ // string for a color name or a color. Now they should only be a number for
+ // a color combination and the other value types for the color name/value
+ // are handled by another variable. That variable can also contain a string
+ // for a color gradient.
+ 'menu': 'menu-custom',
+ 'header-boxed': 'header-boxed-custom',
+ 'footer': 'footer-custom',
+ 'copyright': 'copyright-custom'
+) {
+ $-base-value: map-get($-actual-user-color-palette, $name);
+ @if $-base-value and $-base-value != 'NULL' and type-of($-base-value) != 'number' {
+ $-base-custom-value: map-get($-actual-user-color-palette, $custom-name);
+ $-actual-user-color-palette: map-merge($-actual-user-color-palette, (
+ $name: 1,
+ $custom-name: $-base-custom-value or $-base-value,
+ ));
+ }
+}
$o-color-palettes: map-merge($o-color-palettes, ('user-palette': $-actual-user-color-palette));
// Gray palette
@@ -174,6 +195,7 @@ $-actual-user-theme-color-palette: map-remove($-actual-user-theme-color-palette,
'secondary'
);
$o-theme-color-palettes: map-merge($o-theme-color-palettes, ('user-palette': $-actual-user-theme-color-palette));
+
// ---
// Enable last color and theme color palettes, which are now the user customized
diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss
index c2389d2e867..a9023af7581 100644
--- a/addons/website/static/src/scss/website.scss
+++ b/addons/website/static/src/scss/website.scss
@@ -136,7 +136,8 @@ $-seen-urls: ();
}
// Vertical alignment when top-menu has visually "no background"
- @if o-color('menu') == o-color('body') {
+ $-menu-color: o-color('menu-custom') or o-color('menu');
+ @if (not $-menu-color or $-menu-color == o-color('body')) {
> header {
.navbar, .container {
padding-left: 0;
@@ -226,9 +227,12 @@ $-seen-urls: ();
// Note: this only works because navbar-light is defined before navbar-dark,
// we may want to use a safest way when possible.
@include o-apply-colors('menu');
- @if (color-yiq(o-color('menu')) != $yiq-text-dark) {
+ @include o-apply-colors('menu-custom');
+ $-menu-color: o-color('menu-custom') or o-color('menu');
+ @if ($-menu-color and color-yiq($-menu-color) != $yiq-text-dark) {
@extend .navbar-dark;
}
+ @include o-add-gradient('menu-gradient');
}
$-header-nav-link-height: $nav-link-height;
@@ -258,9 +262,14 @@ $-header-nav-link-height: $nav-link-height;
.o_footer {
@include o-apply-colors('footer');
+ @include o-apply-colors('footer-custom');
+ @include o-add-gradient('footer-gradient');
.o_footer_copyright {
- @include o-apply-colors('copyright', $background: o-color('footer'));
+ $-footer-color: o-color('footer-custom') or o-color('footer');
+ @include o-apply-colors('copyright', $background: $-footer-color);
+ @include o-apply-colors('copyright-custom', $background: $-footer-color);
+ @include o-add-gradient('copyright-gradient');
}
}
@@ -286,7 +295,7 @@ h6 {
}
// Texts
-font[style*='background'],
+font[style*='background']:not(.text-gradient),
font[class*='bg-'] {
padding: 2px 6px 4px;
}
@@ -946,7 +955,8 @@ header {
}
min-width: 250px;
margin: 0 !important;
- background-color: o-color('menu');
+ background-color: o-color('menu-custom') or o-color('menu');
+ @include o-add-gradient('menu-gradient');
transition: transform $-transition-duration cubic-bezier(.694, .0482, .335, 1);
@if $-hamburger-center {
@@ -1102,6 +1112,8 @@ header {
} @else if o-website-value('header-template') == 'boxed' {
#wrapwrap:not(.o_header_overlay) .o_header_boxed_background {
@include o-apply-colors('header-boxed');
+ @include o-apply-colors('header-boxed-custom');
+ @include o-add-gradient('header-boxed-gradient');
}
} @else if o-website-value('header-template') == 'centered_logo' {
header .o_header_centered_logo {
@@ -1280,8 +1292,8 @@ header {
// Footer scrolltop button
@if o-website-value('footer-scrolltop') {
#o_footer_scrolltop {
- $-footer-color: o-color('footer');
- $-copyright-color: o-color('copyright');
+ $-footer-color: o-color('footer-custom') or o-color('footer');
+ $-copyright-color: o-color('copyright-custom') or o-color('copyright');
$-copyright-color: mix(rgba($-copyright-color, 1.0), $-footer-color, percentage(alpha($-copyright-color)));
box-sizing: content-box;
@@ -1290,6 +1302,7 @@ header {
border: 0;
padding: 0;
@include o-apply-colors('footer', $with-extras: false, $background: $-footer-color);
+ @include o-apply-colors('footer-custom', $with-extras: false, $background: $-footer-color);
text-decoration: none;
@if $-footer-color == $-copyright-color {
diff --git a/addons/website/static/tests/tours/snippet_background_edition.js b/addons/website/static/tests/tours/snippet_background_edition.js
new file mode 100644
index 00000000000..123ae91be58
--- /dev/null
+++ b/addons/website/static/tests/tours/snippet_background_edition.js
@@ -0,0 +1,262 @@
+/** @odoo-module */
+
+import tour from 'web_tour.tour';
+import weUtils from 'web_editor.utils';
+import wTourUtils from 'website.tour_utils';
+
+const snippets = [
+ {
+ id: 's_text_image',
+ name: 'Text - Image',
+ },
+];
+const gradients = [
+ 'linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)',
+ 'linear-gradient(135deg, rgb(255, 222, 202) 0%, rgb(202, 115, 69) 100%)',
+];
+
+function checkAndUpdateBackgroundColor({
+ checkCC, checkNoCC,
+ checkBg, checkNoBg,
+ checkGradient, checkNoGradient,
+ changeType, change,
+ finalSelector, finalRun
+}) {
+ const steps = [
+ wTourUtils.changeBackgroundColor(),
+ ];
+
+ function typeToName(xType) {
+ return xType === 'cc' ? 'color combinations' : xType === 'bg' ? 'background colors' : 'gradients';
+ }
+
+ function switchTo(type, _name) {
+ const target = type === 'cc' ? 'color-combinations' : type === 'bg' ? 'custom-colors' : 'gradients';
+ const name = _name || typeToName(type);
+ steps.push({
+ trigger: `.o_we_colorpicker_switch_pane_btn[data-target="${target}"]`,
+ content: `Switch to ${name}`,
+ });
+ }
+
+ function check(checkX, checkNoX, xType, noSwitch = false) {
+ if (!checkX && !checkNoX) {
+ return;
+ }
+
+ const name = typeToName(xType);
+ const selectorCheckX = checkX && `.o_we_color_btn[data-color="${checkX}"].selected`;
+ const selectorCheckNoX = checkNoX && `.o_we_color_btn[data-color="${checkNoX}"]:not(.selected)`;
+ const step = {
+ trigger: selectorCheckX || selectorCheckNoX,
+ content: `The correct ${name} is marked as selected`,
+ position: 'bottom',
+ run: () => null,
+ };
+ if (!selectorCheckX && selectorCheckNoX) {
+ step.extra_trigger = selectorCheckNoX;
+ }
+
+ if (!noSwitch) {
+ switchTo(xType, name);
+ }
+ steps.push(step);
+ }
+
+ check(checkCC, checkNoCC, 'cc', true);
+ check(checkBg, checkNoBg, 'bg');
+ check(checkGradient, checkNoGradient, 'gradient');
+
+ if (changeType) {
+ switchTo(changeType);
+ steps.push(wTourUtils.changeOption('ColoredLevelBackground', `.o_we_color_btn[data-color="${change}"]`));
+ steps.push({
+ trigger: finalSelector,
+ content: "The selected colors have been applied (CC AND (BG or GRADIENT))",
+ position: 'bottom',
+ run: finalRun,
+ });
+ }
+
+ return steps;
+}
+
+tour.register('snippet_background_edition', {
+ test: true,
+ url: '/?enable_editor=1',
+},
+[
+wTourUtils.dragNDrop(snippets[0]),
+wTourUtils.clickOnSnippet(snippets[0]),
+
+// Add a color combination
+...checkAndUpdateBackgroundColor({
+ changeType: 'cc',
+ change: 3,
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc3:not([class*=bg-]):not([style*="background"])`,
+}),
+
+// Change the color combination + Check the previous one was marked as selected
+...checkAndUpdateBackgroundColor({
+ checkCC: 3,
+ changeType: 'cc',
+ change: 2,
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc2:not(.o_cc3):not([class*=bg-])`,
+}),
+
+// Check the color combination was marked as selected + Edit the bg color
+...checkAndUpdateBackgroundColor({
+ checkCC: 2,
+ checkNoCC: 3,
+ changeType: 'bg',
+ change: 'black-50',
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc2.bg-black-50`,
+}),
+
+// Check the current color palette selection + Change the bg color
+...checkAndUpdateBackgroundColor({
+ checkCC: 2,
+ checkBg: 'black-50',
+ changeType: 'bg',
+ change: '800',
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc2.bg-800:not(.bg-black-50)`,
+}),
+
+// Check the current color palette selection + Change the color combination
+// again. It should keep the bg color class.
+...checkAndUpdateBackgroundColor({
+ checkCC: 2,
+ checkBg: '800',
+ checkNoBg: 'black-50',
+ changeType: 'cc',
+ change: 4,
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc4:not(.o_cc2).bg-800`,
+}),
+
+// Check the current color palette status + Replace the bg color by a gradient
+...checkAndUpdateBackgroundColor({
+ checkCC: 4,
+ checkNoCC: 2,
+ checkBg: '800',
+ changeType: 'gradient',
+ change: gradients[0],
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc4:not(.bg-800)[style*="background-image: ${gradients[0]}"]`,
+}),
+
+// Check the current color palette status + Replace the gradient
+...checkAndUpdateBackgroundColor({
+ checkCC: 4,
+ checkNoBg: '800',
+ checkGradient: gradients[0],
+ changeType: 'gradient',
+ change: gradients[1],
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc4[style*="background-image: ${gradients[1]}"]:not([style*="background-image: ${gradients[0]}"])`,
+}),
+
+// Check the current color palette selection + Change the color combination
+// again. It should keep the gradient.
+...checkAndUpdateBackgroundColor({
+ checkCC: 4,
+ checkGradient: gradients[1],
+ checkNoGradient: gradients[0],
+ changeType: 'cc',
+ change: 1,
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc1:not(.o_cc4)[style*="background-image: ${gradients[1]}"]`,
+}),
+
+// Final check of the color status in the color palette
+...checkAndUpdateBackgroundColor({
+ checkCC: 1,
+ checkNoCC: 4,
+ checkGradient: gradients[1],
+}),
+
+// Now, add an image on top of that color combination + gradient
+wTourUtils.changeOption('ColoredLevelBackground', '[data-name="bg_image_toggle_opt"]'),
+{
+ trigger: '.o_existing_attachment_cell img',
+ content: "Select an image in the media dialog",
+},
+{
+ trigger: `.${snippets[0].id}.o_cc.o_cc1`,
+ run: function () {
+ const parts = weUtils.backgroundImageCssToParts(this.$anchor.css('background-image'));
+ if (!parts.url || !parts.url.startsWith('url(')) {
+ console.error('An image should have been added as background.');
+ }
+ if (parts.gradient !== gradients[1]) {
+ console.error('The gradient should have been kept when adding the background image');
+ }
+ },
+},
+
+// Replace the gradient while there is a background-image
+...checkAndUpdateBackgroundColor({
+ checkCC: 1,
+ checkGradient: gradients[1],
+ changeType: 'gradient',
+ change: gradients[0],
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc1:not([style*="${gradients[1]}"])`,
+ finalRun: function () {
+ const parts = weUtils.backgroundImageCssToParts(this.$anchor.css('background-image'));
+ if (!parts.url || !parts.url.startsWith('url(')) {
+ console.error('The image should have been kept when changing the gradient');
+ }
+ if (parts.gradient !== gradients[0]) {
+ console.error('The gradient should have been changed');
+ }
+ },
+}),
+
+// Replace the gradient by a bg color
+...checkAndUpdateBackgroundColor({
+ checkCC: 1,
+ checkGradient: gradients[0],
+ checkNoGradient: gradients[1],
+ changeType: 'bg',
+ change: 'black-75',
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc1.bg-black-75[style^="background-image: url("]:not([style*="${gradients[0]}"])`
+}),
+
+// Re-add a gradient
+...checkAndUpdateBackgroundColor({
+ checkCC: 1,
+ checkBg: 'black-75',
+ checkNoGradient: gradients[0],
+ changeType: 'gradient',
+ change: gradients[1],
+ finalSelector: `.${snippets[0].id}.o_cc.o_cc1:not(.bg-black-75)`,
+ finalRun: function () {
+ const parts = weUtils.backgroundImageCssToParts(this.$anchor.css('background-image'));
+ if (!parts.url || !parts.url.startsWith('url(')) {
+ console.error('The image should have been kept when re-adding the gradient');
+ }
+ if (parts.gradient !== gradients[1]) {
+ console.error('The gradient should have been re-added');
+ }
+ },
+}),
+
+// Final check of color selection and removing the image
+...checkAndUpdateBackgroundColor({
+ checkCC: 1,
+ checkNoBg: 'black-75',
+ checkGradient: gradients[1],
+}),
+wTourUtils.changeOption('ColoredLevelBackground', '[data-name="bg_image_toggle_opt"]'),
+{
+ trigger: `.${snippets[0].id}.o_cc.o_cc1[style*="background-image: ${gradients[1]}"]`,
+ run: () => null,
+},
+
+// Now removing all colors via the 'None' button (note: colorpicker still opened)
+{
+ trigger: '.o_colorpicker_reset',
+ content: "Click on the None button of the color palette",
+},
+{
+ trigger: `.${snippets[0].id}:not(.o_cc):not(.o_cc1):not([style*="background-image"])`,
+ content: "All color classes and properties should have been removed",
+ run: () => null,
+}
+]);
diff --git a/addons/website/static/tests/tours/snippet_empty_parent_autoremove.js b/addons/website/static/tests/tours/snippet_empty_parent_autoremove.js
index 6ddc1fa48b4..2b3671b705e 100644
--- a/addons/website/static/tests/tours/snippet_empty_parent_autoremove.js
+++ b/addons/website/static/tests/tours/snippet_empty_parent_autoremove.js
@@ -55,12 +55,6 @@ tour.register('snippet_empty_parent_autoremove', {
trigger: '#wrap .s_banner .o_we_shape',
run: () => null,
},
- wTourUtils.changeOption('ColoredLevelBackground', 'Filter'),
- {
- content: "Check that background-filter is present",
- trigger: '#wrap .s_banner .o_we_bg_filter',
- run: () => null,
- },
{
content: "Click on first column",
trigger: '#wrap .s_banner .row > :first-child',
diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py
index 4aed9d6758e..c42647ba849 100644
--- a/addons/website/tests/test_ui.py
+++ b/addons/website/tests/test_ui.py
@@ -206,3 +206,13 @@ class TestUi(odoo.tests.HttpCase):
def test_10_website_conditional_visibility(self):
self.start_tour('/', 'conditional_visibility_1', login='admin')
self.start_tour('/', 'conditional_visibility_2', login='admin')
+
+ def test_11_website_snippet_background_edition(self):
+ self.env['ir.attachment'].create({
+ 'public': True,
+ 'type': 'url',
+ 'url': '/web/image/123/test.png',
+ 'name': 'test.png',
+ 'mimetype': 'image/png',
+ })
+ self.start_tour('/', 'snippet_background_edition', login='admin')
diff --git a/addons/website/views/snippets/s_blockquote.xml b/addons/website/views/snippets/s_blockquote.xml
index 75eb66d2cff..2e5d74b38d3 100644
--- a/addons/website/views/snippets/s_blockquote.xml
+++ b/addons/website/views/snippets/s_blockquote.xml
@@ -31,6 +31,7 @@
+
diff --git a/addons/website/views/snippets/s_media_list.xml b/addons/website/views/snippets/s_media_list.xml
index b786ab95f51..76e3499783d 100644
--- a/addons/website/views/snippets/s_media_list.xml
+++ b/addons/website/views/snippets/s_media_list.xml
@@ -62,6 +62,7 @@
+
diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml
index a9cf02988a9..bc99ba1f80d 100644
--- a/addons/website/views/snippets/snippets.xml
+++ b/addons/website/views/snippets/snippets.xml
@@ -190,8 +190,8 @@
-
-
+
+
@@ -384,6 +384,7 @@
+
+
@@ -489,6 +491,7 @@
+
@@ -552,7 +555,8 @@
data-selector="[data-oe-expression='res_company.partner_id']"
data-no-check="true"/>
-
@@ -628,10 +632,18 @@
+ data-customize-website-layer2-color="" data-layer-color="menu-custom" data-layer-gradient="menu-gradient"
+ data-no-bundle-reload="true"
+ data-null-value="'NULL'"
+ data-with-combinations="customizeWebsiteColor"
+ data-with-gradients="true"/>
+ data-customize-website-layer2-color="" data-layer-color="header-boxed-custom" data-layer-gradient="header-boxed-gradient"
+ data-no-bundle-reload="true"
+ data-null-value="'NULL'"
+ data-with-combinations="customizeWebsiteColor"
+ data-with-gradients="true"/>
@@ -834,7 +846,8 @@
-
@@ -878,7 +891,11 @@
+ data-customize-website-layer2-color="" data-layer-color="footer-custom" data-layer-gradient="footer-gradient"
+ data-no-bundle-reload="true"
+ data-null-value="'NULL'"
+ data-with-combinations="customizeWebsiteColor"
+ data-with-gradients="true"/>
-
+ data-customize-website-layer2-color="" data-layer-color="copyright-custom" data-layer-gradient="copyright-gradient"
+ data-no-bundle-reload="true"
+ data-null-value="'NULL'"
+ data-with-combinations="customizeWebsiteColor"
+ data-with-gradients="true"/>
None
@@ -985,6 +1007,7 @@
+