Skip to content

Commit

Permalink
Additional handling in CssFormatter for transparent color cases (no h…
Browse files Browse the repository at this point in the history
…ex representation)
  • Loading branch information
Ryan Criddle committed Jun 29, 2022
1 parent 01e22fe commit 5e29212
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 22 deletions.
1 change: 1 addition & 0 deletions StyleMerge.Tests/InlinerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public InlinerTests()
[InlineData("ShouldApplyStylesForRulesWithMultipleSelectors")]
[InlineData("ShouldConvertColorRGBAToHex")]
[InlineData("ShouldDropTransparentBackgroundColor")]
[InlineData("ShouldDropInlineTransparentBackgroundColor")]
[InlineData("ShouldEliminateStyleBlocksWhereAllRulesAreInlined")]
[InlineData("ShouldEliminateScriptBlocks")]
[InlineData("ShouldKeepImportStylesInStyleBlocks")]
Expand Down
2 changes: 2 additions & 0 deletions StyleMerge.Tests/StyleMerge.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<None Remove="TestCases\ShouldApplyStylesAccordingToSpecificityValues\Input.html" />
<None Remove="TestCases\ShouldApplyStylesAccordingToSpecificityValues\Output.html" />
<None Remove="TestCases\ShouldApplyStylesForRulesWithMultipleSelectors\Input.html" />
<None Remove="TestCases\ShouldDropInlineTransparentBackgroundColor\Input.html" />
<None Remove="TestCases\ShouldDropInlineTransparentBackgroundColor\Output.html" />
<None Remove="TestCases\ShouldDropTransparentBackgroundColor\Input.html" />
<None Remove="TestCases\ShouldDropTransparentBackgroundColor\Output.html" />
<None Remove="TestCases\ShouldHandleBoxSizing\Input.html" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<head>
<style>
div {
background-color: rgba(255, 0, 0, 1);
background-color: rgba(255, 0, 0, 0.75);
}
</style>
</head>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<html>
<head>
<style>
table {
font-size: 14px;
}
</style>
</head>
<body>
<table style="background-color: transparent">
<tbody>
<tr><td>Table content</td></tr>
</tbody>
</table>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<html>
<head>
</head>
<body>
<table style="font-size: 14px">
<tbody>
<tr><td>Table content</td></tr>
</tbody>
</table>
</body>
</html>
24 changes: 20 additions & 4 deletions StyleMerge/CssFormatter.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using AngleSharp;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Values;
using AngleSharp.Text;

namespace StyleMerge
{
public class CssFormatter : IStyleFormatter
{
private const string RgbaPattern = @"rgba[(](\d{1,3})\s?,\s?(\d{1,3})\s?,\s?(\d{1,3})\s?,\s?(\d{1,3})[)]";
private const string RgbaPattern = @"rgba[(](\d{1,3})\s?,\s?(\d{1,3})\s?,\s?(\d{1,3}),\s?.*[)]";
private static readonly MatchEvaluator RgbaEvaluator = new MatchEvaluator(ReplaceRgba);

public string Declaration(string name, string value, bool important)
Expand All @@ -30,7 +33,7 @@ public string BlockDeclarations(IEnumerable<IStyleFormattable> declarations)

using (var writer = new StringWriter(sb))
{
foreach (var declaration in declarations)
foreach (var declaration in Filter(declarations))
{
writer.Write(Symbols.Space);
declaration.ToCss(writer, this);
Expand All @@ -55,7 +58,7 @@ public string BlockRules(IEnumerable<IStyleFormattable> rules)

using (var writer = new StringWriter(sb))
{
foreach (var rule in rules)
foreach (var rule in Filter(rules))
{
writer.Write(Symbols.Space);
rule.ToCss(writer, this);
Expand Down Expand Up @@ -89,7 +92,7 @@ public string Sheet(IEnumerable<IStyleFormattable> rules)

using (var writer = new StringWriter(sb))
{
foreach (var rule in rules)
foreach (var rule in Filter(rules))
{
rule.ToCss(writer, this);
writer.Write(sep);
Expand All @@ -112,5 +115,18 @@ private static string ReplaceRgba(Match match)

return $"#{r:X2}{g:X2}{b:X2}";
}

private IEnumerable<IStyleFormattable> Filter(IEnumerable<IStyleFormattable> rules)
=> rules.Where(x => !IsTransparentColor(x));

private static bool IsTransparentColor(IStyleFormattable rule)
{
// If alpha channel is completely transparent (ie. background: transparent), we don't render
// this rule since there is no compatible 6-digit hex representation ... including this rule
// *should* not be necessary anyway, it is probably redundant in most cases.
return rule is ICssProperty prop
&& prop.RawValue is Color color
&& color.Alpha == 0;
}
}
}
23 changes: 6 additions & 17 deletions StyleMerge/Inliner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using AngleSharp;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Parser;
using AngleSharp.Css.Values;
using AngleSharp.Dom;
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
Expand Down Expand Up @@ -176,25 +175,25 @@ private static void ApplyRulesToElements(IHtmlDocument document, IEnumerable<Rul

foreach (var rule in sortedRules)
{
var applyProps = rule.Properties.Where(x => ShouldApply(x));
if (!applyProps.Any())
continue;

try
{
// All elements except for those determined to not get styles.
foreach (var node in document.QuerySelectorAll(rule.Selector).Where(k => !noApply.Contains(k)))
{
var styles = CssParser.ParseDeclaration(node.GetAttribute("style") ?? string.Empty);

foreach (var prop in applyProps)
foreach (var prop in rule.Properties)
{
// TODO: We should probably lookup the existing property and only set it if it doesn't
// already exist. As things stand currently we are overwriting existing inline styles.
styles.SetProperty(prop.Name, prop.Value, prop.IsImportant ? "important" : null);
}

node.SetAttribute("style", styles.ToCss(CssFormatter));
var styleAttribute = styles.ToCss(CssFormatter);
if (!string.IsNullOrWhiteSpace(styleAttribute))
{
node.SetAttribute("style", styleAttribute);
}
}
}
catch (Exception ex)
Expand All @@ -203,15 +202,5 @@ private static void ApplyRulesToElements(IHtmlDocument document, IEnumerable<Rul
}
}
}

private static bool ShouldApply(ICssProperty x)
{
return !IsTransparentColor(x);
}

private static bool IsTransparentColor(ICssProperty prop)
{
return prop.RawValue is Color color && color.Alpha == 0;
}
}
}

0 comments on commit 5e29212

Please sign in to comment.