summaryrefslogtreecommitdiff
path: root/addons/web_editor/static/src
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2019-11-19 14:30:43 +0000
committerqsm-odoo <qsm@odoo.com>2019-12-01 15:49:57 +0000
commit216cf93b4dab381286991dcf650e859931bf1a43 (patch)
tree27bf2eec4d0c3fa17e9f1726ff3f3413057e5812 /addons/web_editor/static/src
parent702a0cd5c5caecb7ce747dc049f88f03182185ff (diff)
[REF] web, web_editor, *: review normalization of colors
* website Review colorpicker methods to always allow to use normalized colors. Also factorize some code in the color palette widget. Part of https://github.com/odoo/odoo/pull/40282 In preparation of task-2122935 and other tasks
Diffstat (limited to 'addons/web_editor/static/src')
-rw-r--r--addons/web_editor/static/src/js/common/utils.js6
-rw-r--r--addons/web_editor/static/src/js/editor/rte.js1
-rw-r--r--addons/web_editor/static/src/js/editor/rte.summernote.js2
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.options.js25
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js137
5 files changed, 84 insertions, 87 deletions
diff --git a/addons/web_editor/static/src/js/common/utils.js b/addons/web_editor/static/src/js/common/utils.js
index f3373c7bad2..67267d670ee 100644
--- a/addons/web_editor/static/src/js/common/utils.js
+++ b/addons/web_editor/static/src/js/common/utils.js
@@ -1,6 +1,8 @@
odoo.define('web_editor.utils', function (require) {
'use strict';
+const ColorpickerDialog = require('web.ColorpickerDialog');
+
/**
* window.getComputedStyle cannot work properly with CSS shortcuts (like
* 'border-width' which is a shortcut for the top + right + bottom + left border
@@ -116,6 +118,10 @@ function _getNumericAndUnit(value) {
* @returns {boolean}
*/
function _areCssValuesEqual(value1, value2, cssProp, $target) {
+ // If not colors, they will be left untouched
+ value1 = ColorpickerDialog.normalizeCSSColor(value1);
+ value2 = ColorpickerDialog.normalizeCSSColor(value2);
+
// String comparison first
if (value1 === value2) {
return true;
diff --git a/addons/web_editor/static/src/js/editor/rte.js b/addons/web_editor/static/src/js/editor/rte.js
index 7505e570626..b0c0891c1b6 100644
--- a/addons/web_editor/static/src/js/editor/rte.js
+++ b/addons/web_editor/static/src/js/editor/rte.js
@@ -767,6 +767,7 @@ return {
odoo.define('web_editor.rte.summernote_custom_colors', function (require) {
'use strict';
+// These colors are already normalized as per normalizeCSSColor in web.ColorpickerDialog
return [
['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'],
['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'],
diff --git a/addons/web_editor/static/src/js/editor/rte.summernote.js b/addons/web_editor/static/src/js/editor/rte.summernote.js
index 84683eabf15..233a38edb8c 100644
--- a/addons/web_editor/static/src/js/editor/rte.summernote.js
+++ b/addons/web_editor/static/src/js/editor/rte.summernote.js
@@ -56,7 +56,7 @@ renderer.createPalette = function ($container, options) {
selectedColor: $(targetElement).css(eventName === "foreColor" ? 'color' : 'backgroundColor'),
targetClasses: [...targetElement.classList],
});
- colorpicker.on('color_picked custom_color_picked', null, ev => applyColor(ev.data.target, eventName, ev.data.cssColor));
+ colorpicker.on('color_picked', null, ev => applyColor(ev.data.target, eventName, ev.data.cssColor));
colorpicker.on('color_reset', null, ev => applyColor(ev.data.target, eventName, 'inherit'));
return colorpicker.replace(hookEl).then(() => {
if (oldColorpicker) {
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 7df4ff69ade..d4fd5c11e1b 100644
--- a/addons/web_editor/static/src/js/editor/snippets.options.js
+++ b/addons/web_editor/static/src/js/editor/snippets.options.js
@@ -3,6 +3,7 @@ odoo.define('web_editor.snippets.options', function (require) {
var core = require('web.core');
const concurrency = require('web.concurrency');
+const ColorpickerDialog = require('web.ColorpickerDialog');
var Widget = require('web.Widget');
var ColorPaletteWidget = require('web_editor.ColorPalette').ColorPaletteWidget;
const weUtils = require('web_editor.utils');
@@ -1193,6 +1194,15 @@ const SnippetOptionWidget = Widget.extend({
};
},
/**
+ * @param {*}
+ * @returns {string}
+ */
+ _normalizeWidgetValue: function (value) {
+ value = `${value}`; // Force to string
+ value = ColorpickerDialog.normalizeCSSColor(value); // If is a css color, normalize it
+ return value;
+ },
+ /**
* @private
* @param {string} widgetName
* @param {UserValueWidget|this|null} parent
@@ -1359,7 +1369,8 @@ const SnippetOptionWidget = Widget.extend({
const methodsNames = widget.getMethodsNames();
const proms = methodsNames.map(async methodName => {
const value = await this._computeWidgetState(methodName, widget.getMethodsParams(methodName));
- widget.setValue(value, methodName);
+ const normalizedValue = this._normalizeWidgetValue(value);
+ widget.setValue(normalizedValue, methodName);
});
await Promise.all(proms);
@@ -1678,7 +1689,6 @@ registry.colorpicker = SnippetOptionWidget.extend({
xmlDependencies: ['/web_editor/static/src/xml/snippets.xml'],
custom_events: {
'color_picked': '_onColorPicked',
- 'custom_color_picked': '_onCustomColor',
'color_hover': '_onColorHovered',
'color_leave': '_onColorLeft',
'color_reset': '_onColorReset',
@@ -1762,21 +1772,14 @@ registry.colorpicker = SnippetOptionWidget.extend({
* @private
* @param {Event} ev
*/
- _onColorPicked: function () {
+ _onColorPicked: function (ev) {
+ this._changeTargetColor(ev.data.cssColor);
this._updateUI().then(() => {
this.$target.closest('.o_editable').trigger('content_changed');
this.$target.trigger('background-color-event', false);
});
},
/**
- * Called when a custom color is selected
- * @param {*} ev
- */
- _onCustomColor: function (ev) {
- this._changeTargetColor(ev.data.cssColor);
- this._onColorPicked();
- },
- /**
* Called when a color button is entered -> preview the background color.
*
* @private
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 f73c88a3a25..38edef463b6 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
@@ -2,7 +2,7 @@ odoo.define('web_editor.ColorPalette', function (require) {
'use strict';
const core = require('web.core');
-const ColorPickerDialog = require('web.ColorpickerDialog');
+const ColorpickerDialog = require('web.ColorpickerDialog');
const Dialog = require('web.Dialog');
const Widget = require('web.Widget');
const summernoteCustomColors = require('web_editor.rte.summernote_custom_colors');
@@ -36,7 +36,7 @@ const ColorPaletteWidget = Widget.extend({
*/
init: function (parent, options) {
this._super.apply(this, arguments);
- this.summernoteCustomColorsArray = [].concat(...summernoteCustomColors).map((color) => this._convertHexToCssRgba(color));
+ this.summernoteCustomColorsArray = [].concat(...summernoteCustomColors);
this.options = _.extend({
selectedColor: false,
targetClasses: [],
@@ -47,6 +47,11 @@ const ColorPaletteWidget = Widget.extend({
$editable: $(),
}, options || {});
+ const selectedColor = this.options.selectedColor;
+ if (selectedColor) {
+ this.options.selectedColor = ColorpickerDialog.normalizeCSSColor(selectedColor);
+ }
+
this.trigger_up('request_editable', {callback: val => this.options.$editable = val});
},
/**
@@ -107,7 +112,7 @@ const ColorPaletteWidget = Widget.extend({
}
// Render custom colors
- this._buildCustomColor();
+ this._buildCustomColors();
// TODO refactor in master
// The primary and secondary are hardcoded here (but marked as hidden)
@@ -143,7 +148,7 @@ const ColorPaletteWidget = Widget.extend({
* Reloads the color palette to get other custom colors on the page
*/
reloadColorPalette: function () {
- this._buildCustomColor();
+ this._buildCustomColors();
},
//--------------------------------------------------------------------------
@@ -153,41 +158,47 @@ const ColorPaletteWidget = Widget.extend({
/**
* @private
*/
- _buildCustomColor: function () {
- const existingColors = new Set(this.summernoteCustomColorsArray.concat(Array.from(this.el.querySelectorAll('.o_custom_color')).map(el => el.style.backgroundColor)));
- if (!this.options.excluded.includes('custom')) {
- Array.from(this.options.$editable.find('[style*="color"]')).forEach(el => {
- for (const colorProp of ['color', 'backgroundColor']) {
- const color = el.style[colorProp];
- if (color && !existingColors.has(color)) {
- this._addCustomColorButton(color);
- existingColors.add(color);
- }
- }
- });
+ _buildCustomColors: function () {
+ if (this.options.excluded.includes('custom')) {
+ return;
}
+ const existingColors = new Set(this.summernoteCustomColorsArray.concat(
+ [...this.el.querySelectorAll('.o_custom_color')].map(el => {
+ return ColorpickerDialog.normalizeCSSColor(el.style.backgroundColor);
+ })
+ ));
+ _.each(this.options.$editable.find('[style*="color"]'), el => {
+ for (const colorProp of ['color', 'backgroundColor']) {
+ const color = ColorpickerDialog.normalizeCSSColor(el.style[colorProp]);
+ if (color && !existingColors.has(color)) {
+ this._addCustomColorButton(color);
+ existingColors.add(color);
+ }
+ }
+ });
},
/**
* Add a custom button in the coresponding section.
*
* @private
- * @param {string} color Css rgb(a) string
- * @param {Array<string>} classes Classes added to the button
+ * @param {string} color
+ * @param {string[]} classes - classes added to the button
+ * @returns {jQuery}
*/
_addCustomColorButton: function (color, classes = []) {
classes.push('o_custom_color');
- this._createColorButton(color, classes).appendTo(this.$('.o_colorpicker_section[data-name="theme"]'));
+ const $themeSection = this.$('.o_colorpicker_section[data-name="theme"]');
+ return this._createColorButton(color, classes).appendTo($themeSection);
},
/**
* Return a color button.
*
- * @param {string} color Css rgb(a) string
- * @param {Array<string>} classes Classes added to the button
+ * @param {string} color
+ * @param {string[]} classes - classes added to the button
+ * @returns {jQuery}
*/
_createColorButton: function (color, classes) {
- const cssColor = this._convertHexToCssRgba(color);
- const selectedColor = this.options.selectedColor && this._convertHexToCssRgba(this.options.selectedColor);
- if (selectedColor === cssColor) {
+ if (this.options.selectedColor === color) { // both colors are already normalized
classes.push('selected');
}
return $('<button/>', {
@@ -196,33 +207,20 @@ const ColorPaletteWidget = Widget.extend({
});
},
/**
- * Return the hexadecimal css color as an rgb(a) css color: rgb((r, g, b) | rgba(r, g, b, a)
+ * Gets normalized information about a color button.
*
* @private
- * @param {string} hex Css hex string (#FFFFFF(FF))
+ * @param {HTMLElement} buttonEl
+ * @returns {Object}
*/
- _convertHexToCssRgba: function (hex) {
- if (!/^#([0-9A-F]{6}|[0-9A-F]{8})$/i.test(hex)) {
- return hex;
- }
-
- const red = parseInt(hex.substr(1, 2), 16);
- const blue = parseInt(hex.substr(3, 2), 16);
- const green = parseInt(hex.substr(5, 2), 16);
- if (hex.length === 9) {
- return _.str.sprintf('rgba(%s, %s, %s, %s)',
- red,
- blue,
- green,
- parseInt(hex.substr(7, 2), 16)
- );
- } else {
- return _.str.sprintf('rgb(%s, %s, %s)',
- red,
- blue,
- green
- );
- }
+ _getButtonInfo: function (buttonEl) {
+ const bgColor = buttonEl.style.backgroundColor;
+ const cssColor = bgColor ? ColorpickerDialog.normalizeCSSColor(bgColor) : (this.options.colorPrefix + buttonEl.dataset.color);
+ return {
+ cssColor: cssColor,
+ isClass: !!buttonEl.dataset.color,
+ target: buttonEl,
+ };
},
//--------------------------------------------------------------------------
@@ -236,14 +234,10 @@ const ColorPaletteWidget = Widget.extend({
* @param {Event} ev
*/
_onColorButtonClick: function (ev) {
- const target = ev.currentTarget;
+ const buttonEl = ev.currentTarget;
this.$('button.selected').removeClass('selected');
- $(target).addClass('selected');
- this.trigger_up('color_picked', {
- cssColor: target.style.backgroundColor || this.options.colorPrefix + target.dataset.color,
- isClass: !!target.dataset.color,
- target: ev.target,
- });
+ $(buttonEl).addClass('selected');
+ this.trigger_up('color_picked', this._getButtonInfo(buttonEl));
},
/**
* Called when a color button is entered.
@@ -253,12 +247,7 @@ const ColorPaletteWidget = Widget.extend({
*/
_onColorButtonEnter: function (ev) {
ev.stopPropagation();
- const target = ev.currentTarget;
- this.trigger_up('color_hover', {
- cssColor: target.style.backgroundColor || this.options.colorPrefix + target.dataset.color,
- isClass: !!target.dataset.color,
- target: ev.target,
- });
+ this.trigger_up('color_hover', this._getButtonInfo(ev.currentTarget));
},
/**
* Called when a color button is left.
@@ -268,19 +257,17 @@ const ColorPaletteWidget = Widget.extend({
*/
_onColorButtonLeave: function (ev) {
ev.stopPropagation();
- let params = {
- cssColor: '',
- isClass: false,
- target: ev.target,
- };
const selected = this.el.querySelector('button.selected');
+ let params = null;
if (selected) {
+ params = this._getButtonInfo(selected);
+ } else {
params = {
- cssColor: selected.style.backgroundColor || this.options.colorPrefix + selected.dataset.color,
- isClass: !!selected.dataset.color,
- target: ev.target,
+ cssColor: '',
+ isClass: false,
};
}
+ params.target = ev.target;
this.trigger_up('color_leave', params);
},
/**
@@ -302,17 +289,17 @@ const ColorPaletteWidget = Widget.extend({
* @param {Event} ev
*/
_onCustomColorButtonClick: async function (ev) {
- const originalEvent = ev;
- const $selected = this.$('button.selected');
- const colorpicker = new ColorPickerDialog(this, {
+ const target = ev.target;
+ const $selected = this.$('button.selected').removeClass('selected');
+ const colorpicker = new ColorpickerDialog(this, {
defaultColor: this.options.defaultColor || $selected.css('background-color'),
});
colorpicker.on('colorpicker:saved', this, ev => {
- $selected.removeClass('selected');
this._addCustomColorButton(ev.data.cssColor, ['selected']);
- this.trigger_up('custom_color_picked', {
+ this.trigger_up('color_picked', {
cssColor: ev.data.cssColor,
- target: originalEvent.target,
+ isClass: false,
+ target: target,
});
});
colorpicker.open();