/** Remove marketing preheader blocks before display (bluemonday strips display:none). */ const HIDDEN_STYLE = /display\s*:\s*none|mso-hide\s*:\s*all|max-height\s*:\s*0|opacity\s*:\s*0|font-size\s*:\s*0|visibility\s*:\s*hidden/i const HIDDEN_CLASS = /mcnPreviewText|preheader|preview-text/i const INVISIBLE_RUN = /[\u034f\u200b-\u200f\ufeff\u00a0]{4,}/g function shouldStripElement(el: Element): boolean { if (el.hasAttribute("hidden")) return true if (el.getAttribute("aria-hidden") === "true") return true const cls = el.className?.toString() ?? "" if (HIDDEN_CLASS.test(cls)) return true const style = el.getAttribute("style") ?? "" if (!style) return false const compact = style.replace(/\s+/g, "") return ( HIDDEN_STYLE.test(style) || (compact.includes("overflow:hidden") && /max-height\s*:\s*0/.test(style)) ) } export function stripHiddenEmailHtml(html: string): string { if (!html.trim() || typeof DOMParser === "undefined") { return html } try { const doc = new DOMParser().parseFromString(html, "text/html") const remove: Element[] = [] doc.body.querySelectorAll("*").forEach((el) => { if (shouldStripElement(el)) remove.push(el) }) for (const el of remove) el.remove() return doc.body.innerHTML } catch { return html } } export function stripInvisibleTextRuns(text: string): string { return text.replace(INVISIBLE_RUN, " ").replace(/\s+/g, " ").trim() }