DEV: deduplicate inline styles in emails (#30015)

In order to limit issues with duplicate inline CSS definitions, this will now deduplicate inline CSS styles with the "last-to-be-defined-wins" strategy.

Also removes unecessary whitespaces in inline styles.

Context - https://meta.discourse.org/t/resolve-final-styles-in-email-notifications/310219

Co-authored-by: Thomas Kalka <thomas.kalka@gmail.com>
This commit is contained in:
Régis Hanol
2024-11-30 16:38:45 +01:00
committed by GitHub
parent 20d46c9583
commit 7d58793759
4 changed files with 48 additions and 10 deletions

View File

@ -374,12 +374,31 @@ module Email
end
end
def deduplicate_style(style)
styles = {}
style
.split(";")
.select(&:present?)
.map { _1.split(":", 2).map(&:strip) }
.each { |k, v| styles[k] = v if k.present? && v.present? }
styles.map { |k, v| "#{k}:#{v}" }.join(";")
end
def deduplicate_styles
@fragment
.css("[style]")
.each { |element| element["style"] = deduplicate_style element["style"] }
end
def to_html
# needs to be before class + id strip because we need to style redacted
# media and also not double-redact already redacted from lower levels
replace_secure_uploads_urls if SiteSetting.secure_uploads?
strip_classes_and_ids
replace_relative_urls
deduplicate_styles
@fragment.to_html
end