From 16490ec8ad1cf9963e95c8e132b51d1619f01841 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Wed, 18 Sep 2024 17:59:31 +0200 Subject: [PATCH] Html attributes (#202) * Fix strictness. * Improve rendering in non-async context --- Directory.Build.props | 2 +- .../Components/AttributeSelectorComponent.cs | 2 +- .../Components/HtmlAttributeComponent.cs | 2 +- .../Components/HtmlAttributesComponent.cs | 2 +- Mjml.Net/GlobalContext.cs | 9 ++---- Mjml.Net/MjmlRenderContext.cs | 5 ++-- Mjml.Net/MjmlRenderer.cs | 10 +++---- Tests/Components/HtmlAttributesTests.cs | 29 +++++++++++++++++++ Tests/HtmlExtensionsTests.cs | 2 +- Tests/HtmlRenderTests.cs | 2 +- 10 files changed, 46 insertions(+), 19 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 78e29c7..013b84d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,6 +12,6 @@ https://github.com/SebastianStehle/mjml-net.git git snupkg - 4.0.0 + 4.1.0 diff --git a/Mjml.Net.PostProcessors/Components/AttributeSelectorComponent.cs b/Mjml.Net.PostProcessors/Components/AttributeSelectorComponent.cs index 5269f4b..e4e06e2 100644 --- a/Mjml.Net.PostProcessors/Components/AttributeSelectorComponent.cs +++ b/Mjml.Net.PostProcessors/Components/AttributeSelectorComponent.cs @@ -18,7 +18,7 @@ public partial class SelectorComponent : Component public override void Render(IHtmlRenderer renderer, GlobalContext context) { - if (!context.Options.HasProcessor()) + if (!context.Async || !context.Options.HasProcessor()) { return; } diff --git a/Mjml.Net.PostProcessors/Components/HtmlAttributeComponent.cs b/Mjml.Net.PostProcessors/Components/HtmlAttributeComponent.cs index 0374f5a..bcbacd9 100644 --- a/Mjml.Net.PostProcessors/Components/HtmlAttributeComponent.cs +++ b/Mjml.Net.PostProcessors/Components/HtmlAttributeComponent.cs @@ -21,7 +21,7 @@ public partial class HtmlAttributeComponent : Component public override void Render(IHtmlRenderer renderer, GlobalContext context) { - if (!context.Options.HasProcessor()) + if (!context.Async || !context.Options.HasProcessor()) { return; } diff --git a/Mjml.Net.PostProcessors/Components/HtmlAttributesComponent.cs b/Mjml.Net.PostProcessors/Components/HtmlAttributesComponent.cs index 9a92a73..99337cd 100644 --- a/Mjml.Net.PostProcessors/Components/HtmlAttributesComponent.cs +++ b/Mjml.Net.PostProcessors/Components/HtmlAttributesComponent.cs @@ -15,7 +15,7 @@ public partial class HtmlAttributesComponent : Component public override void Render(IHtmlRenderer renderer, GlobalContext context) { - if (!context.Options.HasProcessor()) + if (!context.Async || !context.Options.HasProcessor()) { return; } diff --git a/Mjml.Net/GlobalContext.cs b/Mjml.Net/GlobalContext.cs index 2f683ec..0a0bad2 100644 --- a/Mjml.Net/GlobalContext.cs +++ b/Mjml.Net/GlobalContext.cs @@ -14,18 +14,15 @@ public sealed class GlobalContext public Dictionary> AttributesByName => attributesByName; - public MjmlOptions Options { get; private set; } + public MjmlOptions Options { get; set; } + + public bool Async { get; set; } public IFileLoader? FileLoader { get => fileLoader ??= Options?.FileLoader?.Invoke(); } - public void SetOptions(MjmlOptions options) - { - Options = options; - } - public void Clear() { GlobalData.Clear(); diff --git a/Mjml.Net/MjmlRenderContext.cs b/Mjml.Net/MjmlRenderContext.cs index 3659604..b6dacee 100644 --- a/Mjml.Net/MjmlRenderContext.cs +++ b/Mjml.Net/MjmlRenderContext.cs @@ -19,13 +19,14 @@ public ValidationErrors Validate() return new ValidationErrors(errors); } - public void Setup(MjmlRenderer mjmlRenderer, MjmlOptions? mjmlOptions) + public void Setup(MjmlRenderer mjmlRenderer, bool isAsync, MjmlOptions? mjmlOptions) { this.mjmlRenderer = mjmlRenderer; this.mjmlOptions = mjmlOptions ??= new MjmlOptions(); // Reuse the context and therefore do not set them over the constructor. - context.SetOptions(mjmlOptions); + context.Options = mjmlOptions; + context.Async = isAsync; validationContext.Options = mjmlOptions; } diff --git a/Mjml.Net/MjmlRenderer.cs b/Mjml.Net/MjmlRenderer.cs index 3f3000f..4a289ab 100644 --- a/Mjml.Net/MjmlRenderer.cs +++ b/Mjml.Net/MjmlRenderer.cs @@ -106,7 +106,7 @@ public IMjmlRenderer ClearHelpers() /// public RenderResult Render(string mjml, MjmlOptions? options = null) { - return RenderCore(mjml, options).Result; + return RenderCore(mjml, false, options).Result; } /// @@ -118,7 +118,7 @@ public RenderResult Render(Stream mjml, MjmlOptions? options = null) /// public RenderResult Render(TextReader mjml, MjmlOptions? options = null) { - return RenderCore(mjml.ReadToEnd(), options).Result; + return RenderCore(mjml.ReadToEnd(), false, options).Result; } public async ValueTask RenderAsync(string mjml, MjmlOptions? options = null, @@ -147,7 +147,7 @@ private async ValueTask RenderCoreAsync(string mjml, MjmlOptions? CancellationToken ct) { #pragma warning disable MA0042 // Do not use blocking calls in an async method - var (result, actualOptions) = RenderCore(mjml, options); + var (result, actualOptions) = RenderCore(mjml, true, options); #pragma warning restore MA0042 // Do not use blocking calls in an async method if (actualOptions?.PostProcessors?.Length > 0 && !string.IsNullOrWhiteSpace(result.Html)) @@ -165,7 +165,7 @@ private async ValueTask RenderCoreAsync(string mjml, MjmlOptions? return result; } - private (RenderResult Result, MjmlOptions Options) RenderCore(string mjml, MjmlOptions? options) + private (RenderResult Result, MjmlOptions Options) RenderCore(string mjml, bool isAsync, MjmlOptions? options) { options ??= new MjmlOptions(); @@ -174,7 +174,7 @@ private async ValueTask RenderCoreAsync(string mjml, MjmlOptions? var context = DefaultPools.RenderContexts.Get(); try { - context.Setup(this, options); + context.Setup(this, isAsync, options); context.StartBuffer(); context.Read(reader, null, null); diff --git a/Tests/Components/HtmlAttributesTests.cs b/Tests/Components/HtmlAttributesTests.cs index c3a42c2..73f35c8 100644 --- a/Tests/Components/HtmlAttributesTests.cs +++ b/Tests/Components/HtmlAttributesTests.cs @@ -34,6 +34,35 @@ public async Task Should_render_attributes() AssertHelpers.HtmlFileAssert("Components.Outputs.HtmlAttributes.html", result); } + [Fact] + public void Should_not_render_attributes_in_sync_context() + { + var source = @" + + + + + 42 + + + + + +
+
+
+
+
+
+"; + + var (result, _) = TestHelper.Render(source, new MjmlOptions + { + PostProcessors = [AngleSharpPostProcessor.Default] + }, helpers: []); + + AssertHelpers.HtmlFileAssert("Components.Outputs.HtmlAttributeInvalid.html", result); + } [Fact] public async Task Should_render_selector_only() diff --git a/Tests/HtmlExtensionsTests.cs b/Tests/HtmlExtensionsTests.cs index f81d867..cfbff8a 100644 --- a/Tests/HtmlExtensionsTests.cs +++ b/Tests/HtmlExtensionsTests.cs @@ -15,7 +15,7 @@ public HtmlExtensionsTests() Beautify = true }; - sut.Setup(new MjmlRenderer(), options); + sut.Setup(new MjmlRenderer(), false, options); sut.StartBuffer(); } diff --git a/Tests/HtmlRenderTests.cs b/Tests/HtmlRenderTests.cs index 825cb62..7e36d8d 100644 --- a/Tests/HtmlRenderTests.cs +++ b/Tests/HtmlRenderTests.cs @@ -16,7 +16,7 @@ public HtmlRenderTests() Beautify = true }; - sut.Setup(new MjmlRenderer(), options); + sut.Setup(new MjmlRenderer(), false, options); sut.StartBuffer(); }