summaryrefslogtreecommitdiff
path: root/addons/web_editor
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web_editor')
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.options.js38
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js14
-rw-r--r--addons/web_editor/static/src/scss/bootstrap_overridden.scss14
-rw-r--r--addons/web_editor/static/src/scss/secondary_variables.scss69
-rw-r--r--addons/web_editor/static/src/scss/web_editor.common.scss125
-rw-r--r--addons/web_editor/static/src/scss/web_editor.variables.scss57
-rw-r--r--addons/web_editor/static/src/xml/wysiwyg.xml19
7 files changed, 315 insertions, 21 deletions
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 8decd41bb16..0b30bf856ce 100644
--- a/addons/web_editor/static/src/js/editor/snippets.options.js
+++ b/addons/web_editor/static/src/js/editor/snippets.options.js
@@ -2273,6 +2273,44 @@ const registry = {};
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+/**
+ * Marks color levels of any element that may get or has a color classes. This
+ * is done for the specific main colorpicker option so that those are marked on
+ * snippet drop (so that base snippet definition do not need to care about that)
+ * and on first focus (for compatibility).
+ */
+registry.MainColorpicker = SnippetOptionWidget.extend({
+ /**
+ * @override
+ */
+ start: function () {
+ this._markColorLevel();
+ return this._super(...arguments);
+ },
+ /**
+ * @override
+ */
+ onBuilt: function () {
+ this._markColorLevel();
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Adds a specific class indicating the element is colored so that nested
+ * color classes work (we support one-level). Removing it is not useful,
+ * technically the class can be added on anything that *may* receive a color
+ * class: this does not come with any CSS rule.
+ *
+ * @private
+ */
+ _markColorLevel: function () {
+ this.$target.addClass('o_colored_level');
+ },
+});
+
registry.sizing = SnippetOptionWidget.extend({
/**
* @override
diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js
index 699995f53d9..ed17127c55a 100644
--- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js
+++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js
@@ -60,7 +60,19 @@ var LinkDialog = Dialog.extend({
this.needLabel = !r || (r.sc === r.ec && r.so === r.eo);
if (this.data.range) {
- this.data.iniClassName = $(this.data.range.sc).filter("a").attr("class") || "";
+ const $link = $(this.data.range.sc).filter("a");
+ this.data.iniClassName = $link.attr("class") || "";
+ this.colorCombinationClass = false;
+ let $node = $link;
+ while ($node.length && !$node.is('body')) {
+ const className = $node.attr('class') || '';
+ const m = className.match(/\b(o_cc\d+)\b/g);
+ if (m) {
+ this.colorCombinationClass = m[0];
+ break;
+ }
+ $node = $node.parent();
+ }
this.data.className = this.data.iniClassName.replace(/(^|\s+)btn(-[a-z0-9_-]*)?/gi, ' ');
var is_link = this.data.range.isOnAnchor();
diff --git a/addons/web_editor/static/src/scss/bootstrap_overridden.scss b/addons/web_editor/static/src/scss/bootstrap_overridden.scss
index d1644a1174e..c1144ec23a7 100644
--- a/addons/web_editor/static/src/scss/bootstrap_overridden.scss
+++ b/addons/web_editor/static/src/scss/bootstrap_overridden.scss
@@ -3,16 +3,22 @@ $yiq-contrasted-threshold: false !default;
// Automatically update bootstrap colors map (unused by BS itself)
$colors: () !default;
-$colors: map-merge($o-color-palette, $colors);
+@each $name, $color in $o-color-palette {
+ $colors: map-merge(('#{$name}': o-color($color)), $colors);
+}
// Automatically extend bootstrap to create theme background/text/button classes
$theme-colors: () !default;
-$theme-colors: map-merge($o-theme-color-palette, $theme-colors);
+@each $name, $color in $o-theme-color-palette {
+ $theme-colors: map-merge(('#{$name}': o-color($color)), $theme-colors);
+}
// Automatically extend bootstrap gray palette (the theme palette is supposed to
// at least declare white and black)
$grays: () !default;
-$grays: map-merge($o-gray-color-palette, $grays);
+@each $name, $color in $o-gray-color-palette {
+ $grays: map-merge(('#{$name}': o-color($color)), $grays);
+}
// Bootstrap use standard variables to define individual colors which are then
// placed into a map which is then used to get the value of each individual
@@ -55,3 +61,5 @@ $gray-700: gray('700') !default;
$gray-800: gray('800') !default;
$gray-900: gray('900') !default;
$black: gray('black') !default;
+
+$o-color-system-initialized: true;
diff --git a/addons/web_editor/static/src/scss/secondary_variables.scss b/addons/web_editor/static/src/scss/secondary_variables.scss
index fa8f1a39120..52030130514 100644
--- a/addons/web_editor/static/src/scss/secondary_variables.scss
+++ b/addons/web_editor/static/src/scss/secondary_variables.scss
@@ -6,9 +6,6 @@
// Colors
$o-color-palette: nth($o-color-palettes, $o-color-palette-number) !default;
$o-color-palette: map-merge($o-base-color-palette, o-map-omit($o-color-palette));
-@function palette-color($key) {
- @return map-get($o-color-palette, $key);
-}
// Theme colors
$o-theme-color-palette: nth($o-theme-color-palettes, $o-theme-color-palette-number) !default;
@@ -27,9 +24,6 @@ $o-theme-color-palette: map-merge((
'dark': darken(desaturate($-main-color, 80%), min(70%, max(0%, $-main-color-lightness - 10%))), // Does not lower under 10% lightness
), o-map-omit($o-theme-color-palette));
$o-theme-color-palette: map-merge($o-base-theme-color-palette, o-map-omit($o-theme-color-palette));
-@function palette-theme-color($key) {
- @return map-get($o-theme-color-palette, $key);
-}
// Gray colors
// Extend grays with transparent ones (for some reason, BS4 create black-50 and
@@ -37,6 +31,65 @@ $o-theme-color-palette: map-merge($o-base-theme-color-palette, o-map-omit($o-the
$o-gray-color-palette: nth($o-gray-color-palettes, $o-gray-color-palette-number) !default;
$o-gray-color-palette: map-merge($o-transparent-grays, o-map-omit($o-gray-color-palette));
$o-gray-color-palette: map-merge($o-base-gray-color-palette, o-map-omit($o-gray-color-palette));
-@function palette-gray($key) {
- @return map-get($o-gray-color-palette, $key);
+
+// Color combinations
+$o-color-combinations: nth($o-color-combinations-presets, $o-color-combinations-preset-number) !default;
+
+$o-color-system-initialized: false;
+
+// Returns:
+// - true if the given name is a css color or null
+// - false if a potential valid color name
+// - throws an error if the given arg cannot reference a color
+@function check-color-identifier-type($name) {
+ $-type: type-of($name);
+ @if $-type == 'color' or $-type == 'null' {
+ @return true;
+ } @else if $-type != 'string' {
+ @error "Color name '#{$name}' is of unsupported type '#{$-type}'";
+ }
+ @return false;
+}
+// Looks up for the color related to the given name in the related odoo palettes
+// following redirection a maximum number of time (by default none).
+@function o-related-color($name, $max-recursions: 0, $original-name: $name) {
+ @if $max-recursions < 0 or check-color-identifier-type($name) {
+ @return $name;
+ }
+
+ $-value: null;
+ @if map-has-key($o-color-palette, $name) {
+ $-value: map-get($o-color-palette, $name);
+ } @else if map-has-key($o-theme-color-palette, $name) {
+ $-value: map-get($o-theme-color-palette, $name);
+ } @else if map-has-key($o-gray-color-palette, $name) {
+ $-value: map-get($o-gray-color-palette, $name);
+ }
+ @return o-related-color($-value, $max-recursions - 1, $original-name);
+}
+// Function which allows to retrieve a color value from a name, the color being
+// either in $theme-colors, $grays or $colors maps. If those maps are not
+// initialized yet, it will look up the color in the related odoo palettes.
+@function o-color($name) {
+ @if check-color-identifier-type($name) {
+ @return $name;
+ }
+
+ // When the system is initialized, it means that the bootstrap maps have
+ // been configured and contain a direct mapping between color name -> css
+ // value. We can thus search in those.
+ @if $o-color-system-initialized {
+ @if map-has-key($colors, $name) {
+ @return color($name);
+ }
+ @if map-has-key($theme-colors, $name) {
+ @return theme-color($name);
+ }
+ @if map-has-key($grays, $name) {
+ @return gray($name);
+ }
+ }
+
+ // If not initialized, search the css color value in selected color palettes
+ @return o-related-color($name, $max-recursions: 10);
}
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 1d8ee69551f..fbaa1557fa0 100644
--- a/addons/web_editor/static/src/scss/web_editor.common.scss
+++ b/addons/web_editor/static/src/scss/web_editor.common.scss
@@ -517,3 +517,128 @@ blockquote {
border-left: 5px solid $gray-300;
font-style: italic
}
+
+// Bg/text color classes generation
+.o_cc {
+ #{$o-color-extras-nesting-selector} {
+ // Re-force dropdown-item colors inside presets otherwise the presets
+ // 'link' colors take over.
+ .dropdown-menu .dropdown-item { // Need to add +1 priority thanks to
+ // .dropdown-menu to counter a:not(.btn)
+ &, h6 { // Quick fix: sometimes we use h6 in dropdowns
+ color: $dropdown-link-color;
+
+ @include hover-focus {
+ color: $dropdown-link-hover-color;
+ }
+ }
+ &.disabled,
+ &:disabled {
+ &, h6 { // Quick fix: sometimes we use h6 in dropdowns
+ color: $dropdown-link-disabled-color;
+ }
+ }
+ }
+ }
+}
+@for $index from 1 through length($o-color-combinations) {
+ $config: nth($o-color-combinations, $index);
+ $-bg: map-get($config, 'bg');
+ $-text: map-get($config, 'text');
+ $-headings: map-get($config, 'headings');
+ $-h2: map-get($config, 'h2');
+ $-h3: map-get($config, 'h3');
+ $-h4: map-get($config, 'h4');
+ $-h5: map-get($config, 'h5');
+ $-h6: map-get($config, 'h6');
+ $-link: map-get($config, 'link');
+ $-btn-primary: map-get($config, 'btn-primary');
+ $-btn-primary-border: map-get($config, 'btn-primary-border');
+ $-btn-secondary: map-get($config, 'btn-secondary');
+ $-btn-secondary-border: map-get($config, 'btn-secondary-border');
+
+ // Those color classes color multiple elements when applied on a snippet.
+ // Those rules are not important so that they can be overridden through
+ // bg and text utility classes. **
+ .o_cc#{$index} {
+ // Background & Text
+ @include o-bg-color(o-color($-bg), o-color($-text), $important: false);
+
+ #{$o-color-extras-nesting-selector} {
+ // Headings
+ h1, h2, h3, h4, h5, h6 {
+ // 'inherit' comes from the o-bg-color mixin
+ color: o-color($-headings);
+ }
+ h2, h3, h4, h5, h6 {
+ color: o-color($-h2);
+ }
+ h3, h4, h5, h6 {
+ color: o-color($-h3);
+ }
+ h4, h5, h6 {
+ color: o-color($-h4);
+ }
+ h5, h6 {
+ color: o-color($-h5);
+ }
+ h6 {
+ color: o-color($-h6);
+ }
+
+ // Links
+ $-link-color: if($-link, o-color($-link), theme-color('primary'));
+ $-link-hover-color: darken($-link-color, 15%);
+ a:not(.btn), .btn-link {
+ color: $-link-color;
+
+ @include hover {
+ color: $-link-hover-color;
+ }
+ }
+
+ // Buttons
+
+ // Primary
+ $-btn-primary-color: if($-btn-primary, o-color($-btn-primary), theme-color('primary'));
+ $-btn-primary-border-color: if($-btn-primary-border, o-color($-btn-primary-border), $-btn-primary-color);
+ .btn-fill-primary {
+ @include button-variant($-btn-primary-color, $-btn-primary-border-color);
+ }
+ .btn-outline-primary {
+ @include button-outline-variant($-btn-primary-border-color);
+ }
+
+ // Secondary
+ $-btn-secondary-color: if($-btn-secondary, o-color($-btn-secondary), theme-color('secondary'));
+ $-btn-secondary-border-color: if($-btn-secondary-border, o-color($-btn-secondary-border), $-btn-secondary-color);
+ .btn-fill-secondary {
+ @include button-variant($-btn-secondary-color, $-btn-secondary-border-color);
+ }
+ .btn-outline-secondary {
+ @include button-outline-variant($-btn-secondary-border-color);
+ }
+
+ // 'Active' states. Note: this only emulates very common components
+ // used in snippets. This might need to be more complex the day we
+ // can apply color combinations anywhere (page-item, ...).
+ .nav-pills {
+ .nav-link.active,
+ .show > .nav-link {
+ background-color: $-btn-primary-color;
+ color: color-yiq($-btn-primary-color);
+ }
+ }
+ .dropdown-menu .dropdown-item { // Need to add +1 priority thanks to
+ // .dropdown-menu (see .o_cc).
+ &.active,
+ &:active {
+ &, h6 { // Quick fix: sometimes we use h6 in dropdowns
+ @include gradient-bg($-btn-primary-color);
+ color: color-yiq($-btn-primary-color);
+ }
+ }
+ }
+ }
+ }
+}
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 d0fa36444c4..ecfda70dd87 100644
--- a/addons/web_editor/static/src/scss/web_editor.variables.scss
+++ b/addons/web_editor/static/src/scss/web_editor.variables.scss
@@ -338,7 +338,7 @@ $o-theme-color-palette-number: 1 !default;
// Greyscale transparent colours
// Note: BS values are forced by default in every palette as the values can
-// be used in bootstrap_overridden.scss files through the palette-gray function.
+// be used in bootstrap_overridden.scss files through the o-color function.
// Also, all of the gray colors generates bg- classes in Odoo so black and white
// are added for the same reason.
@@ -370,6 +370,61 @@ $o-gray-color-palettes: (
) !default;
$o-gray-color-palette-number: 1 !default;
+// Color combinations
+$o-color-combinations-presets: (
+ (
+ (
+ 'bg': #FFFFFF,
+ 'text': null,
+ 'headings': null,
+ 'link': null,
+ 'btn-primary': null,
+ 'btn-secondary': null,
+ ),
+ (
+ 'bg': 'gamma',
+ 'text': null,
+ 'headings': 'alpha',
+ 'link': null,
+ 'btn-primary': null,
+ 'btn-secondary': null,
+ ),
+ (
+ 'bg': 'beta',
+ 'text': null,
+ 'headings': null,
+ 'link': null,
+ 'btn-primary': null,
+ 'btn-secondary': 'gamma',
+ ),
+ (
+ 'bg': 'alpha',
+ 'text': null,
+ 'headings': null,
+ 'link': 'epsilon',
+ 'btn-primary': 'epsilon',
+ 'btn-secondary': 'gamma',
+ ),
+ (
+ 'bg': 'epsilon',
+ 'text': null,
+ 'headings': 'delta',
+ 'link': null,
+ 'btn-primary': null,
+ 'btn-secondary': 'gamma',
+ ),
+ ),
+) !default;
+$o-color-combinations-preset-number: 1;
+
// Translations
$o-we-content-to-translate-color: rgb(255, 255, 90) !default;
$o-we-translated-content-color: rgb(120, 215, 110) !default;
+
+// We allow snippets to be colored and elements like card and columns to be
+// colored as well. We need components targeted by those colored classes to
+// use the deepest coloring element config. We only allow here for this to
+// work for one level of nesting. Note: snippets which can contain other
+// snippets will have problem because of this; this is a limitation of the
+// system until a better solution is found.
+$o-color-extras-nesting-selector: '&, .o_colored_level &';
diff --git a/addons/web_editor/static/src/xml/wysiwyg.xml b/addons/web_editor/static/src/xml/wysiwyg.xml
index 402f6ef3858..f23165e8959 100644
--- a/addons/web_editor/static/src/xml/wysiwyg.xml
+++ b/addons/web_editor/static/src/xml/wysiwyg.xml
@@ -461,13 +461,15 @@
<div class="form-group row">
<label class="col-form-label col-md-3">Type</label>
<div class="col-md-9 d-flex align-items-center">
- <t t-foreach="widget.colorsData" t-as="colorData">
- <label role="button" class="m-0 mr-2">
- <input type="radio" name="link_style_color" class="d-none link-style" t-att-value="colorData.type"/>
- <span t-esc="colorData.label"
- t-attf-class="o_btn_preview btn btn-sm btn-#{colorData.btnPreview} #{colorData.type ? '' : 'px-0'}"/>
- </label>
- </t>
+ <div t-attf-class="#{widget.colorCombinationClass ? ('p-2 ' + widget.colorCombinationClass) : ''}">
+ <t t-foreach="widget.colorsData" t-as="colorData">
+ <label role="button" class="m-0 mr-2">
+ <input type="radio" name="link_style_color" class="d-none link-style" t-att-value="colorData.type"/>
+ <span t-esc="colorData.label"
+ t-attf-class="o_btn_preview btn btn-sm btn-#{colorData.btnPreview} #{colorData.type ? '' : 'px-0'}"/>
+ </label>
+ </t>
+ </div>
</div>
</div>
<div id="o_link_dialog_button_opts_collapse" class="collapse">
@@ -509,7 +511,8 @@
<div class="col-lg-4 o_link_dialog_preview">
<div class="form-group text-center">
<label>Preview</label>
- <div style="overflow-x: auto; max-width: 100%; max-height: 200px;">
+ <div t-attf-class="#{widget.colorCombinationClass ? ('p-2 ' + widget.colorCombinationClass) : ''}"
+ style="overflow-x: auto; max-width: 100%; max-height: 200px;">
<a href="#" id="link-preview" aria-label="Preview" title="Preview"/>
</div>
</div>