Skip to content

Instantly share code, notes, and snippets.

@jacobobryant
Created June 14, 2023 19:35
Show Gist options
  • Save jacobobryant/9ae87df0727de9e270df625d9a9ca95e to your computer and use it in GitHub Desktop.
Save jacobobryant/9ae87df0727de9e270df625d9a9ca95e to your computer and use it in GitHub Desktop.
Some javascript code I use for rendering emails in Yakread
// This assumes you have an element like <div id="post-content" data-contents="..."></div>,
// where data-contents has the html you'd like to render. Then call renderPost().
function $(selector) {
return document.querySelector(selector);
}
function renderPost() {
let element = $("#post-content");
let html = element.getAttribute('data-contents');
let options = {
USE_PROFILES: {
html: true,
svg: true,
},
ADD_ATTR: ["target"],
FORCE_BODY: true,
};
element.innerHTML = DOMPurify.sanitize(html, options);
updateMediaQueries();
scopePostCSS();
}
// Reverse engineered from Fastmail. This makes emails switch to mobile layout
// correctly. It seems to work most of the time.
function updateMediaQueries() {
let container = $("#post-content");
let offset = window.innerWidth - container.offsetWidth;
Array.from(document.styleSheets)
.filter(sheet => container.contains(sheet.ownerNode))
.flatMap(sheet => Array.from(sheet.cssRules))
.filter(rule => !!rule.media)
.forEach(rule => {
rule.media.mediaText = rule.media.mediaText.replace(
/-width: (\d+)px/, (_, width) => `-width: ${parseInt(width) + offset}px`
);
});
}
function scopeRule(rule) {
if (!!rule.selectorText) {
rule.selectorText = "#post-content " + rule.selectorText;
}
if (!!rule.cssRules) {
Array.from(rule.cssRules).forEach(scopeRule);
}
}
function scopePostCSS() {
let container = $("#post-content");
Array.from(document.styleSheets)
.filter(sheet => container.contains(sheet.ownerNode))
.flatMap(sheet => Array.from(sheet.cssRules))
.forEach(scopeRule);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment