summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2020-05-28 10:04:43 +0000
committerqsm-odoo <qsm@odoo.com>2020-06-02 09:42:19 +0000
commitd9c4d928f7c7e148d024cb56f53e6bfb98389f6d (patch)
tree7f3a5a4a98065447a82f38cdfa52b1b87a47c5d5
parent69190959ce8e08481be7ebdfefd314edf0c5dce1 (diff)
[IMP] web_editor, *: integrate new o_cc${xxx} classes in the colorpicker
*: website Part of https://github.com/odoo/odoo/pull/45856 task-2197038
-rw-r--r--addons/web_editor/static/src/js/common/utils.js29
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.options.js26
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js67
-rw-r--r--addons/web_editor/static/src/scss/wysiwyg_snippets.scss68
-rw-r--r--addons/web_editor/static/src/xml/snippets.xml30
-rw-r--r--addons/web_editor/static/tests/field_html_tests.js6
-rw-r--r--addons/website/static/src/js/editor/snippets.options.js3
-rw-r--r--addons/website/static/src/scss/website.wysiwyg.scss9
-rw-r--r--addons/website/views/snippets/snippets.xml8
9 files changed, 192 insertions, 54 deletions
diff --git a/addons/web_editor/static/src/js/common/utils.js b/addons/web_editor/static/src/js/common/utils.js
index 912b4717c69..e7e2a4fad97 100644
--- a/addons/web_editor/static/src/js/common/utils.js
+++ b/addons/web_editor/static/src/js/common/utils.js
@@ -139,6 +139,33 @@ function _areCssValuesEqual(value1, value2, cssProp, $target) {
const numValue2 = _convertValueToUnit(value2, data[1], cssProp, $target);
return (Math.abs(numValue1 - numValue2) < Number.EPSILON);
}
+/**
+ * @param {string|number} name
+ * @returns {boolean}
+ */
+function _isColorCombinationName(name) {
+ const number = parseInt(name);
+ return (!isNaN(number) && number % 100 !== 0);
+}
+/**
+ * @param {string[]} colorNames
+ * @param {string} [prefix='bg-']
+ * @returns {string[]}
+ */
+function _computeColorClasses(colorNames, prefix = 'bg-') {
+ let hasCCClasses = false;
+ const classes = colorNames.map(c => {
+ if (_isColorCombinationName(c)) {
+ hasCCClasses = true;
+ return `o_cc${c}`;
+ }
+ return (prefix + c);
+ });
+ if (hasCCClasses) {
+ classes.push('o_cc');
+ }
+ return classes;
+}
return {
CSS_SHORTHANDS: CSS_SHORTHANDS,
@@ -148,5 +175,7 @@ return {
convertNumericToUnit: _convertNumericToUnit,
getNumericAndUnit: _getNumericAndUnit,
areCssValuesEqual: _areCssValuesEqual,
+ isColorCombinationName: _isColorCombinationName,
+ computeColorClasses: _computeColorClasses,
};
});
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 0b30bf856ce..212ab507755 100644
--- a/addons/web_editor/static/src/js/editor/snippets.options.js
+++ b/addons/web_editor/static/src/js/editor/snippets.options.js
@@ -1086,11 +1086,15 @@ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({
* @returns {Promise}
*/
_renderColorPalette: function () {
- const options = {};
- options.selectedColor = this._value;
+ const options = {
+ selectedColor: this._value,
+ };
if (this.options.dataAttributes.excluded) {
options.excluded = this.options.dataAttributes.excluded.replace(/ /g, '').split(',');
}
+ if (this.options.dataAttributes.withCombinations) {
+ options.withCombinations = !!this.options.dataAttributes.withCombinations;
+ }
const oldColorPalette = this.colorPalette;
this.colorPalette = new ColorPaletteWidget(this, options);
if (oldColorPalette) {
@@ -1108,14 +1112,17 @@ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({
_updateUI: async function (color) {
await this._super(...arguments);
- this.colorPreviewEl.classList.remove(...this.colorPalette.getColorNames().map(c => 'bg-' + c));
+ const classes = weUtils.computeColorClasses(this.colorPalette.getColorNames());
+ this.colorPreviewEl.classList.remove(...classes);
this.colorPreviewEl.style.removeProperty('background-color');
if (this._value) {
if (ColorpickerWidget.isCSSColor(this._value)) {
this.colorPreviewEl.style.backgroundColor = this._value;
+ } else if (weUtils.isColorCombinationName(this._value)) {
+ this.colorPreviewEl.classList.add('o_cc', `o_cc${this._value}`);
} else {
- this.colorPreviewEl.classList.add('bg-' + this._value);
+ this.colorPreviewEl.classList.add(`bg-${this._value}`);
}
}
@@ -1631,9 +1638,15 @@ const SnippetOptionWidget = Widget.extend({
// other potential color names (to remove) and if we know about a prefix
// (otherwise we suppose that we should use the actual related color).
if (params.colorNames && params.colorPrefix) {
- const classes = params.colorNames.map(c => params.colorPrefix + c);
+ const classes = weUtils.computeColorClasses(params.colorNames, params.colorPrefix);
this.$target[0].classList.remove(...classes);
+ if (weUtils.isColorCombinationName(widgetValue)) {
+ // Those are the special color combinations classes. Just have
+ // to add it (and adding the potential extra class) then leave.
+ this.$target[0].classList.add('o_cc', `o_cc${widgetValue}`, params.extraClass);
+ return;
+ }
if (params.colorNames.includes(widgetValue)) {
const originalCSSValue = window.getComputedStyle(this.$target[0])[cssProps[0]];
const className = params.colorPrefix + widgetValue;
@@ -1924,7 +1937,8 @@ const SnippetOptionWidget = Widget.extend({
case 'selectStyle': {
if (params.colorPrefix && params.colorNames) {
for (const c of params.colorNames) {
- if (this.$target[0].classList.contains(params.colorPrefix + c)) {
+ const className = weUtils.computeColorClasses([c], params.colorPrefix)[0];
+ if (this.$target[0].classList.contains(className)) {
return c;
}
}
diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js b/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js
index 60fdec4108d..4f6d677a1cb 100644
--- a/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js
+++ b/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js
@@ -7,6 +7,7 @@ const session = require('web.session');
const {ColorpickerWidget} = require('web.Colorpicker');
const Widget = require('web.Widget');
const summernoteCustomColors = require('web_editor.rte.summernote_custom_colors');
+const weUtils = require('web_editor.utils');
const qweb = core.qweb;
@@ -14,9 +15,10 @@ const ColorPaletteWidget = Widget.extend({
// ! for xmlDependencies, see loadDependencies function
template: 'web_editor.snippet.option.colorpicker',
events: {
- 'click button': '_onColorButtonClick',
- 'mouseenter button': '_onColorButtonEnter',
- 'mouseleave button': '_onColorButtonLeave',
+ 'click .o_we_color_btn': '_onColorButtonClick',
+ 'mouseenter .o_we_color_btn': '_onColorButtonEnter',
+ 'mouseleave .o_we_color_btn': '_onColorButtonLeave',
+ 'click .o_we_colorpicker_switch_pane_btn': '_onSwitchPaneButtonClick',
},
custom_events: {
'colorpicker_select': '_onColorPickerSelect',
@@ -42,9 +44,13 @@ const ColorPaletteWidget = Widget.extend({
excluded: [],
excludeSectionOf: null,
$editable: $(),
+ withCombinations: false,
}, options || {});
this.selectedColor = '';
+ this.resetButton = this.options.resetButton;
+ this.withCombinations = this.options.withCombinations;
+
this.trigger_up('request_editable', {callback: val => this.options.$editable = val});
},
/**
@@ -60,28 +66,20 @@ const ColorPaletteWidget = Widget.extend({
start: async function () {
const res = this._super.apply(this, arguments);
- const $colorSection = this.$('.o_colorpicker_sections');
- const $wrapper = $colorSection.find('.o_colorpicker_section_tabs');
+ const $colorSection = this.$('.o_colorpicker_sections[data-color-tab="theme-colors"]');
const $clpicker = qweb.has_template('web_editor.colorpicker')
? $(qweb.render('web_editor.colorpicker'))
: $(`<colorpicker><div class="o_colorpicker_section" data-name="common"></div></colorpicker>`);
- $clpicker.appendTo($wrapper);
+ $clpicker.find('button').addClass('o_we_color_btn');
+ $clpicker.appendTo($colorSection);
// Remove excluded palettes (note: only hide them to still be able
// to remove their related colors on the DOM target)
- _.each(this.options.excluded, function (exc) {
- $colorSection.find('[data-name="' + exc + '"]').addClass('d-none');
+ _.each(this.options.excluded, exc => {
+ this.$('[data-name="' + exc + '"]').addClass('d-none');
});
if (this.options.excludeSectionOf) {
- $colorSection.find('[data-name]:has([data-color="' + this.options.excludeSectionOf + '"])').addClass('d-none');
- }
-
- if (this.options.resetButton) {
- let $section = this.$('.o_colorpicker_section[data-name="theme"]');
- if ($section.hasClass('d-none')) {
- $section = $section.insertBefore('<div class="o_colorpicker_section" data-name="reset"/>');
- }
- this._createColorButton('', ['o_colorpicker_reset', 'float-right']).appendTo($section);
+ this.$('[data-name]:has([data-color="' + this.options.excludeSectionOf + '"])').addClass('d-none');
}
this.el.querySelectorAll('.o_colorpicker_section').forEach(elem => {
@@ -109,9 +107,14 @@ const ColorPaletteWidget = Widget.extend({
this.el.querySelectorAll('button[data-color]').forEach(elem => {
const colorName = elem.dataset.color;
const $color = $(elem);
- $color.addClass('bg-' + colorName);
+ const isCCName = weUtils.isColorCombinationName(colorName);
+ if (isCCName) {
+ $color.find('.o_we_cc_preview_wrapper').addClass(`o_cc o_cc${colorName}`);
+ } else {
+ $color.addClass(`bg-${colorName}`);
+ }
this.colorNames.push(colorName);
- if (!elem.classList.contains('d-none')) {
+ if (!isCCName && !elem.classList.contains('d-none')) {
const color = ColorpickerWidget.normalizeCSSColor(this.style.getPropertyValue('--' + colorName).trim());
this.colorToColorNames[color] = colorName;
}
@@ -140,7 +143,7 @@ const ColorPaletteWidget = Widget.extend({
this.colorPicker = new ColorpickerWidget(this, {
defaultColor: defaultColor,
});
- await this.colorPicker.prependTo(this.$el);
+ await this.colorPicker.prependTo($colorSection);
return res;
},
/**
@@ -217,12 +220,8 @@ const ColorPaletteWidget = Widget.extend({
_addCustomColorButton: function (color, classes = []) {
classes.push('o_custom_color');
const $themeSection = this.$('.o_colorpicker_section[data-name="theme"]');
- // There is 8 buttons on a colorpalette line, the clear button is always the last of the first line.
- if (this.options.resetButton && $themeSection.find('button').length < 8) {
- const $resetButton = $themeSection.find('.o_colorpicker_reset');
- return this._createColorButton(color, classes).insertBefore($resetButton);
- }
- return this._createColorButton(color, classes).appendTo($themeSection);
+ const $button = this._createColorButton(color, classes);
+ return $button.appendTo($themeSection);
},
/**
* Return a color button.
@@ -233,7 +232,7 @@ const ColorPaletteWidget = Widget.extend({
*/
_createColorButton: function (color, classes) {
return $('<button/>', {
- class: classes.join(' '),
+ class: 'o_we_color_btn ' + classes.join(' '),
style: 'background-color:' + color + ';',
});
},
@@ -338,6 +337,20 @@ const ColorPaletteWidget = Widget.extend({
target: this.colorPicker.el,
}, 'custom_color_picked');
},
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onSwitchPaneButtonClick(ev) {
+ ev.stopPropagation();
+ this.el.querySelectorAll('.o_we_colorpicker_switch_pane_btn').forEach(el => {
+ el.classList.remove('active');
+ });
+ ev.currentTarget.classList.add('active');
+ this.el.querySelectorAll('.o_colorpicker_sections').forEach(el => {
+ el.classList.toggle('d-none', el.dataset.colorTab !== ev.currentTarget.dataset.target);
+ });
+ },
});
//------------------------------------------------------------------------------
diff --git a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss
index 97b4659535e..1631c70f075 100644
--- a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss
+++ b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss
@@ -635,13 +635,55 @@ body.editor_enable.editor_has_snippets {
}
}
+.o_we_cc_preview_container {
+ background-color: white !important;
+ background-image: url("/web_editor/static/src/img/transparent.png") !important;
+ font-family: sans-serif !important;
+ font-size: 16px !important;
+}
+.o_we_cc_preview_wrapper > * {
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+}
+.o_we_color_combination_btn_text {
+ color: inherit !important;
+ font-family: inherit !important;
+ font-size: 0.8em !important;
+}
+.o_we_color_combination_btn_title {
+ font-size: 1em !important;
+}
+.o_we_color_combination_btn_btn {
+ padding: 0 1px !important;
+ border-radius: 2px !important;
+ font-size: 0.8em !important;
+}
+
// SNIPPET OPTIONS
.colorpicker {
- padding: 3px;
+ .d-flex .btn.o_we_colorpicker_switch_pane_btn {
+ font-size: 0.8em !important;
+
+ &.active {
+ border-bottom: 1px solid $o-we-handles-accent-color !important;
+ }
+
+ + .o_colorpicker_reset {
+ border: 1px solid var(--o-we-color) !important;
+ border-radius: 2px !important;
+ font-size: 0.8em !important;
+ padding: 0 2px !important;
+ align-self: center;
+ }
+
+ &:focus {
+ box-shadow: none;
+ }
+ }
.o_colorpicker_sections {
font-size: 14px;
- button {
+ .o_we_color_btn, .o_we_color_combination_btn {
float: left;
width: percentage(1 / 8);
padding-top: percentage(1 / 8);
@@ -664,12 +706,30 @@ body.editor_enable.editor_has_snippets {
}
}
+ .o_we_color_combination_btn {
+ float: none;
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ background-clip: padding-box;
+ border-top: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+
+ > .o_we_cc_preview_wrapper {
+ padding: 8px;
+ }
+
+ + .o_we_color_combination_btn {
+ margin-top: -4px;
+ }
+ }
+
.o_colorpicker_section {
> :first-child {
margin: 4px 0;
}
- button {
+ .o_we_color_btn {
position: relative;
&.selected::before {
@@ -688,7 +748,7 @@ body.editor_enable.editor_has_snippets {
}
&[data-name="transparent_grayscale"], &[data-name="theme"], &[data-name="reset"] {
- button {
+ .o_we_color_btn {
@include o-alpha-button-preview;
&::before, &::after {
diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml
index 59d3d28d5cc..aee5de39106 100644
--- a/addons/web_editor/static/src/xml/snippets.xml
+++ b/addons/web_editor/static/src/xml/snippets.xml
@@ -43,11 +43,35 @@
<!-- options -->
<div t-name="web_editor.snippet.option.colorpicker" class="colorpicker">
-
- <div class="o_colorpicker_sections">
- <div class="tab-content o_colorpicker_section_tabs"/>
+ <div class="d-flex px-1">
+ <button t-if="widget.withCombinations" type="button" class="btn flex-grow-1 o_we_colorpicker_switch_pane_btn active" data-target="color-combinations">Combinations</button>
+ <button type="button" t-attf-class="btn flex-grow-1 o_we_colorpicker_switch_pane_btn #{widget.withCombinations ? '' : 'active'}" data-target="theme-colors">Custom</button>
+ <button t-if="widget.resetButton" type="button" class="btn flex-grow-1 o_we_color_btn o_colorpicker_reset">
+ <t t-if="widget.withCombinations">None</t>
+ <t t-else="">Reset</t>
+ </button>
+ </div>
+ <div t-attf-class="o_colorpicker_sections #{widget.withCombinations ? '' : 'd-none'} px-1" data-color-tab="color-combinations">
+ <!-- List all Presets -->
+ <t t-foreach="5" t-as="i">
+ <t t-call="web_editor.colorpalette.combination.btn">
+ <t t-set="number" t-value="i + 1"/>
+ </t>
+ </t>
</div>
+ <div t-attf-class="o_colorpicker_sections #{widget.withCombinations ? 'd-none' : ''} p-1" data-color-tab="theme-colors"/>
</div>
+ <t t-name="web_editor.colorpalette.combination.btn">
+ <button type="button" class="o_we_color_btn o_we_color_combination_btn o_we_cc_preview_container"
+ t-att-data-color="number" t-attf-title="Preset #{number}">
+ <div class="o_we_cc_preview_wrapper d-flex justify-content-between align-items-end">
+ <h1 class="o_we_color_combination_btn_title">Title</h1>
+ <p class="o_we_color_combination_btn_text flex-grow-1">Text</p>
+ <span class="o_we_color_combination_btn_btn btn btn-sm btn-primary o_btn_preview mr-1"><small>Button</small></span>
+ <span class="o_we_color_combination_btn_btn btn btn-sm btn-secondary o_btn_preview"><small>Button</small></span>
+ </div>
+ </button>
+ </t>
<t t-name="web_editor.many2one.button">
<div class="btn-group">
diff --git a/addons/web_editor/static/tests/field_html_tests.js b/addons/web_editor/static/tests/field_html_tests.js
index ea20cdc5623..d1e83c32393 100644
--- a/addons/web_editor/static/tests/field_html_tests.js
+++ b/addons/web_editor/static/tests/field_html_tests.js
@@ -201,7 +201,7 @@ QUnit.module('web_editor', {}, function () {
assert.ok($field.find('.note-back-color-preview').hasClass('show'),
"should display the color picker");
- await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button[style="background-color:#00FFFF;"]'));
+ await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview .o_we_color_btn[style="background-color:#00FFFF;"]'));
assert.ok(!$field.find('.note-back-color-preview').hasClass('show'),
"should close the color picker");
@@ -227,7 +227,7 @@ QUnit.module('web_editor', {}, function () {
// text is selected
await openColorpicker('.note-toolbar .note-back-color-preview');
- await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button.bg-gamma'));
+ await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview .o_we_color_btn.bg-gamma'));
assert.strictEqual($field.find('.note-editable').html(),
'<p>t<font style="background-color: rgb(0, 255, 255);">oto t</font><font style="" class="bg-gamma">oto&nbsp;</font><font class="bg-gamma" style="">to</font>to</p><p>tata</p>',
@@ -386,7 +386,7 @@ QUnit.module('web_editor', {}, function () {
}
await openColorpicker('.note-toolbar .note-back-color-preview');
- await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview button.bg-gamma'));
+ await testUtils.dom.click($field.find('.note-toolbar .note-back-color-preview .o_we_color_btn.bg-gamma'));
await testUtils.form.clickSave(form);
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index 89310998fde..5bde2b6d1c8 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -5,8 +5,9 @@ const {ColorpickerWidget} = require('web.Colorpicker');
const config = require('web.config');
var core = require('web.core');
var Dialog = require('web.Dialog');
-const wUtils = require('website.utils');
+const weUtils = require('web_editor.utils');
var options = require('web_editor.snippets.options');
+const wUtils = require('website.utils');
require('website.s_popup_options');
var _t = core._t;
diff --git a/addons/website/static/src/scss/website.wysiwyg.scss b/addons/website/static/src/scss/website.wysiwyg.scss
index 1eaaa7d97b8..a2f210f70da 100644
--- a/addons/website/static/src/scss/website.wysiwyg.scss
+++ b/addons/website/static/src/scss/website.wysiwyg.scss
@@ -135,7 +135,7 @@ $i: 1;
clear: both;
}
- > button {
+ > .o_we_color_btn {
&:hover,
&.selected {
@@ -152,8 +152,11 @@ $i: 1;
}
}
- .note-palette-title {
- color: $o-we-color-text-light;
+ .note-palette-title, a, button:not(.o_we_color_combination_btn) {
+
+ &, &:hover {
+ color: $o-we-color-text-light;
+ }
}
.palette-reset {
diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml
index 35a819eb40a..904d855565c 100644
--- a/addons/website/views/snippets/snippets.xml
+++ b/addons/website/views/snippets/snippets.xml
@@ -325,18 +325,12 @@
data-js="MainColorpicker"
data-selector="section, .carousel-item, section .row > div, .o_record_cover_container"
data-exclude=".parallax, .o_gallery .carousel-item, .s_col_no_bgcolor, .s_col_no_bgcolor.row > div, .o_gallery .row > div, .s_carousel_wrapper, .s_tabs .oe_structure > *">
- <we-select data-trigger="bg_color_opt" data-trigger-value="">
- <we-button data-select-class="o_cc o_cc1">Color combinations 1</we-button>
- <we-button data-select-class="o_cc o_cc2">Color combinations 2</we-button>
- <we-button data-select-class="o_cc o_cc3">Color combinations 3</we-button>
- <we-button data-select-class="o_cc o_cc4">Color combinations 4</we-button>
- <we-button data-select-class="o_cc o_cc5">Color combinations 5</we-button>
- </we-select>
<we-colorpicker string="Background Color"
data-name="bg_color_opt"
data-select-style="true"
data-css-property="background-color"
data-color-prefix="bg-"
+ data-with-combinations="true"
data-dependencies="!cover_background_opt"/>
</div>