From 6a9ec78e5572933872c4d891b11350d35f328aea Mon Sep 17 00:00:00 2001 From: Antoine Guenet Date: Tue, 3 May 2022 07:58:57 +0000 Subject: [PATCH] [FIX] mass_mailing, web_editor: ensure proper table dimensions (masonry) When fixing a row's max-width for responsivity, we need to get the parent table's width before manipulating it. Failure to do that caused issues with nested table dimensions. In addition, masonry's maze of nested tables required some extra styling in order to propagate alignment. task-2761098 Part-of: odoo/odoo#87962 --- addons/mass_mailing/views/assets.xml | 3 ++ .../static/src/js/backend/convert_inline.js | 47 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/addons/mass_mailing/views/assets.xml b/addons/mass_mailing/views/assets.xml index 35d7ead835a..5e40487e0fb 100644 --- a/addons/mass_mailing/views/assets.xml +++ b/addons/mass_mailing/views/assets.xml @@ -67,6 +67,9 @@ td > img:only-child { min-width: 100% !important; } + .o_desktop_h100 { + height: unset !important; + } } diff --git a/addons/web_editor/static/src/js/backend/convert_inline.js b/addons/web_editor/static/src/js/backend/convert_inline.js index ff751496a6c..5b6ae7d9d31 100644 --- a/addons/web_editor/static/src/js/backend/convert_inline.js +++ b/addons/web_editor/static/src/js/backend/convert_inline.js @@ -109,7 +109,13 @@ function bootstrapToTable($editable) { const editable = $editable.get(0); // First give all rows in columns a separate container parent. for (const rowInColumn of [...editable.querySelectorAll('.row')].filter(row => RE_COL_MATCH.test(row.parentElement.className))) { - _wrap(rowInColumn, 'div', 'o_fake_table'); + const previous = rowInColumn.previousElementSibling; + if (previous && previous.classList.contains('o_fake_table')) { + // If a container was already created there, append to it. + previous.append(rowInColumn); + } else { + _wrap(rowInColumn, 'div', 'o_fake_table'); + } } // These containers from the mass mailing masonry snippet require full @@ -126,9 +132,16 @@ function bootstrapToTable($editable) { masonryRow.parentElement.style.setProperty('height', '100%'); } + const containers = editable.querySelectorAll('.container, .container-fluid, .o_fake_table'); + // Capture the widths of the containers before manipulating it. + for (const container of containers) { + container.setAttribute('o-temp-width', _getWidth(container)); + } // Now convert all containers with rows to tables. - for (const container of [...editable.querySelectorAll('.container, .container-fluid, .o_fake_table')].filter(n => [...n.children].some(c => c.classList.contains('row')))) { - const containerWidth = _getWidth(container); + for (const container of [...containers].filter(n => [...n.children].some(c => c.classList.contains('row')))) { + // The width of the table was stored in a temporary attribute. Fetch it + // for use in `_applyColspan` and remove the attribute at the end. + const containerWidth = container.getAttribute('o-temp-width'); // TABLE const table = _createTable(container.attributes); @@ -256,6 +269,9 @@ function bootstrapToTable($editable) { tr.remove(); // row was cloned and inserted already } } + for (const table of editable.querySelectorAll('table')) { + table.removeAttribute('o-temp-width'); + } } /** * Convert Bootstrap cards to table structures. @@ -404,10 +420,31 @@ function enforceTablesResponsivity(editable) { for (const tr of editable.querySelectorAll('tr')) { tr.style.setProperty('width', '100%'); } - for (const td of editable.querySelectorAll('td[style*="max-width"]')) { + for (const td of editable.querySelectorAll('td[colspan]')) { td.setAttribute('width', '100%'); td.style.setProperty('width', '100%'); - td.style.setProperty('display', 'inline-block'); + td.style.setProperty('display', 'inline-block'); // Allow cells to wrap. + } + // Masonry has crazy nested tables that require some extra treatment. + for (const td of editable.querySelectorAll('.s_masonry_block td')) { + td.classList.toggle('o_desktop_h100', true); + td.style.setProperty('height', '100%'); + if ([...td.children].map(child => child.nodeName.toLowerCase()).includes('table')) { + td.style.setProperty('height', _getHeight(td.parentElement) + 'px'); + } else { + // Hack that makes vertical-align possible within an inline-block. + const wrapper = document.createElement('div'); + wrapper.style.setProperty('display', 'inline-block'); + for (const child of [...td.childNodes]) { + wrapper.append(child); + } + td.append(wrapper); + const centeringSpan = document.createElement('span'); + centeringSpan.style.setProperty('height', '100%'); + centeringSpan.style.setProperty('display', 'inline-block'); + centeringSpan.style.setProperty('vertical-align', 'middle'); + td.prepend(centeringSpan); + } } } /**