0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-27 22:49:56 -05:00

🐛 Fixed Outlook incorrect text styling and ' appearing in email content (#13313)

refs https://github.com/TryGhost/Team/issues/1047

Rendering segmented emails uses `cheerio` to parse and re-render the html but this had a side-effect of converting the `$#39;` char code to the more modern `$apos;` code resulting in Outlook not understanding quotes inside inlined CSS and showing the raw char code if it appeared in the email contents.

- extracted our handling of the unsupported char codes from the main email html generation into a function so that it can be re-used when generating segmented html
This commit is contained in:
Kevin Ansfield 2021-09-17 08:39:29 +01:00 committed by GitHub
parent 191b313271
commit 02347aa788
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -15,6 +15,30 @@ const logging = require('@tryghost/logging');
const ALLOWED_REPLACEMENTS = ['first_name'];
// Format a full html document ready for email by inlining CSS, adjusting links,
// and performing any client-specific fixes
const formatHtmlForEmail = function formatHtmlForEmail(html) {
const juiceOptions = {inlinePseudoElements: true};
let juicedHtml = juice(html, juiceOptions);
// convert juiced HTML to a DOM-like interface for further manipulation
// happens after inlining of CSS so we can change element types without worrying about styling
const _cheerio = cheerio.load(juicedHtml);
// force all links to open in new tab
_cheerio('a').attr('target', '_blank');
// convert figure and figcaption to div so that Outlook applies margins
_cheerio('figure, figcaption').each((i, elem) => !!(elem.tagName = 'div'));
juicedHtml = _cheerio.html();
// Fix any unsupported chars in Outlook
juicedHtml = juicedHtml.replace(/'/g, ''');
return juicedHtml;
};
const getSite = () => {
const publicSettings = settingsCache.getPublic();
return Object.assign({}, publicSettings, {
@ -273,25 +297,9 @@ const serialize = async (postModel, options = {isBrowserPreview: false, apiVersi
htmlTemplate = htmlTemplate.replace('%recipient.unsubscribe_url%', previewUnsubscribeUrl);
}
// Inline css to style attributes, turn on support for pseudo classes.
const juiceOptions = {inlinePseudoElements: true};
let juicedHtml = juice(htmlTemplate, juiceOptions);
// convert juiced HTML to a DOM-like interface for further manipulation
// happens after inlining of CSS so we can change element types without worrying about styling
_cheerio = cheerio.load(juicedHtml);
// force all links to open in new tab
_cheerio('a').attr('target','_blank');
// convert figure and figcaption to div so that Outlook applies margins
_cheerio('figure, figcaption').each((i, elem) => !!(elem.tagName = 'div'));
juicedHtml = _cheerio.html();
// Fix any unsupported chars in Outlook
juicedHtml = juicedHtml.replace(/'/g, ''');
// Clean up any unknown replacements strings to get our final content
const {html, plaintext} = normalizeReplacementStrings({
html: juicedHtml,
html: formatHtmlForEmail(htmlTemplate),
plaintext: post.plaintext
});
@ -314,7 +322,8 @@ function renderEmailForSegment(email, memberSegment) {
$(node).removeAttr('data-gh-segment');
}
});
result.html = $.html();
result.html = formatHtmlForEmail($.html());
result.plaintext = htmlToPlaintext(result.html);
return result;