-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve css var's with their actual values? #339
Comments
I was able to inline the CSS variables with the following code - it's not perfect (expect issues if you mix using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using AngleSharp.Html;
using PreMailer.Net;
using System.Collections.Immutable;
using System.Text.RegularExpressions;
using AngleSharp.Html.Dom;
partial class EmailGenerationService
{
private readonly HtmlParser _htmlParser = new ();
private readonly CssParser _cssParser = new ();
public async Task<Stream> ToEmailReadyHtml(string htmlContent)
{
var result = PreMailer.Net.PreMailer.MoveCssInline(htmlContent, removeStyleElements: true, stripIdAndClassAttributes: true, removeComments: true);
var ms = new MemoryStream();
var streamWriter = new StreamWriter(ms);
InlineCssVariables(result.Html).ToHtml(streamWriter, HtmlMarkupFormatter.Instance);
await streamWriter.FlushAsync();
ms.Position = 0;
return ms;
}
private IHtmlDocument InlineCssVariables(string html)
{
var doc = _htmlParser.ParseDocument(html);
InlineCssVariables(doc.DocumentElement, ImmutableDictionary<string, string?>.Empty);
return doc;
}
private void InlineCssVariables(IElement documentElement, ImmutableDictionary<string, string?> cssVariables)
{
if (documentElement.GetAttribute("style") is string styles)
{
var styleProps = _cssParser.ParseStyleClass("inline", styles);
cssVariables = cssVariables.AddRange(
from cssStyle in styleProps.Attributes
where cssStyle.Style.StartsWith("--")
select new KeyValuePair<string, string?>(cssStyle.Style, Evaluate(cssStyle.Value))
);
foreach (var cssStyle in styleProps.Attributes.ToArray())
{
if (cssStyle.Style.StartsWith("--"))
{
styleProps.Attributes.Remove(cssStyle.Style);
continue;
}
var value = Evaluate(cssStyle.Value);
if (value == null)
styleProps.Attributes.Remove(cssStyle.Style);
else if (cssStyle.Value != value)
cssStyle.Value = value;
}
documentElement.SetAttribute("style", styleProps.ToString());
}
foreach (var elem in documentElement.Children)
InlineCssVariables(elem, cssVariables);
string? Evaluate(string value)
{
var match = CssVariableFunction().Match(value);
if (!match.Success)
return value;
return cssVariables.TryGetValue(match.Groups["varName"].Value, out var variableValue)
? variableValue
: match.Groups.TryGetValue("defaultValue", out var group) ? group.Value : null;
}
}
[GeneratedRegex("""var\((?<varName>--[^ ,]+)(, (?<defaultValue>.*))?\)""")]
private static partial Regex CssVariableFunction();
} |
Successfuly implemented the solution in our PreMailer wrapper class. Since we only use simple variables (not the more complex functions) for email layouts, I don't expect to run into issues (yet). Thanks for the code. |
Is there a way to resolve css variables into their actual values?
css
html
html > after inlining with PreMailer.net
Which doesn't work with web mail (at least Gmail because they strip html attributes).
Also current Bootstrap versions are now predominantly using css variables which only adds to this issue and a need to resolve the variables into their actual values.
Any guidance would be appreciated.
The text was updated successfully, but these errors were encountered: