[FIX] web_editor, website: improve perf of color previews

Follow-up of [1].

After [2], color previews on the side panel would be changed by the
wysiwyg adapter. The adapter would add each block individually inside
the iframe and check its current styling to then add the style to the
color preview elements. This was performed many times (as color palettes
all have their own individual rendering of the color previews)
and slowed down the editor.

This commit improves that by relying on the copied variables introduced
at [3]. This removes the "re-render" of the color preview elements,
instead relying on styling rules and CSS variables which are initialized
when the editor is started.

[1]: https://github.com/odoo-dev/odoo/pull/1149#discussion_r900120846
[2]: https://github.com/odoo/odoo/commit/212a8bfdd21269b18054200b9e2585e1c95540d6
[3]: https://github.com/odoo/odoo/commit/a396f791da94d064d58cce15892e74f45d29b7b7

closes odoo/odoo#106366

X-original-commit: 7f5a9d040348048990b25c271875c77d2c314e4d
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Co-authored-by: qsm-odoo <qsm@odoo.com>
This commit is contained in:
Arthur Detroux (ard)
2022-11-24 11:08:39 +01:00
committed by qsm-odoo
co-authored by qsm-odoo
parent 0c8e158393
commit 0a83f41d59
7 changed files with 77 additions and 53 deletions
@@ -22,10 +22,12 @@ const EDITOR_COLOR_CSS_VARIABLES = [...COLOR_PALETTE_COMPATIBILITY_COLOR_NAMES];
for (let i = 1; i <= 5; i++) {
EDITOR_COLOR_CSS_VARIABLES.push(`o-color-${i}`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-bg`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-h1`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-headings`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-text`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-primary`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-primary-text`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-secondary`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-secondary-text`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-primary-border`);
EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-secondary-border`);
}
@@ -298,15 +298,6 @@ const ColorPaletteWidget = Widget.extend({
});
await this.colorPicker.appendTo(this.sections['custom-colors']);
}
// When the color palette is created outside its editing
// element, the theme preview might not reflect the styles
// of the editable. The parent widgets will update the styles
// accordingly.
if (!this.options.excluded.includes('theme')) {
this.trigger_up('update_color_previews', {
ccPreviewEls: this.el.querySelectorAll('.o_we_cc_preview_wrapper'),
});
}
return res;
},
/**
@@ -1362,6 +1362,11 @@ const Wysiwyg = Widget.extend({
for (const style of stylesToCopy) {
element.style.setProperty(`--we-cp-${style}`, weUtils.getCSSVariableValue(style));
}
element.classList.toggle('o_we_has_btn_outline_primary',
weUtils.getCSSVariableValue('btn-primary-outline') === 'true');
element.classList.toggle('o_we_has_btn_outline_secondary',
weUtils.getCSSVariableValue('btn-secondary-outline') === 'true');
},
/**
* Detached function to allow overriding.
@@ -53,6 +53,9 @@
$-btn-primary: map-get($colors, 'o-cc#{$index}-btn-primary');
@if not $-btn-primary {
@include print-variable('o-cc#{$index}-btn-primary', map-get($theme-colors, 'primary'));
@include print-variable('o-cc#{$index}-btn-primary-text', color-contrast(map-get($theme-colors, 'primary')));
} @else {
@include print-variable('o-cc#{$index}-btn-primary-text', color-contrast($-btn-primary));
}
@if not map-get($colors, 'o-cc#{$index}-btn-primary-border') {
@include print-variable('o-cc#{$index}-btn-primary-border', $-btn-primary or map-get($theme-colors, 'primary'));
@@ -61,6 +64,9 @@
$-btn-secondary: map-get($colors, 'o-cc#{$index}-btn-secondary');
@if not $-btn-secondary {
@include print-variable('o-cc#{$index}-btn-secondary', map-get($theme-colors, 'secondary'));
@include print-variable('o-cc#{$index}-btn-secondary-text', color-contrast(map-get($theme-colors, 'secondary')));
} @else {
@include print-variable('o-cc#{$index}-btn-secondary-text', color-contrast($-btn-secondary));
}
@if not map-get($colors, 'o-cc#{$index}-btn-secondary-border') {
@include print-variable('o-cc#{$index}-btn-secondary-border', $-btn-secondary or map-get($theme-colors, 'secondary'));
@@ -83,10 +83,62 @@
}
}
@mixin preview-outline-button($type, $ccIndex) {
.btn-#{$type} {
background-color: transparent;
color: var(--we-cp-o-cc#{$ccIndex}-btn-#{$type});
border-color: var(--we-cp-o-cc#{$ccIndex}-btn-#{$type});
}
.btn-#{$type}:hover {
background-color: var(--we-cp-o-cc#{$ccIndex}-btn-#{$type});
color: var(--we-cp-o-cc#{$ccIndex}-btn-#{$type}-text);
}
}
.o_w_wysiwyg, .o_loading_dummy {
#oe_snippets {
transform: none;
transition: none;
.o_we_cc_preview_wrapper {
@for $index from 1 through 5 {
&.o_cc#{$index} {
background-color: var(--we-cp-o-cc#{$index}-bg);
color: var(--we-cp-o-cc#{$index}-text);
h1 {
color: var(--we-cp-o-cc#{$index}-headings);
}
.btn-primary {
background-color: var(--we-cp-o-cc#{$index}-btn-primary);
color: var(--we-cp-o-cc#{$index}-btn-primary-text);
border-color: var(--we-cp-o-cc#{$index}-btn-primary);
}
.btn-secondary {
background-color: var(--we-cp-o-cc#{$index}-btn-secondary);
color: var(--we-cp-o-cc#{$index}-btn-secondary-text);
border-color: var(--we-cp-o-cc#{$index}-btn-secondary);
}
}
}
}
&.o_we_has_btn_outline_primary {
.o_we_cc_preview_wrapper {
@for $index from 1 through 5 {
&.o_cc#{$index} {
@include preview-outline-button('primary', $index)
}
}
}
}
&.o_we_has_btn_outline_secondary {
.o_we_cc_preview_wrapper {
@for $index from 1 through 5 {
&.o_cc#{$index} {
@include preview-outline-button('secondary', $index)
}
}
}
}
}
}
@@ -59,6 +59,10 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
if (this.websiteService.isDesigner && viewKey) {
switchableRelatedViews = this.rpc('/website/get_switchable_related_views', {key: viewKey});
}
// Set utils functions' editable window to the current iframe's window.
// This allows those function to access the correct styles definitions,
// document element, etc.
setEditableWindow(this.websiteService.contentWindow);
this.switchableRelatedViews = Promise.resolve(switchableRelatedViews);
});
@@ -89,17 +93,12 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
}
this.props.wysiwygReady();
this.widget.odooEditor.observerActive();
// Set utils functions' editable window to the current iframe's window.
// This allows those function to access the correct styles definitions,
// document element, etc.
setEditableWindow(this.websiteService.contentWindow);
};
initWysiwyg();
return () => {
this.$editable.off('click.odoo-website-editor', '*');
setEditableWindow(window);
};
}, () => []);
@@ -132,6 +131,7 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
if (this.dummyWidgetEl) {
this.dummyWidgetEl.remove();
document.body.classList.remove('editor_has_dummy_snippets');
setEditableWindow(window);
}
});
}
@@ -800,41 +800,14 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
},
});
}
/***
* Updates the Color Preview elements to reflect
* the colors that are inside the iframe.
* See the web_editor.color.combination.preview QWeb template.
/**
* Updates the panel so that color previews reflects the ones used by the
* edited content.
*
* @param event
* @param event.data.ccPreviewEls {HTMLElement} The color combination preview element.
* @private
*/
_onColorPreviewsUpdate(event) {
_onColorPreviewsUpdate() {
this.widget.setCSSVariables(this.widget.snippetsMenu.el);
const stylesToCopy = [
'background-color',
'border',
'color',
];
const copyStyles = (from, to) => {
const cloneStyle = this.websiteService.contentWindow.getComputedStyle(from);
for (const style of stylesToCopy) {
to.style.setProperty(style, cloneStyle.getPropertyValue(style));
}
};
for (const ccPreviewEl of event.data.ccPreviewEls) {
ccPreviewEl.setAttribute('style', '');
Object.values(ccPreviewEl.children).forEach(child => child.setAttribute('style', ''));
const iframeClone = ccPreviewEl.cloneNode(true);
this.websiteService.pageDocument.body.appendChild(iframeClone);
copyStyles(iframeClone, ccPreviewEl);
copyStyles(iframeClone.querySelector('h1'), ccPreviewEl.querySelector('h1'));
copyStyles(iframeClone.querySelector('.btn-primary'), ccPreviewEl.querySelector('.btn-primary'));
copyStyles(iframeClone.querySelector('.btn-secondary'), ccPreviewEl.querySelector('.btn-secondary'));
copyStyles(iframeClone.querySelector('p'), ccPreviewEl.querySelector('p'));
iframeClone.remove();
}
}
/**
* Update the context to trigger a mobile view.
@@ -1495,10 +1495,7 @@ options.registry.ThemeColors = options.registry.OptionsTab.extend({
*/
async updateUI() {
if (this.updateColorPreviews) {
const ccPreviewEls = this.el.querySelectorAll('.o_we_cc_preview_wrapper');
this.trigger_up('update_color_previews', {
ccPreviewEls,
});
this.trigger_up('update_color_previews');
this.updateColorPreviews = false;
}
await this._super(...arguments);
@@ -1552,9 +1549,7 @@ options.registry.ThemeColors = options.registry.OptionsTab.extend({
ccPreviewEls.push(ccPreviewEl);
presetCollapseEl.appendChild(collapseEl);
}
this.trigger_up('update_color_previews', {
ccPreviewEls,
});
this.trigger_up('update_color_previews');
await this._super(...arguments);
},
});