186 lines
6.3 KiB
TypeScript
186 lines
6.3 KiB
TypeScript
/** CSS injecté dans les iframes d’aperçu mail (sujet + corps). */
|
||
|
||
const DARK_TEXT = "#e8eaed"
|
||
const DARK_LINK = "#8ab4f8"
|
||
const LIGHT_TEXT = "#202124"
|
||
const LIGHT_LINK = "#1a73e8"
|
||
|
||
export function emailPreviewBaseCss(isDark: boolean): string {
|
||
return `
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
html {
|
||
color-scheme: ${isDark ? "dark" : "light"};
|
||
background: transparent !important;
|
||
}
|
||
html, body {
|
||
background: transparent !important;
|
||
overflow: hidden;
|
||
word-wrap: break-word;
|
||
overflow-wrap: break-word;
|
||
}
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
color: ${isDark ? DARK_TEXT : LIGHT_TEXT} !important;
|
||
padding: 0;
|
||
}
|
||
a, a * { color: ${isDark ? DARK_LINK : LIGHT_LINK} !important; }
|
||
img { max-width: 100%; height: auto; }
|
||
blockquote {
|
||
border-left: 3px solid ${isDark ? "#5f6368" : "#dadce0"};
|
||
padding-left: 12px;
|
||
margin: 8px 0;
|
||
color: ${isDark ? "#9aa0a6" : "#5f6368"} !important;
|
||
}
|
||
pre, code {
|
||
background: ${isDark ? "#3c4043" : "#f6f8fa"} !important;
|
||
color: ${isDark ? DARK_TEXT : LIGHT_TEXT} !important;
|
||
border-radius: 3px;
|
||
font-size: 13px;
|
||
}
|
||
pre { padding: 12px; overflow-x: auto; }
|
||
code { padding: 2px 6px; }
|
||
`
|
||
}
|
||
|
||
export function emailPreviewSubjectCss(isDark: boolean): string {
|
||
return `
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
html {
|
||
color-scheme: ${isDark ? "dark" : "light"};
|
||
background: transparent !important;
|
||
}
|
||
html, body {
|
||
background: transparent !important;
|
||
overflow: hidden;
|
||
white-space: normal;
|
||
word-wrap: break-word;
|
||
}
|
||
body {
|
||
font-family: 'Google Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
font-size: 22px;
|
||
line-height: 1.3;
|
||
color: ${isDark ? DARK_TEXT : LIGHT_TEXT} !important;
|
||
padding: 0;
|
||
}
|
||
`
|
||
}
|
||
|
||
/** Force le texte clair et fonds transparents sur le HTML d’e-mail en mode sombre. */
|
||
export function emailPreviewDarkOverrideCss(): string {
|
||
return `
|
||
:root { color-scheme: dark; }
|
||
|
||
body,
|
||
body div, body p, body span, body td, body th, body li, body font,
|
||
body h1, body h2, body h3, body h4, body h5, body h6,
|
||
body label, body strong, body b, body em, body i, body u,
|
||
body center, body table, body tbody, body thead, body tfoot, body tr {
|
||
color: ${DARK_TEXT} !important;
|
||
}
|
||
|
||
body a, body a * {
|
||
color: ${DARK_LINK} !important;
|
||
}
|
||
|
||
[bgcolor="#ffffff"], [bgcolor="#FFFFFF"], [bgcolor="white"],
|
||
[bgcolor="#f8f9fa"], [bgcolor="#F8F9FA"], [bgcolor="#f1f3f4"], [bgcolor="#F1F3F4"],
|
||
[bgcolor="#e8eaed"], [bgcolor="#E8EAED"], [bgcolor="#f6f8fc"], [bgcolor="#F6F8FC"],
|
||
[bgcolor="#fafafa"], [bgcolor="#FAFAFA"], [bgcolor="#eeeeee"], [bgcolor="#EEEEEE"],
|
||
[bgcolor="#fcfcfc"], [bgcolor="#FCFCFC"], [bgcolor="#fff"], [bgcolor="#FFF"] {
|
||
background-color: transparent !important;
|
||
background: transparent !important;
|
||
}
|
||
|
||
[color="#000000"], [color="#000"], [color="#111111"], [color="#202124"],
|
||
[color="#3c4043"], [color="#5f6368"], [color="#444746"], [color="#1f1f1f"],
|
||
[color="#333333"], [color="#333"], [color="#666666"], [color="#666"],
|
||
[color="#757575"], [color="#80868b"], [color="#9aa0a6"] {
|
||
color: ${DARK_TEXT} !important;
|
||
}
|
||
|
||
font[color] {
|
||
color: ${DARK_TEXT} !important;
|
||
}
|
||
|
||
[bgcolor="#000000"], [bgcolor="#000"], [bgcolor="#202124"], [bgcolor="#3c4043"],
|
||
[bgcolor="#1a1a1a"], [bgcolor="#2d2d2d"] {
|
||
background-color: #3c4043 !important;
|
||
}
|
||
|
||
div, td, th, p, span, li, h1, h2, h3, h4, h5, h6, table {
|
||
border-color: color-mix(in srgb, ${DARK_TEXT} 25%, transparent) !important;
|
||
}
|
||
`
|
||
}
|
||
|
||
/** Adoucit les fonds très sombres en mode clair (e-mails « dark »). */
|
||
export function emailPreviewLightOverrideCss(): string {
|
||
return `
|
||
[bgcolor="#000000"], [bgcolor="#000"], [bgcolor="#202124"], [bgcolor="#3c4043"],
|
||
[bgcolor="#1a1a1a"], [bgcolor="#2d2d2d"] {
|
||
background-color: #f1f3f4 !important;
|
||
}
|
||
|
||
[color="#ffffff"], [color="#FFFFFF"], [color="#e8eaed"], [color="#f8f9fa"],
|
||
[color="#dadce0"] {
|
||
color: ${LIGHT_TEXT} !important;
|
||
}
|
||
|
||
font[color="#ffffff"], font[color="#FFFFFF"], font[color="#e8eaed"] {
|
||
color: ${LIGHT_TEXT} !important;
|
||
}
|
||
`
|
||
}
|
||
|
||
const LIGHT_BG_STYLE =
|
||
/background(?:-color)?\s*:\s*(?:#(?:fff(?:fff)?|fefefe|f[ef][ef][ef](?:ff)?)|white|rgb\(\s*255\s*,\s*255\s*,\s*255\s*\)|rgba\(\s*255\s*,\s*255\s*,\s*255\s*,[^)]+\))/gi
|
||
|
||
const DARK_BG_STYLE =
|
||
/background(?:-color)?\s*:\s*(?:#(?:000(?:000)?|202124|3c4043|1a1a1a|2d2d2d)|black|rgb\(\s*0\s*,\s*0\s*,\s*0\s*\))/gi
|
||
|
||
/** Remplace ou supprime les couleurs de texte inline (pas background-color). */
|
||
const INLINE_COLOR_STYLE =
|
||
/(?<!background-)(?<!border-)color\s*:\s*(?:#[0-9a-f]{3,8}\b|rgb\(\s*[\d.,\s%]+\s*\)|rgba\(\s*[\d.,\s%]+\s*\)|[a-z]{3,20})\b/gi
|
||
|
||
const INLINE_BG_STYLE =
|
||
/background(?:-color)?\s*:\s*(?:#[0-9a-f]{3,8}\b|rgb\(\s*[\d.,\s%]+\s*\)|rgba\(\s*[\d.,\s%]+\s*\)|[a-z]{3,20})\b/gi
|
||
|
||
function rewriteStyleAttribute(styles: string, isDark: boolean): string {
|
||
let next = styles
|
||
if (isDark) {
|
||
next = next
|
||
.replace(INLINE_BG_STYLE, "background:transparent")
|
||
.replace(INLINE_COLOR_STYLE, `color:${DARK_TEXT}`)
|
||
} else {
|
||
next = next
|
||
.replace(DARK_BG_STYLE, "background:#f1f3f4")
|
||
.replace(
|
||
/(?<!background-)(?<!border-)color\s*:\s*(?:#(?:fff(?:fff)?|e8eaed|f8f9fa)|white|rgb\(\s*255\s*,)/gi,
|
||
`color:${LIGHT_TEXT}`
|
||
)
|
||
}
|
||
return next.replace(/;\s*;/g, ";").replace(/^;|;$/g, "").trim()
|
||
}
|
||
|
||
function rewriteInlineStyles(html: string, isDark: boolean): string {
|
||
return html.replace(
|
||
/\sstyle=(["'])([\s\S]*?)\1/gi,
|
||
(_match, quote: string, styles: string) => {
|
||
const rewritten = rewriteStyleAttribute(styles, isDark)
|
||
if (!rewritten) return ""
|
||
return ` style=${quote}${rewritten}${quote}`
|
||
}
|
||
)
|
||
}
|
||
|
||
export function preprocessEmailHtmlForTheme(html: string, isDark: boolean): string {
|
||
let next = rewriteInlineStyles(html, isDark)
|
||
if (isDark) {
|
||
next = next.replace(LIGHT_BG_STYLE, "background:transparent")
|
||
next = next.replace(/\sbgcolor=(["'])(?:#?(?:fff(?:fff)?|ffffff|white)|#f[0-9a-f]{5})\1/gi, "")
|
||
}
|
||
return next
|
||
}
|