From 337c859ba296be954f22fc7e71563188b09aebb4 Mon Sep 17 00:00:00 2001 From: Antoine Guenet Date: Fri, 21 Apr 2023 08:22:56 +0000 Subject: [PATCH] [FIX] web_editor, mass_mailing: properly handle (responsive) images This addresses a series of issues regarding images, their responsive behavior and their alignment. opw-3244705 opw-3185231 X-original-commit: e20bc14e8860ce8f84eb5b0006ec67b708530161 Part-of: odoo/odoo#124465 --- .../data/mailing_data_templates.xml | 3 +- .../static/src/js/backend/convert_inline.js | 57 ++++++++++++++----- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/addons/mass_mailing/data/mailing_data_templates.xml b/addons/mass_mailing/data/mailing_data_templates.xml index 747a65fb725..79a2b852c51 100644 --- a/addons/mass_mailing/data/mailing_data_templates.xml +++ b/addons/mass_mailing/data/mailing_data_templates.xml @@ -80,7 +80,8 @@ td { max-width: inherit !important; } - td > img:only-child { + img:only-child:not(.img-fluid) { + object-fit: cover; min-width: 100% !important; } .o_desktop_h100 { 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 12e594146ae..ace2a33a145 100644 --- a/addons/web_editor/static/src/js/backend/convert_inline.js +++ b/addons/web_editor/static/src/js/backend/convert_inline.js @@ -654,20 +654,10 @@ async function toInline($editable, cssRules, $iframe) { } } } - - // Fix outlook image rendering bug (this change will be kept in both - // fields). - for (const attributeName of ['width', 'height']) { - const images = editable.querySelectorAll('img'); - for (const image of images) { - let value = image.getAttribute(attributeName) || (attributeName === 'height' && image.offsetHeight); - if (!value) { - value = attributeName === 'width' ? _getWidth(image) : _getHeight(image);; - } - image.setAttribute(attributeName, value); - image.style.setProperty(attributeName, value + 'px'); - }; - }; + // Fix card-img-top heights (must happen before we transform everything). + for (const imgTop of editable.querySelectorAll('.card-img-top')) { + imgTop.style.setProperty('height', _getHeight(imgTop) + 'px'); + } attachmentThumbnailToLinkImg($editable); fontToImg($editable); @@ -687,6 +677,27 @@ async function toInline($editable, cssRules, $iframe) { flattenBackgroundImages(editable); formatTables($editable); responsiveToStaticForOutlook(editable); + // Fix Outlook image rendering bug. + for (const attributeName of ['width', 'height']) { + const images = editable.querySelectorAll('img'); + for (const image of images) { + if (image.style[attributeName] !== 'auto') { + const value = image.getAttribute(attributeName) || + (attributeName === 'height' && image.offsetHeight); + (attributeName === 'width' ? _getWidth(image) : _getHeight(image)); + if (value) { + image.setAttribute(attributeName, value); + image.style.setProperty(attributeName, value + 'px'); + } + } + }; + }; + // Fix mx-auto on images in table cells. + for (const centeredImage of editable.querySelectorAll('td > img.mx-auto')) { + if (centeredImage.parentElement.children.length === 1) { + centeredImage.parentElement.style.setProperty('text-align', 'center'); + } + } // Remove contenteditable attributes [editable, ...editable.querySelectorAll('[contenteditable]')].forEach(node => node.removeAttribute('contenteditable')); @@ -799,6 +810,9 @@ function fontToImg($editable) { wrapper.style.setProperty('display', 'inline-block'); wrapper.append(image); font.before(wrapper); + if (font.classList.contains('mx-auto')) { + wrapper.parentElement.style.textAlign = 'center'; + } font.remove(); wrapper.style.setProperty('padding', padding); wrapper.style.setProperty('width', width + 'px'); @@ -1101,6 +1115,21 @@ function normalizeRem($editable, rootFontSize=16) { if (td.closest('.s_masonry_block')) { outlookTd.style.padding = 0; // Not sure why this is needed. } + // Outlook doesn't support left/right padding on images. When the image + // is the only child of its parent, apply said padding to the parent. + if (td.children.length === 1 && td.firstElementChild.nodeName === 'IMG') { + const tdComputedStyle = getComputedStyle(td); + for (const side of ['left', 'right']) { + if (td.firstElementChild.style.width === '100%') { + const prop = `padding-${side}`; + const imagePadding = +td.firstElementChild.style[prop].replace('px', ''); + if (imagePadding > 0) { + const tdPadding = +tdComputedStyle[prop].replace('px', '') || 0; + outlookTd.style[prop] = tdPadding + imagePadding + 'px'; + } + } + } + } // The opening tag of `outlookTd` is for Outlook. td.before(_createMso(outlookTd.outerHTML.replace('', ''))); // The opening tag of `td` is for the others.