From 55c90cc9fa4ae3308f35129c8061c202c81f8bfc Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Thu, 28 May 2020 10:04:47 +0000 Subject: [PATCH] [IMP] website, *: allow presets user edition *: web, web_editor Now, the user can edit each individual component of each color preset thanks to the third tab of the left panel. The edition of the first preset is the same as the others for the users but it is actually also used for "no-preset" areas, meaning that they impact the whole website by default (*without impacting the other presets*). The website thus appears as areas using presets, preset 1 being the default (in the future all areas will be customizable with a different preset). The only difference between "using preset 1 explicitely" and "not using a preset" will be that background color is transparent in no-preset, leaving the body background appear. If the body background has no image, then there is no difference at all as the background color of the body is set to be the background color of the preset 1. In boxed mode, that color is used for the "box" and the website body uses a different customizable color. Note: before this commit, the "text" color edition was used to set the main text color and one of the constrasting color for the color-yiq function (the darkest if a dark color or the lightest if a light color). That last part has been removed and automatic colors will now always use $gray-900 and $white as contrasting colors, unless changed by the theme explicitely. This needed to be removed as now the "text color" edition has been moved in the "preset 1" config and should thus only impact the "no-preset / preset 1" areas instead of all the presets. Part of https://github.com/odoo/odoo/pull/45856 task-2197038 --- .../web/static/src/scss/bootstrap_review.scss | 13 +++- .../static/src/scss/bs_mixins_overrides.scss | 6 +- .../static/src/js/editor/snippets.options.js | 6 +- .../static/src/scss/bootstrap_overridden.scss | 11 +++ .../scss/bootstrap_overridden_backend.scss | 11 +++ .../static/src/scss/web_editor.common.scss | 54 +++++++++++++ .../static/src/scss/web_editor.variables.scss | 5 ++ .../static/src/scss/wysiwyg_snippets.scss | 32 ++++++-- addons/web_editor/static/src/xml/snippets.xml | 15 ++-- .../static/src/js/editor/snippets.options.js | 78 +++++++++++++++++++ .../static/src/scss/bootstrap_overridden.scss | 38 +++++---- .../static/src/scss/primary_variables.scss | 7 -- addons/website/static/src/scss/website.scss | 26 ++----- .../static/src/scss/website.wysiwyg.scss | 5 ++ .../website/static/src/xml/website.editor.xml | 24 ++++++ addons/website/views/snippets/snippets.xml | 34 +++----- 16 files changed, 284 insertions(+), 81 deletions(-) diff --git a/addons/web/static/src/scss/bootstrap_review.scss b/addons/web/static/src/scss/bootstrap_review.scss index f8c03533669..8fab23b0b1a 100644 --- a/addons/web/static/src/scss/bootstrap_review.scss +++ b/addons/web/static/src/scss/bootstrap_review.scss @@ -108,15 +108,22 @@ // We do it ourself here with a tweak: we introduce btn-fill-* (working as the // normal btn-* classes (in opposition to btn-outline-* classes). We then map // the btn-* classes to either btn-fill-* or btn-outline-* classes depending on -// the configuration. +// the configuration. We also allow to define a border-color different than the +// background color. +$o-btn-bg-colors: () !default; +$o-btn-border-colors: () !default; @each $color, $value in $theme-colors { + $-bg-color: map-get($o-btn-bg-colors, $color) or $value; + $-border-color: map-get($o-btn-border-colors, $color) or $-bg-color; .btn-fill-#{$color} { - @include button-variant($value, $value); + @include button-variant($-bg-color, $-border-color); } } @each $color, $value in $theme-colors { + $-bg-color: map-get($o-btn-bg-colors, $color) or $value; + $-border-color: map-get($o-btn-border-colors, $color) or $-bg-color; .btn-outline-#{$color} { - @include button-outline-variant($value); + @include button-outline-variant($-border-color); } } $o-btn-outline-defaults: () !default; diff --git a/addons/web/static/src/scss/bs_mixins_overrides.scss b/addons/web/static/src/scss/bs_mixins_overrides.scss index c705e5741ba..9ae6db9ecc1 100644 --- a/addons/web/static/src/scss/bs_mixins_overrides.scss +++ b/addons/web/static/src/scss/bs_mixins_overrides.scss @@ -14,6 +14,10 @@ $enable-deprecation-messages: false !default; @return o-get-most-contrast($color, $light, $dark, $background, $threshold, $cross-mix); } +@function mute-color($color) { + @return scale-color($color, $alpha: -30%); +} + // This placeholder regroups the rules that will apply on all elements with a // bg-* class (see o-bg-color, bg-variant). The optimized-css way would be to // have a common class for them all. @@ -37,7 +41,7 @@ $o-color-extras-nesting-selector: '&' !default; .text-muted { // Always important since the basic BS rule is important - color: scale-color($-yiq-color, $alpha: -30%) !important; + color: mute-color($-yiq-color) !important; } } } diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 212ab507755..113337f6dab 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -739,7 +739,11 @@ const SelectUserValueWidget = UserValueWidget.extend({ * * @private */ - _onClick: function () { + _onClick: function (ev) { + if (ev.target.closest('[role="button"]')) { + return; + } + if (!this.menuTogglerEl.classList.contains('active')) { this.trigger_up('user_value_widget_opening'); this.menuTogglerEl.classList.add('active'); diff --git a/addons/web_editor/static/src/scss/bootstrap_overridden.scss b/addons/web_editor/static/src/scss/bootstrap_overridden.scss index c1144ec23a7..f48d9bdaecb 100644 --- a/addons/web_editor/static/src/scss/bootstrap_overridden.scss +++ b/addons/web_editor/static/src/scss/bootstrap_overridden.scss @@ -7,6 +7,17 @@ $colors: () !default; $colors: map-merge(('#{$name}': o-color($color)), $colors); } +$o-btn-bg-colors: () !default; +$o-btn-bg-colors: map-merge(( + 'primary': o-color('o-cc1-btn-primary'), + 'secondary': o-color('o-cc1-btn-secondary'), +), $o-btn-bg-colors); +$o-btn-border-colors: () !default; +$o-btn-border-colors: map-merge(( + 'primary': o-color('o-cc1-btn-primary-border'), + 'secondary': o-color('o-cc1-btn-secondary-border'), +), $o-btn-border-colors); + // Automatically extend bootstrap to create theme background/text/button classes $theme-colors: () !default; @each $name, $color in $o-theme-color-palette { diff --git a/addons/web_editor/static/src/scss/bootstrap_overridden_backend.scss b/addons/web_editor/static/src/scss/bootstrap_overridden_backend.scss index 8e1042c4cbd..ef2d6cf03c5 100644 --- a/addons/web_editor/static/src/scss/bootstrap_overridden_backend.scss +++ b/addons/web_editor/static/src/scss/bootstrap_overridden_backend.scss @@ -1,3 +1,14 @@ $o-theme-color-palette: map-remove($o-theme-color-palette, 'primary', 'secondary', 'success', 'info', 'warning', 'danger', 'light', 'dark'); $o-gray-color-palette: map-remove($o-gray-color-palette, '100', '200', '300', '400', '500', '600', '700', '800', '900'); + +$o-btn-bg-colors: () !default; +$o-btn-bg-colors: map-merge(( + 'primary': null, + 'secondary': null, +), $o-btn-bg-colors); +$o-btn-border-colors: () !default; +$o-btn-border-colors: map-merge(( + 'primary': null, + 'secondary': null, +), $o-btn-border-colors); diff --git a/addons/web_editor/static/src/scss/web_editor.common.scss b/addons/web_editor/static/src/scss/web_editor.common.scss index 0eb6ee9fd1b..08a202263fc 100644 --- a/addons/web_editor/static/src/scss/web_editor.common.scss +++ b/addons/web_editor/static/src/scss/web_editor.common.scss @@ -6,6 +6,60 @@ @each $color, $value in $grays { --#{$color}: #{$value}; } + + // Most of the keys of the color combination color should be null. We have + // to indicate their fallback values. + @for $index from 1 through length($o-color-combinations) { + $-text: color('o-cc#{$index}-text') or color-yiq(o-color('o-cc#{$index}-bg')); + $-headings: color('o-cc#{$index}-headings') or $-text; + $-h2: color('o-cc#{$index}-h2') or $-headings; + $-h3: color('o-cc#{$index}-h3') or $-h2; + $-h4: color('o-cc#{$index}-h4') or $-h3; + $-h5: color('o-cc#{$index}-h5') or $-h4; + $-h6: color('o-cc#{$index}-h6') or $-h5; + + @if not color('o-cc#{$index}-text') { + --o-cc#{$index}-text: #{$-text}; + } + @if not color('o-cc#{$index}-headings') { + --o-cc#{$index}-headings: #{$-headings}; + } + @if not color('o-cc#{$index}-h2') { + --o-cc#{$index}-h2: #{$-h2}; + } + @if not color('o-cc#{$index}-h3') { + --o-cc#{$index}-h3: #{$-h3}; + } + @if not color('o-cc#{$index}-h4') { + --o-cc#{$index}-h4: #{$-h4}; + } + @if not color('o-cc#{$index}-h5') { + --o-cc#{$index}-h5: #{$-h5}; + } + @if not color('o-cc#{$index}-h6') { + --o-cc#{$index}-h6: #{$-h6}; + } + + @if not color('o-cc#{$index}-link') { + --o-cc#{$index}-link: #{theme-color('primary')}; + } + + $-btn-primary: color('o-cc#{$index}-btn-primary'); + @if not $-btn-primary { + --o-cc#{$index}-btn-primary: #{theme-color('primary')}; + } + @if not color('o-cc#{$index}-btn-primary-border') { + --o-cc#{$index}-btn-primary-border: #{$-btn-primary or theme-color('primary')}; + } + + $-btn-secondary: color('o-cc#{$index}-btn-secondary'); + @if not $-btn-secondary { + --o-cc#{$index}-btn-secondary: #{theme-color('secondary')}; + } + @if not color('o-cc#{$index}-btn-secondary-border') { + --o-cc#{$index}-btn-secondary-border: #{$-btn-secondary or theme-color('secondary')}; + } + } } html, body { diff --git a/addons/web_editor/static/src/scss/web_editor.variables.scss b/addons/web_editor/static/src/scss/web_editor.variables.scss index ab240268f62..5f6f97a5e74 100644 --- a/addons/web_editor/static/src/scss/web_editor.variables.scss +++ b/addons/web_editor/static/src/scss/web_editor.variables.scss @@ -251,6 +251,7 @@ $o-we-toolbar-height: 32px; &.btn-primary { @include button-variant($o-brand-primary, $o-brand-primary); + color: white; } &.btn-secondary { @include button-variant($o-we-bg-color, $o-we-bg-color); @@ -262,15 +263,19 @@ $o-we-toolbar-height: 32px; } &.btn-success { @include button-variant($o-we-color-success, $o-we-color-success); + color: white; } &.btn-info { @include button-variant($o-we-color-info, $o-we-color-info); + color: white; } &.btn-warning { @include button-variant($o-we-color-warning, $o-we-color-warning); + color: $o-we-color-divider; } &.btn-danger { @include button-variant($o-we-color-danger, $o-we-color-danger); + color: $o-we-color-divider; } } } diff --git a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss index 1631c70f075..99c9ddf2a56 100644 --- a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss +++ b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss @@ -265,6 +265,21 @@ body.editor_enable.editor_has_snippets { } we-toggler { @include we-icon-button('\f107'); + + + * { + display: none !important; + margin-top: -1px !important; + background-color: rgba(0, 0, 0, 0.3); + } + &.active { + &::after { + content: '\f106'; + } + + + * { + display: block !important; + } + } } %we-icon-button { position: relative; @@ -284,8 +299,9 @@ body.editor_enable.editor_has_snippets { } we-customizeblock-options { + position: relative; display: block; - padding: 0.5em; + padding: 1em; color: var(--o-we-snippets-color); &:nth-child(2n) { @@ -343,6 +359,14 @@ body.editor_enable.editor_has_snippets { } } + .o_we_fold_icon { + @include o-position-absolute(0, 100%, 0, auto); + display: flex; + justify-content: center; + align-items: center; + width: 1em; + } + //---------------------------------------------------------------------- // User Value Widgets //---------------------------------------------------------------------- @@ -409,16 +433,10 @@ body.editor_enable.editor_has_snippets { &.active { background-color: transparent; border-color: var(--o-we-color); - - + we-select-menu { - display: block; - } } } we-select-menu { @include o-position-absolute(100%, 0, auto, 0); - margin-top: -1px; - display: none; z-index: $zindex-dropdown; border: 1px solid var(--o-we-color); background-color: var(--o-we-bg-color-dark); diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml index aee5de39106..aff99211e31 100644 --- a/addons/web_editor/static/src/xml/snippets.xml +++ b/addons/web_editor/static/src/xml/snippets.xml @@ -64,14 +64,17 @@ + +
+

Title

+

Text

+ Button + Button +
+
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index b1e98e1b874..d99c09c8924 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -614,6 +614,13 @@ options.registry.background.include({ }); options.registry.Theme = options.Class.extend({ + events: { + 'click .o_color_combinations_edition we-toggler': '_onCCTogglerClick', + // FIXME investigate why using 'click' does not work *anymore* but those + // foldable areas will be made more robust and standard with the new UI. + 'mouseup .o_cc_subheadings_toggler_icon': '_onCCHeadingsTogglerClick', + }, + /** * @override */ @@ -812,6 +819,77 @@ options.registry.Theme = options.Class.extend({ }); return aceEditor; }, + /** + * @override + */ + async _renderOriginalXML($xml) { + const uiFragment = await this._super(...arguments); + + uiFragment.querySelectorAll('.o_cc_subheadings_toggler').forEach(headingsEl => { + const togglerEl = document.createElement('span'); + togglerEl.classList.add('o_cc_subheadings_toggler_icon', 'o_we_fold_icon', 'fa', 'fa-caret-down'); + togglerEl.setAttribute('role', 'button'); + const titleEl = headingsEl.querySelector('we-title'); + titleEl.insertBefore(togglerEl, titleEl.firstChild); + }); + uiFragment.querySelectorAll('.o_cc_subheadings_collapse').forEach(subheadingsEl => { + subheadingsEl.classList.add('d-none'); + }); + + return uiFragment; + }, + /** + * @override + */ + async _renderCustomXML(uiFragment) { + const ccEl = uiFragment.querySelector('.o_color_combinations_edition'); + for (let i = 1; i <= 5; i++) { + const togglerEl = document.createElement('we-toggler'); + togglerEl.classList.add('pt-0', 'pb-0', 'pl-0'); + const divEl = document.createElement('div'); + divEl.classList.add('o_we_cc_preview_container'); + const ccPreviewEl = $(qweb.render('web_editor.color.combination.preview'))[0]; + ccPreviewEl.classList.add('p-1', 'text-center', `o_cc${i}`); + divEl.appendChild(ccPreviewEl); + togglerEl.appendChild(divEl); + ccEl.appendChild(togglerEl); + + const collapseEl = document.createElement('we-collapse'); + const editionEl = $(qweb.render('website.color_combination_edition', {number: i}))[0]; + collapseEl.appendChild(editionEl); + ccEl.appendChild(collapseEl); + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Event} ev + */ + _onCCTogglerClick(ev) { + const ccTogglerEls = this.el.querySelectorAll('.o_color_combinations_edition we-toggler'); + for (const el of ccTogglerEls) { + if (el !== ev.currentTarget) { + el.classList.remove('active'); + } + } + ev.currentTarget.classList.toggle('active'); + }, + /** + * @private + * @param {Event} ev + */ + _onCCHeadingsTogglerClick(ev) { + const togglerEl = ev.currentTarget; + const collapseEl = togglerEl.closest('we-collapse').querySelector('.o_cc_subheadings_collapse'); + const show = togglerEl.classList.contains('fa-caret-down'); + togglerEl.classList.toggle('fa-caret-down', !show); + togglerEl.classList.toggle('fa-caret-up', show); + collapseEl.classList.toggle('d-none', !show); + }, }); options.registry.menu_data = options.Class.extend({ diff --git a/addons/website/static/src/scss/bootstrap_overridden.scss b/addons/website/static/src/scss/bootstrap_overridden.scss index c00ab7833ba..042b4d1dd72 100644 --- a/addons/website/static/src/scss/bootstrap_overridden.scss +++ b/addons/website/static/src/scss/bootstrap_overridden.scss @@ -2,32 +2,40 @@ // Color system // -// Bootstrap default for $yiq-text-light and $yiq-text-dark are $white and -// $gray-900. What we want to do is use the user text color as light or dark -// depending on its contrast. Themes should be careful if they decide to -// override those values. This would be simplified by giving the user the choice -// for its dark *and* light text colors. -$-light: if(o-color('white') != null, o-color('white'), #FFFFFF); -$-dark: if(o-color('900') != null, o-color('900'), #212529); -$-text: if(o-color('text') != null, o-color('text'), $-dark); -$-is-light: (o-get-most-contrast($-text, $-light, $-dark, o-color('body'), $cross-mix: false) == $-dark); -$yiq-text-light: if($-is-light, o-color('text'), null) !default; -$yiq-text-dark: if($-is-light, null, o-color('text')) !default; +// Use auto threshold for yiq colors +// Note: also need to be defined here so that color-yiq below works +$yiq-contrasted-threshold: false !default; + +// Customize the light and dark text colors for use in our YIQ color contrast function. +$yiq-text-dark: o-color('900') !default; +$yiq-text-light: o-color('white') !default; // Body // // Settings for the `` element. -$body-bg: o-color('body') !default; -$body-color: o-color('text') !default; +$body-bg: if($o-theme-layout == 'full', o-color('o-cc1-bg'), o-color('body')) !default; +$body-color: o-color('o-cc1-text') or color-yiq(o-color('o-cc1-bg')) !default; // Links // // Style anchor elements. +$link-color: o-color('o-cc1-link') !default; $link-decoration: if(o-website-value('link-underline') == 'always', underline, none) !default; $link-hover-decoration: if(o-website-value('link-underline') != 'never', underline, none) !default; +// Components +// +// Define common padding and border radius sizes and more. + +// Note: for the 'active' color, color preset edition is not really flexible but +// this could come in a future update. +$component-active-bg: o-color('o-cc1-btn-primary') !default; +@if $component-active-bg { + $component-active-color: color-yiq($component-active-bg) !default; +} + // Fonts // // Font, line-height, and color for body text, headings, and more. @@ -44,7 +52,9 @@ $h5-font-size: $font-size-base * $o-theme-h5-font-size-multiplier !default; $h6-font-size: $font-size-base * $o-theme-h6-font-size-multiplier !default; $headings-font-family: $o-theme-headings-font !default; -$headings-color: o-color('h1') !default; +$headings-color: o-color('o-cc1-headings') !default; + +$text-muted: mute-color($body-color) !default; // Jumbotron diff --git a/addons/website/static/src/scss/primary_variables.scss b/addons/website/static/src/scss/primary_variables.scss index 432ac1163c6..7f5a77fae14 100644 --- a/addons/website/static/src/scss/primary_variables.scss +++ b/addons/website/static/src/scss/primary_variables.scss @@ -8,13 +8,6 @@ $o-base-color-palette: map-merge($o-base-color-palette, ( 'body': $o-portal-default-body-bg, 'menu': #F8F9FA, // BS gray-100 'footer': #F8F9FA, // BS gray-100 - 'text': null, // Default to bootstrap - 'h1': null, // Default to text - 'h2': null, // Default to h1 - 'h3': null, // Default to h2 - 'h4': null, // Default to h3 - 'h5': null, // Default to h4 - 'h6': null, // Default to h5 )); // By default, all user color palette values are null. Each null value is diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss index bf2e0b01353..46de1af4a93 100644 --- a/addons/website/static/src/scss/website.scss +++ b/addons/website/static/src/scss/website.scss @@ -41,21 +41,7 @@ $-font-numbers: ( } // 5) Use final value used by the theme - $-h1-color: if($headings-color == inherit or not $headings-color, $body-color, $headings-color); - $-h2-color: if(color('h2'), color('h2'), $-h1-color); - $-h3-color: if(color('h3'), color('h3'), $-h2-color); - $-h4-color: if(color('h4'), color('h4'), $-h3-color); - $-h5-color: if(color('h5'), color('h5'), $-h4-color); - $-h6-color: if(color('h6'), color('h6'), $-h5-color); - --body: #{$body-bg}; - --text: #{$body-color}; - --h1: #{$-h1-color}; - --h2: #{$-h2-color}; - --h3: #{$-h3-color}; - --h4: #{$-h4-color}; - --h5: #{$-h5-color}; - --h6: #{$-h6-color}; --logo-height: #{$o-theme-navbar-logo-height}; --fixed-logo-height: #{$o-theme-navbar-fixed-logo-height}; @@ -81,7 +67,7 @@ $-font-numbers: ( } #wrap { - background-color: $white; + background-color: o-color('o-cc1-bg'); } } } @@ -145,19 +131,19 @@ $-header-nav-link-height: $nav-link-height; } } h2, h3, h4, h5, h6 { - color: color('h2'); + color: color('o-cc1-h2'); } h3, h4, h5, h6 { - color: color('h3'); + color: color('o-cc1-h3'); } h4, h5, h6 { - color: color('h4'); + color: color('o-cc1-h4'); } h5, h6 { - color: color('h5'); + color: color('o-cc1-h5'); } h6 { - color: color('h6'); + color: color('o-cc1-h6'); } .btn { @if ($o-theme-buttons-font != $o-theme-font) { diff --git a/addons/website/static/src/scss/website.wysiwyg.scss b/addons/website/static/src/scss/website.wysiwyg.scss index a2f210f70da..980026c5e82 100644 --- a/addons/website/static/src/scss/website.wysiwyg.scss +++ b/addons/website/static/src/scss/website.wysiwyg.scss @@ -169,3 +169,8 @@ $i: 1; } } } + +we-collapse { + position: relative; + padding: 0.3em 0.3em 0.3em 1em; +} diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index fecb8626102..998c60f4963 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -84,6 +84,30 @@ + +
+ + + + + + + + + + + + + + + + + + + +
+
+
diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml index 42ce9562f9a..504e00787f0 100644 --- a/addons/website/views/snippets/snippets.xml +++ b/addons/website/views/snippets/snippets.xml @@ -646,20 +646,20 @@ still customizable. - - + + +
- - + @@ -668,17 +668,7 @@ On Hover Always - - - - - - - - - - - + Fill @@ -688,19 +678,19 @@ Fill Outline + + Full + Boxed + - - + + None Image Pattern - + - - Full - Boxed - &lt;head&gt; &lt;/body&gt;