diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/HtmlBlockPass.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/HtmlBlockPass.cs index a7dd2bf318..b0c9979f09 100644 --- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/HtmlBlockPass.cs +++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/HtmlBlockPass.cs @@ -44,8 +44,59 @@ namespace Microsoft.AspNetCore.Blazor.Razor // Forcibly remove a node to prevent infinite loops. trees.RemoveAt(trees.Count - 1); - rewriteVisitor.Visit(reference.Node); - reference.Replace(new HtmlBlockIntermediateNode() + // We want to fold together siblings where possible. To do this, first we find + // the index of the node we're looking at now - then we need to walk backwards + // and identify a set of contiguous nodes we can merge. + var start = reference.Parent.Children.Count - 1; + for (; start >= 0; start--) + { + if (ReferenceEquals(reference.Node, reference.Parent.Children[start])) + { + break; + } + } + + // This is the current node. Check if the left sibling is always a candidate + // for rewriting. Due to the order we processed the nodes, we know that the + // left sibling is next in the list to process if it's a candidate. + var end = start; + while (start - 1 >= 0) + { + var candidate = reference.Parent.Children[start - 1]; + if (trees.Count == 0 || !ReferenceEquals(trees[trees.Count - 1].Node, candidate)) + { + // This means the we're out of nodes, or the left sibling is not in the list. + break; + } + + // This means that the left sibling is valid to merge. + start--; + + // Remove this since we're combining it. + trees.RemoveAt(trees.Count - 1); + } + + // As a degenerate case, don't bother rewriting an single HtmlContent node + // It doesn't add any value. + if (end - start == 0 && reference.Node is HtmlContentIntermediateNode) + { + continue; + } + + // Now we know the range of nodes to rewrite (end is inclusive) + var length = end + 1 - start; + while (length > 0) + { + // Keep using start since we're removing nodes. + var node = reference.Parent.Children[start]; + reference.Parent.Children.RemoveAt(start); + + rewriteVisitor.Visit(node); + + length--; + } + + reference.Parent.Children.Insert(start, new HtmlBlockIntermediateNode() { Content = rewriteVisitor.Builder.ToString(), }); @@ -138,14 +189,28 @@ namespace Microsoft.AspNetCore.Blazor.Razor public override void VisitHtml(HtmlContentIntermediateNode node) { + // We need to restore the state after processing this node. + // We might have found a leaf-block of HTML, but that shouldn't + // affect our parent's state. + var originalState = _foundNonHtml; + + _foundNonHtml = false; + if (node.HasDiagnostics) { // Treat node with errors as non-HTML _foundNonHtml = true; } - + // Visit Children base.VisitDefault(node); + + if (!_foundNonHtml) + { + Trees.Add(new IntermediateNodeReference(Parent, node)); + } + + _foundNonHtml = originalState |= _foundNonHtml; } public override void VisitToken(IntermediateToken node) diff --git a/src/Microsoft.AspNetCore.Blazor/RenderTree/RenderTreeFrame.cs b/src/Microsoft.AspNetCore.Blazor/RenderTree/RenderTreeFrame.cs index 3b89d16ba5..91a9a0c8f1 100644 --- a/src/Microsoft.AspNetCore.Blazor/RenderTree/RenderTreeFrame.cs +++ b/src/Microsoft.AspNetCore.Blazor/RenderTree/RenderTreeFrame.cs @@ -334,6 +334,9 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree case RenderTreeFrameType.Text: return $"Text: (seq={Sequence}, len=n/a) {EscapeNewlines(TextContent)}"; + case RenderTreeFrameType.Markup: + return $"Markup: (seq={Sequence}, len=n/a) {EscapeNewlines(TextContent)}"; + case RenderTreeFrameType.ElementReferenceCapture: return $"ElementReferenceCapture: (seq={Sequence}, len=n/a) {ElementReferenceCaptureAction}"; } diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs index 76b4b811ab..3350ba57bd 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs @@ -488,5 +488,71 @@ namespace Test frames, frame => AssertFrame.Text(frame, "Hi")); } + + // Integration test for HTML block rewriting + [Fact] + public void Render_HtmlBlock_Integration() + { + // Arrange + AdditionalSyntaxTrees.Add(Parse(@" +using Microsoft.AspNetCore.Blazor; +using Microsoft.AspNetCore.Blazor.Components; +namespace Test +{ + public class MyComponent : BlazorComponent + { + [Parameter] + RenderFragment ChildContent { get; set; } + } +} +")); + + var component = CompileToComponent(@" +@addTagHelper *, TestAssembly + + + + + +
+
@(""hi"")
+
+
+
@(""hi"")
+
+
+ +"); + + // Act + var frames = GetRenderTree(component); + + // Assert: component frames are correct + Assert.Collection( + frames, + frame => AssertFrame.Element(frame, "html", 9, 0), + frame => AssertFrame.Whitespace(frame, 1), + frame => AssertFrame.Markup(frame, "\n ", 2), + frame => AssertFrame.Element(frame, "body", 5, 3), + frame => AssertFrame.Whitespace(frame, 4), + frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 5), + frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 6), + frame => AssertFrame.Whitespace(frame, 16), + frame => AssertFrame.Whitespace(frame, 17)); + + // Assert: Captured ChildContent frames are correct + var childFrames = GetFrames((RenderFragment)frames[6].AttributeValue); + Assert.Collection( + childFrames, + frame => AssertFrame.Whitespace(frame, 7), + frame => AssertFrame.Markup(frame, "
\n ", 8), + frame => AssertFrame.Element(frame, "div", 2, 9), + frame => AssertFrame.Text(frame, "hi", 10), + frame => AssertFrame.Whitespace(frame, 11), + frame => AssertFrame.Markup(frame, "
\n
\n ", 12), + frame => AssertFrame.Element(frame, "div", 2, 13), + frame => AssertFrame.Text(frame, "hi", 14), + frame => AssertFrame.Markup(frame, "\n
\n ", 15)); + } } } diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RenderingRazorIntegrationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RenderingRazorIntegrationTest.cs index 654e8f2a7d..09312b0cb7 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/RenderingRazorIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/RenderingRazorIntegrationTest.cs @@ -175,9 +175,9 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test var frames = GetRenderTree(component); // Assert - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Start", 0), - frame => AssertFrame.Text(frame, "End", 1)); + Assert.Collection( + frames, + frame => AssertFrame.Markup(frame, "StartEnd", 0)); } [Fact] diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.codegen.cs index 072760b8c0..3b9e68efaa 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.codegen.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.codegen.cs @@ -19,11 +19,10 @@ namespace Test builder.AddAttribute(1, "SomeProp", "val"); builder.AddAttribute(2, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => { builder2.AddContent(3, "\n Some "); - builder2.AddMarkupContent(4, "further"); - builder2.AddContent(5, " content\n"); + builder2.AddMarkupContent(4, "further content\n"); } )); - builder.AddComponentReferenceCapture(6, (__value) => { + builder.AddComponentReferenceCapture(5, (__value) => { #line 2 "x:\dir\subdir\Test\TestComponent.cshtml" myInstance = (Test.MyComponent)__value; diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.ir.txt index f35669e7a8..a24b6860a7 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.ir.txt +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.ir.txt @@ -13,9 +13,7 @@ Document - ComponentExtensionNode - (31:1,0 [96] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent - Test.MyComponent HtmlContent - (76:1,45 [11] x:\dir\subdir\Test\TestComponent.cshtml) IntermediateToken - (76:1,45 [11] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n Some - HtmlBlock - - further - HtmlContent - (103:2,25 [10] x:\dir\subdir\Test\TestComponent.cshtml) - IntermediateToken - (103:2,25 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - content\n + HtmlBlock - - further content\n RefExtensionNode - (49:1,18 [10] x:\dir\subdir\Test\TestComponent.cshtml) - myInstance - Test.MyComponent ComponentAttributeExtensionNode - - SomeProp - HtmlContent - (71:1,40 [3] x:\dir\subdir\Test\TestComponent.cshtml) diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.mappings.txt index 5928e2d3b7..0c8c2b2eb6 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.mappings.txt +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Component_WithRef_WithChildContent/TestComponent.mappings.txt @@ -1,13 +1,13 @@ Source Location: (49:1,18 [10] x:\dir\subdir\Test\TestComponent.cshtml) |myInstance| -Generated Location: (1176:28,18 [10] ) +Generated Location: (1131:27,18 [10] ) |myInstance| Source Location: (143:5,12 [44] x:\dir\subdir\Test\TestComponent.cshtml) | private Test.MyComponent myInstance; | -Generated Location: (1430:38,12 [44] ) +Generated Location: (1385:37,12 [44] ) | private Test.MyComponent myInstance; | diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.codegen.cs index 7d5094f269..21d41c6240 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.codegen.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.codegen.cs @@ -16,10 +16,9 @@ namespace Test protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder) { base.BuildRenderTree(builder); - builder.AddMarkupContent(0, "

Hello, world!

"); - builder.AddContent(1, "\n\nWelcome to your new app.\n\n"); - builder.OpenComponent(2); - builder.AddAttribute(3, "Title", ""); + builder.AddMarkupContent(0, "

Hello, world!

\n\nWelcome to your new app.\n\n"); + builder.OpenComponent(1); + builder.AddAttribute(2, "Title", ""); builder.CloseComponent(); } #pragma warning restore 1998 diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.ir.txt index 238d257383..f9fe77c727 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.ir.txt +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_772/TestComponent.ir.txt @@ -11,9 +11,7 @@ Document - MethodDeclaration - - protected override - void - BuildRenderTree CSharpCode - IntermediateToken - - CSharp - base.BuildRenderTree(builder); - HtmlBlock - -

Hello, world!

- HtmlContent - (66:3,22 [32] x:\dir\subdir\Test\TestComponent.cshtml) - IntermediateToken - (66:3,22 [32] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\nWelcome to your new app.\n\n + HtmlBlock - -

Hello, world!

\n\nWelcome to your new app.\n\n ComponentExtensionNode - (98:7,0 [23] x:\dir\subdir\Test\TestComponent.cshtml) - SurveyPrompt - Test.SurveyPrompt ComponentAttributeExtensionNode - (119:7,21 [0] x:\dir\subdir\Test\TestComponent.cshtml) - Title - Title HtmlContent - (119:7,21 [0] x:\dir\subdir\Test\TestComponent.cshtml) diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.codegen.cs index 336eb6e0ec..a3c8ecaf8a 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.codegen.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.codegen.cs @@ -16,10 +16,9 @@ namespace Test protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder) { base.BuildRenderTree(builder); - builder.AddMarkupContent(0, "

Hello, world!

"); - builder.AddContent(1, "\n\nWelcome to your new app.\n\n"); - builder.OpenComponent(2); - builder.AddAttribute(3, "Title", "
Test!
"); + builder.AddMarkupContent(0, "

Hello, world!

\n\nWelcome to your new app.\n\n"); + builder.OpenComponent(1); + builder.AddAttribute(2, "Title", "
Test!
"); builder.CloseComponent(); } #pragma warning restore 1998 diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.ir.txt index 161232aae6..53347b0920 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.ir.txt +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/Regression_773/TestComponent.ir.txt @@ -11,9 +11,7 @@ Document - MethodDeclaration - - protected override - void - BuildRenderTree CSharpCode - IntermediateToken - - CSharp - base.BuildRenderTree(builder); - HtmlBlock - -

Hello, world!

- HtmlContent - (66:3,22 [32] x:\dir\subdir\Test\TestComponent.cshtml) - IntermediateToken - (66:3,22 [32] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\nWelcome to your new app.\n\n + HtmlBlock - -

Hello, world!

\n\nWelcome to your new app.\n\n ComponentExtensionNode - (98:7,0 [41] x:\dir\subdir\Test\TestComponent.cshtml) - SurveyPrompt - Test.SurveyPrompt ComponentAttributeExtensionNode - (119:7,21 [16] x:\dir\subdir\Test\TestComponent.cshtml) - Title - Title HtmlContent - (119:7,21 [16] x:\dir\subdir\Test\TestComponent.cshtml) diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.codegen.cs index c561840bfd..ef4a72a59e 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.codegen.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.codegen.cs @@ -15,9 +15,8 @@ namespace Test protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder) { base.BuildRenderTree(builder); - builder.AddMarkupContent(0, "

Hello

"); - builder.AddContent(1, "\n\n"); - builder.AddContent(2, "My value"); + builder.AddMarkupContent(0, "

Hello

\n\n"); + builder.AddContent(1, "My value"); } #pragma warning restore 1998 } diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.ir.txt index 580bbd8848..09cbbb151d 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.ir.txt +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithCSharpExpression/TestComponent.ir.txt @@ -10,8 +10,6 @@ Document - MethodDeclaration - - protected override - void - BuildRenderTree CSharpCode - IntermediateToken - - CSharp - base.BuildRenderTree(builder); - HtmlBlock - -

Hello

- HtmlContent - (14:0,14 [4] x:\dir\subdir\Test\TestComponent.cshtml) - IntermediateToken - (14:0,14 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n + HtmlBlock - -

Hello

\n\n CSharpExpression - (20:2,2 [10] x:\dir\subdir\Test\TestComponent.cshtml) IntermediateToken - (20:2,2 [10] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - "My value" diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.codegen.cs index 7cea719d6a..97bc6b5fa3 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.codegen.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.codegen.cs @@ -15,9 +15,8 @@ namespace Test protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder) { base.BuildRenderTree(builder); - builder.AddMarkupContent(0, "

Hello

"); - builder.AddContent(1, "\n\n"); - builder.OpenComponent(2); + builder.AddMarkupContent(0, "

Hello

\n\n"); + builder.OpenComponent(1); builder.CloseComponent(); } #pragma warning restore 1998 diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.ir.txt index ccd7057150..0c1c2c7c16 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.ir.txt +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/TrailingWhiteSpace_WithComponent/TestComponent.ir.txt @@ -10,7 +10,5 @@ Document - MethodDeclaration - - protected override - void - BuildRenderTree CSharpCode - IntermediateToken - - CSharp - base.BuildRenderTree(builder); - HtmlBlock - -

Hello

- HtmlContent - (45:1,14 [4] x:\dir\subdir\Test\TestComponent.cshtml) - IntermediateToken - (45:1,14 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n + HtmlBlock - -

Hello

\n\n ComponentExtensionNode - (49:3,0 [22] x:\dir\subdir\Test\TestComponent.cshtml) - SomeOtherComponent - Test.SomeOtherComponent diff --git a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/HtmlBlockPassTest.cs b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/HtmlBlockPassTest.cs index 34df7f97fc..402e93adc1 100644 --- a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/HtmlBlockPassTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/HtmlBlockPassTest.cs @@ -64,6 +64,76 @@ namespace Microsoft.AspNetCore.Blazor.Razor Assert.Equal(expected, block.Content, ignoreLineEndingDifferences: true); } + [Fact] + public void Execute_RewritesHtml_WithComment() + { + // Arrange + var document = CreateDocument(@"StartEnd"); + + var expected = NormalizeContent(@"StartEnd"); + + var documentNode = Lower(document); + + // Act + Pass.Execute(document, documentNode); + + // Assert + var block = documentNode.FindDescendantNodes().Single(); + Assert.Equal(expected, block.Content, ignoreLineEndingDifferences: true); + } + + [Fact] + public void Execute_RewritesHtml_MergesSiblings() + { + // Arrange + var document = CreateDocument(@" + + @(""Hi"")
+
+
@(""Hi"")
+"); + + var expected = NormalizeContent(@" +
+
+ "); + + var documentNode = Lower(document); + + // Act + Pass.Execute(document, documentNode); + + // Assert + var block = documentNode.FindDescendantNodes().Single(); + Assert.Equal(expected, block.Content, ignoreLineEndingDifferences: true); + } + + [Fact] + public void Execute_RewritesHtml_MergesSiblings_LeftEdge() + { + // Arrange + var document = CreateDocument(@" +
+
+
@(""Hi"")
+"); + + var expected = NormalizeContent(@" +
+
+ "); + + var documentNode = Lower(document); + + // Act + Pass.Execute(document, documentNode); + + // Assert + var block = documentNode.FindDescendantNodes().Single(); + Assert.Equal(expected, block.Content, ignoreLineEndingDifferences: true); + } + + [Fact] public void Execute_RewritesHtml_CSharpInAttributes() { @@ -75,7 +145,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor "); - var expected = NormalizeContent(@"
foo
"); + var expected = NormalizeContent("
foo
\n "); var documentNode = Lower(document); @@ -100,7 +170,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor "); - var expected = NormalizeContent(@"
rewriteme
"); + var expected = NormalizeContent("
rewriteme
\n "); var documentNode = Lower(document); @@ -248,7 +318,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor "); - var expected = NormalizeContent(@"
rewriteme
"); + var expected = NormalizeContent("
rewriteme
\n "); var documentNode = Lower(document);