diff --git a/addons/web_editor/static/src/js/common/utils.js b/addons/web_editor/static/src/js/common/utils.js index 1ed08a80792..61e8f648ee8 100644 --- a/addons/web_editor/static/src/js/common/utils.js +++ b/addons/web_editor/static/src/js/common/utils.js @@ -167,6 +167,26 @@ function _computeColorClasses(colorNames, prefix = 'bg-') { } return classes; } +/** + * @param {string} key + * @param {CSSStyleDeclaration} [htmlStyle] if not provided, it is computed + * @returns {string} + */ +function _getCSSVariableValue(key, htmlStyle) { + if (htmlStyle === undefined) { + htmlStyle = window.getComputedStyle(document.documentElement); + } + // Get trimmed value from the HTML element + let value = htmlStyle.getPropertyValue(`--${key}`).trim(); + // If it is a color value, it needs to be normalized + value = ColorpickerWidget.normalizeCSSColor(value); + // Normally scss-string values are "printed" single-quoted. That way no + // magic conversation is needed when customizing a variable: either save it + // quoted for strings or non quoted for colors, numbers, etc. However, + // Chrome has the annoying behavior of changing the single-quotes to + // double-quotes when reading them through getPropertyValue... + return value.replace(/"/g, "'"); +} return { CSS_SHORTHANDS: CSS_SHORTHANDS, @@ -178,5 +198,6 @@ return { areCssValuesEqual: _areCssValuesEqual, isColorCombinationName: _isColorCombinationName, computeColorClasses: _computeColorClasses, + getCSSVariableValue: _getCSSVariableValue, }; }); 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 285283f1fc8..daa53fb7dae 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -1198,9 +1198,7 @@ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({ const cssCompatible = this.options.dataAttributes.hasOwnProperty('cssCompatible'); if ((useCssColor || cssCompatible) && !ColorpickerWidget.isCSSColor(value)) { if (useCssColor) { - const style = window.getComputedStyle(document.documentElement); - value = style.getPropertyValue(`--${value}`).trim(); - value = ColorpickerWidget.normalizeCSSColor(value); + value = weUtils.getCSSVariableValue(value); } else { value = `var(--${value})`; } @@ -1840,8 +1838,7 @@ const SnippetOptionWidget = Widget.extend({ // At this point, the widget value is either a property/color name or // an actual css property value. If it is a property/color name, we will // apply a css variable as style value. - const htmlStyle = window.getComputedStyle(document.documentElement); - const htmlPropValue = htmlStyle.getPropertyValue('--' + widgetValue); + const htmlPropValue = weUtils.getCSSVariableValue(widgetValue); if (htmlPropValue) { widgetValue = `var(--${widgetValue})`; } @@ -2999,9 +2996,7 @@ const ImageHandlerOption = SnippetOptionWidget.extend({ */ _normalizeColor(color) { if (!ColorpickerWidget.isCSSColor(color)) { - const style = window.getComputedStyle(document.documentElement); - color = style.getPropertyValue('--' + color).trim(); - color = ColorpickerWidget.normalizeCSSColor(color); + color = weUtils.getCSSVariableValue(color); } return color; }, 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 5ed02d3a332..25e8dfa2835 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 @@ -115,7 +115,7 @@ const ColorPaletteWidget = Widget.extend({ } this.colorNames.push(colorName); if (!isCCName && !elem.classList.contains('d-none')) { - const color = ColorpickerWidget.normalizeCSSColor(this.style.getPropertyValue('--' + colorName).trim()); + const color = weUtils.getCSSVariableValue(colorName, this.style); this.colorToColorNames[color] = colorName; } }); @@ -125,7 +125,7 @@ const ColorPaletteWidget = Widget.extend({ if (this.options.selectedColor) { let selectedColor = this.options.selectedColor; if (compatibilityColorNames.includes(selectedColor)) { - selectedColor = this.style.getPropertyValue('--' + selectedColor).trim() || selectedColor; + selectedColor = weUtils.getCSSVariableValue(selectedColor, this.style) || selectedColor; } selectedColor = ColorpickerWidget.normalizeCSSColor(selectedColor); if (selectedColor !== 'rgba(0, 0, 0, 0)') { @@ -138,7 +138,7 @@ const ColorPaletteWidget = Widget.extend({ // Colorpicker let defaultColor = this.selectedColor; if (defaultColor && !ColorpickerWidget.isCSSColor(defaultColor)) { - defaultColor = ColorpickerWidget.normalizeCSSColor(this.style.getPropertyValue('--' + defaultColor).trim()); + defaultColor = weUtils.getCSSVariableValue(defaultColor, this.style); } this.colorPicker = new ColorpickerWidget(this, { defaultColor: defaultColor, @@ -175,8 +175,8 @@ const ColorPaletteWidget = Widget.extend({ }); }, }); - this.style.getPropertyValue(`--custom-colors`).trim().split(' ').forEach(v => { - const color = this.style.getPropertyValue(`--${v.substring(1, v.length - 1)}`).trim(); + weUtils.getCSSVariableValue('custom-colors', this.style).split(' ').forEach(v => { + const color = weUtils.getCSSVariableValue(v.substring(1, v.length - 1), this.style); if (ColorpickerWidget.isCSSColor(color)) { this._addCustomColor(existingColors, color); } @@ -201,7 +201,7 @@ const ColorPaletteWidget = Widget.extend({ return; } if (!ColorpickerWidget.isCSSColor(color)) { - color = this.style.getPropertyValue('--' + color).trim(); + color = weUtils.getCSSVariableValue(color, this.style); } const normColor = ColorpickerWidget.normalizeCSSColor(color); if (!existingColors.has(normColor)) { diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 9c405641cc7..981ca05e387 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -78,8 +78,8 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ */ start: async function () { const style = window.getComputedStyle(document.documentElement); - const nbFonts = parseInt(style.getPropertyValue('--number-of-fonts')); - const googleFontsProperty = style.getPropertyValue('--google-fonts').trim(); + const nbFonts = parseInt(weUtils.getCSSVariableValue('number-of-fonts', style)); + const googleFontsProperty = weUtils.getCSSVariableValue('google-fonts', style); this.googleFonts = googleFontsProperty ? googleFontsProperty.split(/\s*,\s*/g) : []; this.googleFonts = this.googleFonts.map(font => font.substring(1, font.length - 1)); // Unquote @@ -93,7 +93,7 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ const fontEl = document.createElement('we-button'); fontEl.classList.add(`o_we_option_font_${realFontNb}`); fontEl.dataset.variable = variable; - fontEl.dataset[methodName] = style.getPropertyValue(`--font-number-${realFontNb}`).trim(); + fontEl.dataset[methodName] = weUtils.getCSSVariableValue(`font-number-${realFontNb}`, style); fontEl.dataset.font = realFontNb; fontEls.push(fontEl); this.menuEl.appendChild(fontEl); @@ -196,7 +196,7 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ const values = {}; const style = window.getComputedStyle(document.documentElement); _.each(FontFamilyPickerUserValueWidget.prototype.fontVariables, variable => { - const value = style.getPropertyValue(`--${variable}`).trim(); + const value = weUtils.getCSSVariableValue(variable, style); if (value.substring(1, value.length - 1) === googleFont) { // If an element is using the google font being removed, reset // it to the theme default. @@ -303,11 +303,10 @@ options.Class.include({ return mostXmlIDsStr; // Need to return the exact same string as in possibleValues } case 'customizeWebsiteVariable': { - const style = window.getComputedStyle(document.documentElement); - return style.getPropertyValue('--' + params.variable).trim(); + return weUtils.getCSSVariableValue(params.variable); } case 'customizeWebsiteColor': { - return this._getCSSColorFromName(params.color); + return weUtils.getCSSVariableValue(params.color); } } return this._super(...arguments); @@ -392,16 +391,6 @@ options.Class.include({ }, }); }, - /** - * @private - * @param {string} colorName - * @returns {string} - */ - _getCSSColorFromName: function (colorName) { - const style = window.getComputedStyle(document.documentElement); - const color = style.getPropertyValue('--' + colorName).trim(); - return ColorpickerWidget.normalizeCSSColor(color); - }, /** * @private */ @@ -632,8 +621,8 @@ options.registry.Theme = options.Class.extend({ start: async function () { // Checks for support of the old color system const style = window.getComputedStyle(document.documentElement); - const supportOldColorSystem = style.getPropertyValue('--support-13-0-color-system').trim() === 'true'; - const hasCustomizedOldColorSystem = style.getPropertyValue('--has-customized-13-0-color-system').trim() === 'true'; + const supportOldColorSystem = weUtils.getCSSVariableValue('support-13-0-color-system', style) === 'true'; + const hasCustomizedOldColorSystem = weUtils.getCSSVariableValue('has-customized-13-0-color-system', style) === 'true'; this._showOldColorSystemWarning = supportOldColorSystem && hasCustomizedOldColorSystem; return this._super(...arguments); @@ -777,8 +766,7 @@ options.registry.Theme = options.Class.extend({ for (const widget of widgets) { if (widget.getMethodsNames().includes('customizeWebsiteVariable') && widget.getMethodsParams('customizeWebsiteVariable').variable === 'color-palettes-number') { - const style = window.getComputedStyle(document.documentElement); - const hasCustomizedColors = style.getPropertyValue('--has-customized-colors').trim(); + const hasCustomizedColors = weUtils.getCSSVariableValue('has-customized-colors'); if (hasCustomizedColors && hasCustomizedColors !== 'false') { return _t("Changing the color palette will reset all your color customizations, are you sure you want to proceed?"); } @@ -859,7 +847,7 @@ options.registry.Theme = options.Class.extend({ async _renderCustomXML(uiFragment) { const paletteSelectorEl = uiFragment.querySelector('[data-variable="color-palettes-number"]'); const style = window.getComputedStyle(document.documentElement); - const nbPalettes = parseInt(style.getPropertyValue('--number-of-color-palettes')); + const nbPalettes = parseInt(weUtils.getCSSVariableValue('number-of-color-palettes', style)); for (let i = 1; i <= nbPalettes; i++) { const btnEl = document.createElement('we-button'); btnEl.classList.add('o_palette_color_preview_button'); @@ -867,7 +855,7 @@ options.registry.Theme = options.Class.extend({ for (let c = 1; c <= 5; c++) { const colorPreviewEl = document.createElement('span'); colorPreviewEl.classList.add('o_palette_color_preview'); - const color = style.getPropertyValue(`--o-palette-${i}-o-color-${c}`).trim(); + const color = weUtils.getCSSVariableValue(`o-palette-${i}-o-color-${c}`, style); colorPreviewEl.style.backgroundColor = color; btnEl.appendChild(colorPreviewEl); } diff --git a/addons/website/static/src/snippets/s_chart/000.js b/addons/website/static/src/snippets/s_chart/000.js index 865190fc81b..2c67bd03612 100644 --- a/addons/website/static/src/snippets/s_chart/000.js +++ b/addons/website/static/src/snippets/s_chart/000.js @@ -2,6 +2,7 @@ odoo.define('website.s_chart', function (require) { 'use strict'; const publicWidget = require('web.public.widget'); +const weUtils = require('web_editor.utils'); const ChartWidget = publicWidget.Widget.extend({ selector: '.s_chart', @@ -131,7 +132,7 @@ const ChartWidget = publicWidget.Widget.extend({ if (!color) { return 'transparent'; } - return this.style.getPropertyValue(`--${color}`).trim() || color; + return weUtils.getCSSVariableValue(color, this.style) || color; }, }); diff --git a/addons/website/static/src/snippets/s_chart/options.js b/addons/website/static/src/snippets/s_chart/options.js index 6dd654fdf8c..a76a0a71f31 100644 --- a/addons/website/static/src/snippets/s_chart/options.js +++ b/addons/website/static/src/snippets/s_chart/options.js @@ -4,6 +4,7 @@ odoo.define('website.s_chart_options', function (require) { var core = require('web.core'); const {ColorpickerWidget} = require('web.Colorpicker'); var options = require('web_editor.snippets.options'); +const weUtils = require('web_editor.utils'); var _t = core._t; @@ -81,7 +82,7 @@ options.registry.InnerChart = options.Class.extend({ const color = el.dataset.backgroundColor || el.dataset.borderColor; if (color) { el.style.border = '2px solid'; - el.style.borderColor = ColorpickerWidget.isCSSColor(color) ? color : this.style.getPropertyValue(`--${color}`).trim(); + el.style.borderColor = ColorpickerWidget.isCSSColor(color) ? color : weUtils.getCSSVariableValue(color, this.style); } }); }, @@ -368,7 +369,7 @@ options.registry.InnerChart = options.Class.extend({ } }); customColors = customColors.filter((el, i, array) => { - return !this.style.getPropertyValue(`--${el}`) && array.indexOf(el) === i && el !== ''; // unique non class not transparent + return !weUtils.getCSSVariableValue(el, this.style) && array.indexOf(el) === i && el !== ''; // unique non class not transparent }); ev.data.onSuccess(customColors); }, diff --git a/addons/website/static/src/snippets/s_countdown/000.js b/addons/website/static/src/snippets/s_countdown/000.js index cdee6a0fd8a..9959f6680a4 100644 --- a/addons/website/static/src/snippets/s_countdown/000.js +++ b/addons/website/static/src/snippets/s_countdown/000.js @@ -4,6 +4,7 @@ odoo.define('website.s_countdown', function (require) { const {ColorpickerWidget} = require('web.Colorpicker'); const core = require('web.core'); const publicWidget = require('web.public.widget'); +const weUtils = require('web_editor.utils'); const qweb = core.qweb; const _t = core._t; @@ -75,8 +76,7 @@ const CountdownWidget = publicWidget.Widget.extend({ if (ColorpickerWidget.isCSSColor(color)) { return color; } - const style = window.getComputedStyle(document.documentElement); - return style.getPropertyValue('--' + color).trim(); + return weUtils.getCSSVariableValue(color); }, /** * Gets the time difference in seconds between now and countdown due date.