diff --git a/PreMailer.Net/PreMailer.Net.Tests/CssElementStyleResolverTests.cs b/PreMailer.Net/PreMailer.Net.Tests/CssElementStyleResolverTests.cs index b505635..5f4ec29 100644 --- a/PreMailer.Net/PreMailer.Net.Tests/CssElementStyleResolverTests.cs +++ b/PreMailer.Net/PreMailer.Net.Tests/CssElementStyleResolverTests.cs @@ -22,5 +22,39 @@ public void GetAllStylesForElement() Assert.Equal("style", result.ElementAt(0).AttributeName); Assert.Equal("bgcolor", result.ElementAt(1).AttributeName); } + + [Fact] + public void GetAllStyles_PreservesImportantFlagsInInlineStyles() + { + var document = new HtmlParser().ParseDocument("
"); + var element = document.Body.FirstElementChild; + + var styleClass = new StyleClass(); + styleClass.Attributes["color"] = CssAttribute.FromRule("color: red"); + + var result = CssElementStyleResolver.GetAllStyles(element, styleClass); + + var styleAttribute = result.FirstOrDefault(a => a.AttributeName == "style"); + Assert.NotNull(styleAttribute); + Assert.Contains("font-weight: bold !important", styleAttribute.CssValue); + Assert.Contains("color: red", styleAttribute.CssValue); + } + + [Fact] + public void GetAllStyles_PreservesImportantFlagsWhenMergingStyles() + { + var document = new HtmlParser().ParseDocument("
"); + var element = document.Body.FirstElementChild; + + var styleClass = new StyleClass(); + styleClass.Attributes["font-weight"] = CssAttribute.FromRule("font-weight: normal"); + + var result = CssElementStyleResolver.GetAllStyles(element, styleClass); + + var styleAttribute = result.FirstOrDefault(a => a.AttributeName == "style"); + Assert.NotNull(styleAttribute); + Assert.Contains("font-weight: bold !important", styleAttribute.CssValue); + Assert.DoesNotContain("font-weight: normal", styleAttribute.CssValue); + } } } diff --git a/PreMailer.Net/PreMailer.Net.Tests/PreMailerTests.cs b/PreMailer.Net/PreMailer.Net.Tests/PreMailerTests.cs index 4db0e0e..9923ece 100644 --- a/PreMailer.Net/PreMailer.Net.Tests/PreMailerTests.cs +++ b/PreMailer.Net/PreMailer.Net.Tests/PreMailerTests.cs @@ -188,6 +188,23 @@ public void MoveCssInline_ImportantFlag_HonorsImportantFlagInline() Assert.Contains("
+.test { + color:red; + } + + +

test

+"; + + var premailedOutput = PreMailer.MoveCssInline(input); + + Assert.Contains("font-weight: bold !important", premailedOutput.Html); + } + [Fact] public void MoveCssInline_AbsoluteBackgroundUrl_ShouldNotBeCleanedAsComment() { diff --git a/PreMailer.Net/PreMailer.Net.Tests/StyleClassApplierTests.cs b/PreMailer.Net/PreMailer.Net.Tests/StyleClassApplierTests.cs index 8088bb3..1f40b34 100644 --- a/PreMailer.Net/PreMailer.Net.Tests/StyleClassApplierTests.cs +++ b/PreMailer.Net/PreMailer.Net.Tests/StyleClassApplierTests.cs @@ -58,7 +58,24 @@ public void ApplyInlineStylesWithoutImportant() var result = StyleClassApplier.ApplyAllStyles(elementDictionary); - Assert.Equal("
", result.ElementAt(0).Key.OuterHtml); + Assert.Equal("
", result.ElementAt(0).Key.OuterHtml); + } + + [Fact] + public void ApplyInlineStylesWithImportant() + { + var document = new HtmlParser().ParseDocument("
"); + + var clazz = new StyleClass(); + clazz.Attributes["color"] = CssAttribute.FromRule("color: #000"); + + var elementDictionary = new Dictionary { + {document.Body.FirstElementChild, clazz} + }; + + var result = StyleClassApplier.ApplyAllStyles(elementDictionary); + + Assert.Equal("
", result.ElementAt(0).Key.OuterHtml); } } } diff --git a/PreMailer.Net/PreMailer.Net/CssElementStyleResolver.cs b/PreMailer.Net/PreMailer.Net/CssElementStyleResolver.cs index 6d4f5c6..efc115c 100644 --- a/PreMailer.Net/PreMailer.Net/CssElementStyleResolver.cs +++ b/PreMailer.Net/PreMailer.Net/CssElementStyleResolver.cs @@ -8,19 +8,47 @@ public static class CssElementStyleResolver { private const string premailerAttributePrefix = "-premailer-"; - public static IEnumerable GetAllStyles(IElement domElement, StyleClass styleClass) + public static IEnumerable GetAllStyles(IElement domElement, StyleClass styleClass) + { + var attributeCssList = new List(); + var originalStyleAttr = domElement.Attributes["style"]; + + AddSpecialPremailerAttributes(attributeCssList, styleClass); + + var mergedStyleClass = new StyleClass(); + + if (styleClass.Attributes.Count > 0) { - var attributeCssList = new List(); - - AddSpecialPremailerAttributes(attributeCssList, styleClass); - - if (styleClass.Attributes.Count > 0) - attributeCssList.Add(new AttributeToCss { AttributeName = "style", CssValue = styleClass.ToString() }); - - attributeCssList.AddRange(CssStyleEquivalence.FindEquivalent(domElement, styleClass)); - - return attributeCssList; + mergedStyleClass.Merge(styleClass, true); + } + + if (originalStyleAttr != null) + { + var parser = new CssParser(); + var originalStyleClass = parser.ParseStyleClass("inline", originalStyleAttr.Value); + + foreach (var attr in originalStyleClass.Attributes) + { + if (attr.Important) + { + mergedStyleClass.Attributes.Merge(attr); + } + else if (!mergedStyleClass.Attributes.TryGetValue(attr.Style, out var existing) || !existing.Important) + { + mergedStyleClass.Attributes.Merge(attr); + } + } } + + if (mergedStyleClass.Attributes.Count > 0) + { + attributeCssList.Add(new AttributeToCss { AttributeName = "style", CssValue = mergedStyleClass.ToString(emitImportant: true) }); + } + + attributeCssList.AddRange(CssStyleEquivalence.FindEquivalent(domElement, styleClass)); + + return attributeCssList; + } private static void AddSpecialPremailerAttributes(List attributeCssList, StyleClass styleClass) { @@ -44,4 +72,4 @@ private static void AddSpecialPremailerAttributes(List attribute } } } -} \ No newline at end of file +} diff --git a/PreMailer.Net/PreMailer.Net/PreMailer.cs b/PreMailer.Net/PreMailer.Net/PreMailer.cs index 34a402c..c259aa8 100644 --- a/PreMailer.Net/PreMailer.Net/PreMailer.cs +++ b/PreMailer.Net/PreMailer.Net/PreMailer.cs @@ -537,4 +537,4 @@ public void Dispose() _document.Dispose(); } } -} \ No newline at end of file +} diff --git a/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs b/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs index 930f7a1..96056be 100644 --- a/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs +++ b/PreMailer.Net/PreMailer.Net/StyleClassApplier.cs @@ -15,24 +15,24 @@ public static Dictionary ApplyAllStyles(Dictionary