From e13743ff2e3564e7e30c5a6088f5c6608847b224 Mon Sep 17 00:00:00 2001 From: Benjamin Vray Date: Thu, 8 Dec 2022 08:55:44 +0000 Subject: [PATCH] [FIX] web_editor, website: mitigate line between shapes issues This commit mitigates an issue with shape elements sometimes having tiny spacing on their top or bottom edge. This issue is mainly on Chrome when the user has changed the page zoom. When the page is zoomed the elements can have a width value with a decimal part. Because of it, the size of the SVG background images are not correctly rounded compared to their container and therefore leaves a visible space. Steps to reproduce the bug: - On Chrome, add several shapes on a website page. - Change the zoom of the page and change the window width. - At some points, the gap will appear. The least bad solution we found to fix this is to ensure that the width of the shape elements is always as close to an integer as possible. Reminder: several commits had attempted to fix this before ([1], [2], [3], [4]). But that wasn't enough to stop it happening. Some shapes still need to be fixed although that will likely be done in future versions. [1]: https://github.com/odoo/odoo/commit/c0f62593a4da37e8404dddc0a5762879a5ebbf7f [2]: https://github.com/odoo/odoo/commit/ac82407b259eab929486bf0a333a48bc507efa60 [3]: https://github.com/odoo/odoo/commit/42b3ad10e0b32b7fc72f801e2c67d6baf938c566 [4]: https://github.com/odoo/odoo/commit/e386f318f5cff50901dba3db8a2587911ba02a6e task-2824607 opw-3069213 opw-3057533 X-original-commit: 623db525e18931a4dd5794da78be840afc34991a Part-of: odoo/odoo#108228 --- .../static/src/js/editor/snippets.options.js | 9 +- .../src/js/content/snippets.animation.js | 83 +++++++++++++++++++ .../static/src/js/editor/snippets.options.js | 11 ++- 3 files changed, 101 insertions(+), 2 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 b3bca12b765..1244773ff3a 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -6757,7 +6757,7 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ const shapeContainer = target.querySelector(':scope > .o_we_shape'); if (shapeContainer) { - shapeContainer.remove(); + this._removeShapeEl(shapeContainer); } if (newContainer) { const preShapeLayerElement = this._getLastPreShapeLayerElement(); @@ -6855,6 +6855,13 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ this.prevShape = target.dataset.oeShapeData; } }, + /** + * @private + * @param {HTMLElement} shapeEl + */ + _removeShapeEl(shapeEl) { + shapeEl.remove(); + }, /** * Overwrites shape properties with the specified data. * diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index e2f0fc14569..1e1cde02534 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -1467,6 +1467,89 @@ registry.ImagesLazyLoading = publicWidget.Widget.extend({ }, }); +/** + * @todo while this solution mitigates the issue, it is not fixing it entirely + * but mainly, we should find a better solution than a JS solution as soon as + * one is available and ideally without having to make ugly patches to the SVGs. + * + * Due to a bug on Chrome when using browser zoom, there is sometimes a gap + * between sections with shapes. This gap is due to a rounding issue when + * positioning the SVG background images. This code reduces the rounding error + * by ensuring that shape elements always have a width value as close to an + * integer as possible. + * + * Note: a gap also appears between some shapes without zoom. This is likely + * due to error in the shapes themselves. Many things were done to try and fix + * this, but the remaining errors will likely be fixed with a review of the + * shapes in future Odoo versions. + * + * /!\ + * If a better solution for stable comes up, this widget behavior may be + * disabled, avoid depending on it if possible. + * /!\ + */ +registry.ZoomedBackgroundShape = publicWidget.Widget.extend({ + selector: '.o_we_shape', + disabledInEditableMode: false, + + /** + * @override + */ + start() { + this._onBackgroundShapeResize(); + this.throttledShapeResize = _.throttle(() => this._onBackgroundShapeResize(), 25); + window.addEventListener('resize', this.throttledShapeResize); + return this._super(...arguments); + }, + /** + * @override + */ + destroy() { + this._updateShapePosition(); + window.removeEventListener('resize', this.throttledShapeResize); + this._super(...arguments); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Updates the left and right offset of the shape. + * + * @private + * @param {string} offset + */ + _updateShapePosition(offset = '') { + this.el.style.left = offset; + this.el.style.right = offset; + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + */ + _onBackgroundShapeResize() { + this._updateShapePosition(); + // Get the decimal part of the shape element width. + let decimalPart = this.el.getBoundingClientRect().width % 1; + // Round to two decimal places. + decimalPart = Math.round((decimalPart + Number.EPSILON) * 100) / 100; + // If there is a decimal part. (e.g. Chrome + browser zoom enabled) + if (decimalPart > 0) { + // Compensate for the gap by giving an integer width value to the + // shape by changing its "right" and "left" positions. + let offset = (decimalPart < 0.5 ? decimalPart : decimalPart - 1) / 2; + // This never causes the horizontal scrollbar to appear because it + // only appears if the overflow to the right exceeds 0.333px. + this._updateShapePosition(offset + 'px'); + } + }, +}); + return { Widget: publicWidget.Widget, Animation: Animation, diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index daba07839f5..b716fc2fb37 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -936,7 +936,16 @@ options.registry.BackgroundShape.include({ return el; } return _getLastPreFilterLayerElement(this.$target); - } + }, + /** + * @override + */ + _removeShapeEl(shapeEl) { + this.trigger_up('widgets_stop_request', { + $target: $(shapeEl), + }); + return this._super(...arguments); + }, }); options.registry.ReplaceMedia.include({