diff --git a/PreMailer.Net/PreMailer.Net.Tests/Base64UrlTests.cs b/PreMailer.Net/PreMailer.Net.Tests/Base64UrlTests.cs new file mode 100644 index 0000000..1e8031f --- /dev/null +++ b/PreMailer.Net/PreMailer.Net.Tests/Base64UrlTests.cs @@ -0,0 +1,50 @@ +using System; +using Xunit; + +namespace PreMailer.Net.Tests +{ + public class Base64UrlTests + { + [Fact] + public void MoveCssInline_WithUnquotedBase64BackgroundImage_ShouldPreserveBase64Data() + { + string input = ""; + + var result = PreMailer.MoveCssInline(input); + + Assert.Contains("background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA)", result.Html); + Assert.Contains("background-repeat: no-repeat", result.Html); + } + + [Fact] + public void MoveCssInline_WithQuotedBase64BackgroundImage_ShouldPreserveBase64Data() + { + string input = ""; + + var result = PreMailer.MoveCssInline(input); + + Assert.Contains("background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA\")", result.Html); + Assert.Contains("background-repeat: no-repeat", result.Html); + } + + [Fact] + public void MoveCssInline_WithSvgXmlBackgroundImage_ShouldPreserveEncodedData() + { + string input = ""; + + var result = PreMailer.MoveCssInline(input); + + Assert.Contains("background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e\")", result.Html); + } + + [Fact] + public void MoveCssInline_WithBase64DataWithDoubleEquals_ShouldPreserveEnding() + { + string input = ""; + + var result = PreMailer.MoveCssInline(input); + + Assert.Contains("background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA==)", result.Html); + } + } +} diff --git a/PreMailer.Net/PreMailer.Net/CssParser.cs b/PreMailer.Net/PreMailer.Net/CssParser.cs index a9b0511..683b6ca 100644 --- a/PreMailer.Net/PreMailer.Net/CssParser.cs +++ b/PreMailer.Net/PreMailer.Net/CssParser.cs @@ -128,8 +128,8 @@ private static string CleanUp(string s) temp = Regex.Replace(temp, "(['\"])([^'\"\\\\]*(?:\\\\.[^'\"\\\\]*)*?)http://([^'\"]*?)\\1", m => m.Groups[1].Value + m.Groups[2].Value + "http:" + httpProtocolMarker + m.Groups[3].Value + m.Groups[1].Value); - temp = Regex.Replace(temp, "(data:[^;]+;base64,[^)\"']*?)//([^)\"']*)", m => - m.Groups[1].Value + dataUrlMarker + m.Groups[2].Value); + temp = Regex.Replace(temp, "(data:[^;]+;base64,)([^)\"']*?)//([^)\"']*)", m => + m.Groups[1].Value + m.Groups[2].Value + dataUrlMarker + m.Groups[3].Value); temp = _cssCommentRegex.Replace(temp, ""); temp = _unsupportedAtRuleRegex.Replace(temp, ""); @@ -141,6 +141,9 @@ private static string CleanUp(string s) temp = temp.Replace(httpProtocolMarker, "//"); temp = temp.Replace(dataUrlMarker, "//"); + temp = Regex.Replace(temp, @"url\s*\(\s*(['""]?)data:([^;]+);base64,([^)'""]*)(['""]?)\s*\)", m => + "url(" + m.Groups[1].Value + "data:" + m.Groups[2].Value + ";base64," + m.Groups[3].Value + m.Groups[4].Value + ")"); + return temp; } diff --git a/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs b/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs index 96056be..57a9e2c 100644 --- a/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs +++ b/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs @@ -47,8 +47,7 @@ private static void SetAttribute(IElement domElement, AttributeToCss attributeTo value = value.Replace("px", string.Empty); } - // Quotation marks in CSS is common, but when applied to the style attribute we will use single quotes instead. - if (value.Contains("\"")) + if (value.Contains("\"") && !(value.Contains("data:") && value.Contains(";base64,"))) { value = value.Replace("\"", "'"); }