From 11418cc6f0afcc8e14869f4f38ae0d6d462ac712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Souk=C3=A9ina=20Bojabza?= Date: Tue, 26 Sep 2023 15:26:33 +0200 Subject: [PATCH] [IMP] web_editor, website: add individual Padding option for grid items Before this commit, the "Padding" grid mode option, added in commit [1], was impacting all the grid items at the same time, which was not convenient since all these elements would have the same padding and could not be styled individually. This commit improves this option in order to modify the padding of the grid items individually. The highlight effect, added in commit [2], when changing the padding is still added. [1]: https://github.com/odoo/odoo/commit/cc406afcea7bf5846233a9f97a4a8ac5f618f3ec [2]: https://github.com/odoo/odoo/commit/f3f2c4c73ce08d3898b8c88e1ef045f7bbd1f624 task-3369695 Part-of: odoo/odoo#136683 --- .../static/src/js/common/grid_layout_utils.js | 42 ++++---- .../static/src/js/editor/snippets.options.js | 97 ++++++++++++------- .../static/src/scss/wysiwyg_snippets.scss | 2 +- addons/website/views/snippets/snippets.xml | 17 ++-- 4 files changed, 92 insertions(+), 66 deletions(-) diff --git a/addons/web_editor/static/src/js/common/grid_layout_utils.js b/addons/web_editor/static/src/js/common/grid_layout_utils.js index f403e56822c..4946327ce44 100644 --- a/addons/web_editor/static/src/js/common/grid_layout_utils.js +++ b/addons/web_editor/static/src/js/common/grid_layout_utils.js @@ -163,23 +163,23 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) { let zIndex = 1; const imageColumns = []; // array of boolean telling if it is a column with only an image. - // Checking if all the columns have a background color to take that into - // account when computing their size and padding (to make them look good). - const allBackgroundColor = [...columnEls].every(columnEl => columnEl.classList.contains('o_cc')); - for (const columnEl of columnEls) { // Finding out if the images are alone in their column. let isImageColumn = _checkIfImageColumn(columnEl); const imageEl = columnEl.querySelector('img'); + // Checking if the column has a background color to take that into + // account when computing its size and padding (to make it look good). + const hasBackgroundColor = columnEl.classList.contains("o_cc"); + const isImageWithoutPadding = isImageColumn && !hasBackgroundColor; // Placing the column. const style = window.getComputedStyle(columnEl); // Horizontal placement. - const columnLeft = isImageColumn ? imageEl.offsetLeft : columnEl.offsetLeft; + const columnLeft = isImageWithoutPadding ? imageEl.offsetLeft : columnEl.offsetLeft; // Getting the width of the column. const paddingLeft = parseFloat(style.paddingLeft); - const width = isImageColumn ? parseFloat(imageEl.scrollWidth) - : parseFloat(columnEl.scrollWidth) - (allBackgroundColor ? 0 : 2 * paddingLeft); + const width = isImageWithoutPadding ? parseFloat(imageEl.scrollWidth) + : parseFloat(columnEl.scrollWidth) - (hasBackgroundColor ? 0 : 2 * paddingLeft); let columnSpan = Math.round((width + columnGap) / (columnSize + columnGap)); if (columnSpan < 1) { columnSpan = 1; @@ -188,16 +188,16 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) { const columnEnd = columnStart + columnSpan; // Vertical placement. - const columnTop = isImageColumn ? imageEl.offsetTop : columnEl.offsetTop; + const columnTop = isImageWithoutPadding ? imageEl.offsetTop : columnEl.offsetTop; // Getting the top and bottom paddings and computing the row offset. const paddingTop = parseFloat(style.paddingTop); const paddingBottom = parseFloat(style.paddingBottom); const rowOffsetTop = Math.floor((paddingTop + rowGap) / (rowSize + rowGap)); // Getting the height of the column. - const height = isImageColumn ? parseFloat(imageEl.scrollHeight) - : parseFloat(columnEl.scrollHeight) - (allBackgroundColor ? 0 : paddingTop + paddingBottom); + const height = isImageWithoutPadding ? parseFloat(imageEl.scrollHeight) + : parseFloat(columnEl.scrollHeight) - (hasBackgroundColor ? 0 : paddingTop + paddingBottom); const rowSpan = Math.ceil((height + rowGap) / (rowSize + rowGap)); - const rowStart = Math.round(columnTop / (rowSize + rowGap)) + 1 + (allBackgroundColor || isImageColumn ? 0 : rowOffsetTop); + const rowStart = Math.round(columnTop / (rowSize + rowGap)) + 1 + (hasBackgroundColor || isImageWithoutPadding ? 0 : rowOffsetTop); const rowEnd = rowStart + rowSpan; columnEl.style.gridArea = `${rowStart} / ${columnStart} / ${rowEnd} / ${columnEnd}`; @@ -205,10 +205,13 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) { // Adding the grid classes. columnEl.classList.add('g-col-lg-' + columnSpan, 'g-height-' + rowSpan); - // Setting the initial z-index. columnEl.style.zIndex = zIndex++; - + // Setting the paddings. + if (hasBackgroundColor) { + columnEl.style.setProperty("--grid-item-padding-y", `${paddingTop}px`); + columnEl.style.setProperty("--grid-item-padding-x", `${paddingLeft}px`); + } // Reload the images. _reloadLazyImages(columnEl); @@ -217,17 +220,6 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) { imageColumns.push(isImageColumn); } - // If all the columns have a background color, set their padding to the - // original padding of the first column. - if (allBackgroundColor) { - const style = window.getComputedStyle(columnEls[0]); - const paddingY = style.paddingTop; - const paddingX = style.paddingLeft; - const rowEl = columnEls[0].parentNode; - rowEl.style.setProperty('--grid-item-padding-y', paddingY); - rowEl.style.setProperty('--grid-item-padding-x', paddingX); - } - for (const [i, columnEl] of [...columnEls].entries()) { // Removing padding and offset classes. const regex = /^(pt|pb|col-|offset-)/; @@ -304,6 +296,8 @@ export function _convertToNormalColumn(columnEl) { const gridSizeClasses = columnEl.className.match(/(g-col-lg|g-height)-[0-9]+/g); columnEl.classList.remove("o_grid_item", "o_grid_item_image", "o_grid_item_image_contain", ...gridSizeClasses); columnEl.style.removeProperty("z-index"); + columnEl.style.removeProperty("--grid-item-padding-x"); + columnEl.style.removeProperty("--grid-item-padding-y"); columnEl.style.removeProperty("grid-area"); } /** 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 29724dd2ccc..783886ff7a6 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -5111,15 +5111,6 @@ registry.Box = SnippetOptionWidget.extend({ registry.layout_column = SnippetOptionWidget.extend({ - /** - * @override - */ - cleanForSave() { - // Remove the padding highlights. - this.$target[0].querySelectorAll('.o_we_padding_highlight').forEach(highlightedEl => { - highlightedEl._removePaddingPreview(); - }); - }, //-------------------------------------------------------------------------- // Options @@ -5266,24 +5257,6 @@ registry.layout_column = SnippetOptionWidget.extend({ gridUtils._resizeGrid(rowEl); this.trigger_up('activate_snippet', {$snippet: $(newColumnEl)}); }, - /** - * @override - */ - async selectStyle(previewMode, widgetValue, params) { - await this._super(...arguments); - if (params.cssProperty.startsWith('--grid-item-padding')) { - // Reset the animations. - this._removePaddingPreview(); - void this.$target[0].offsetWidth; // Trigger a DOM reflow. - - // Highlight the padding when changing it, by adding a pseudo- - // element with an animated colored border inside the grid items. - const rowEl = this.$target[0]; - rowEl.classList.add('o_we_padding_highlight'); - rowEl._removePaddingPreview = this._removePaddingPreview.bind(this); - rowEl.addEventListener('animationend', rowEl._removePaddingPreview); - } - }, //-------------------------------------------------------------------------- // Private @@ -5381,10 +5354,18 @@ registry.layout_column = SnippetOptionWidget.extend({ * @private * @param {Element} rowEl */ - _toggleNormalMode(rowEl) { + async _toggleNormalMode(rowEl) { // Removing the grid class rowEl.classList.remove('o_grid_mode'); const columnEls = rowEl.children; + // Removing the grid previews (if any). + await new Promise(resolve => { + this.trigger_up("clean_ui_request", { + targetEl: this.$target[0].closest("section"), + onSuccess: resolve, + }); + }); + for (const columnEl of columnEls) { // Reloading the images. gridUtils._reloadLazyImages(columnEl); @@ -5393,20 +5374,70 @@ registry.layout_column = SnippetOptionWidget.extend({ } // Removing the grid properties. delete rowEl.dataset.rowCount; + // Kept for compatibility. rowEl.style.removeProperty('--grid-item-padding-x'); rowEl.style.removeProperty('--grid-item-padding-y'); }, +}); + +registry.GridColumns = SnippetOptionWidget.extend({ + /** + * @override + */ + cleanUI() { + // Remove the padding highlights. + this._removePaddingPreview(); + }, + + //-------------------------------------------------------------------------- + // Options + //-------------------------------------------------------------------------- + + /** + * @override + */ + async selectStyle(previewMode, widgetValue, params) { + await this._super(...arguments); + if (["--grid-item-padding-y", "--grid-item-padding-x"].includes(params.cssProperty)) { + // Reset the animation. + this._removePaddingPreview(); + void this.$target[0].offsetWidth; // Trigger a DOM reflow. + + // Highlight the padding when changing it, by adding a pseudo- + // element with an animated colored border inside the grid item. + this.options.wysiwyg.odooEditor.observerUnactive("addPaddingPreview"); + this.$target[0].classList.add("o_we_padding_highlight"); + this.options.wysiwyg.odooEditor.observerActive("addPaddingPreview"); + this.removePaddingPreview = this._removePaddingPreview.bind(this); + this.$target[0].addEventListener("animationend", this.removePaddingPreview); + } + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @override + */ + _computeWidgetVisibility(widgetName, params) { + if (["grid_padding_y_opt", "grid_padding_x_opt"].includes(widgetName)) { + return this.$target[0].parentElement.classList.contains("o_grid_mode"); + } + return this._super(...arguments); + }, /** * Removes the padding highlights that were added when changing the grid - * items padding. + * item padding. * * @private */ _removePaddingPreview() { - const rowEl = this.$target[0]; - rowEl.removeEventListener('animationend', rowEl._removePaddingPreview); - rowEl.classList.remove('o_we_padding_highlight'); - delete rowEl._removePaddingPreview; + this.options.wysiwyg.odooEditor.observerUnactive("removePaddingPreview"); + this.$target[0].removeEventListener("animationend", this.removePaddingPreview); + this.$target[0].classList.remove("o_we_padding_highlight"); + delete this.removePaddingPreview; + this.options.wysiwyg.odooEditor.observerActive("removePaddingPreview"); }, }); diff --git a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss index 3cbd03033fb..96a41587c49 100644 --- a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss +++ b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss @@ -2638,7 +2638,7 @@ we-button-group.o_grid we-selection-items { } } -.o_we_padding_highlight > .o_grid_item { +.o_we_padding_highlight.o_grid_item { position: relative; &::after { diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml index 4707d4c43f5..a0e147ce2b1 100644 --- a/addons/website/views/snippets/snippets.xml +++ b/addons/website/views/snippets/snippets.xml @@ -539,10 +539,6 @@ Text Button - - - - @@ -570,10 +566,6 @@ Text Button - - - - @@ -647,6 +639,15 @@ + +
+ + + + +
+