From fd5426943f565e403eaf03cee17ba5057e3cb85c Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Fri, 10 Aug 2018 16:11:16 -0700 Subject: [PATCH] Merge sibling nodes during markup block rewrite This change adds the ability to merge sibling nodes when possible during markup block rewriting. We retain that invariant that each markup block is a valid chunk of markup containing properly nested tags. We still haven't done any work to remove whitespace yet, so most of the cases where this comes into play right now will merge an element with its surrounding whitespace. --- .../HtmlBlockPass.cs | 71 ++++++++++++++++- .../RenderTree/RenderTreeFrame.cs | 3 + .../ComponentRenderingRazorIntegrationTest.cs | 66 ++++++++++++++++ .../RenderingRazorIntegrationTest.cs | 6 +- .../TestComponent.codegen.cs | 5 +- .../TestComponent.ir.txt | 4 +- .../TestComponent.mappings.txt | 4 +- .../Regression_772/TestComponent.codegen.cs | 7 +- .../Regression_772/TestComponent.ir.txt | 4 +- .../Regression_773/TestComponent.codegen.cs | 7 +- .../Regression_773/TestComponent.ir.txt | 4 +- .../TestComponent.codegen.cs | 5 +- .../TestComponent.ir.txt | 4 +- .../TestComponent.codegen.cs | 5 +- .../TestComponent.ir.txt | 4 +- .../HtmlBlockPassTest.cs | 76 ++++++++++++++++++- 16 files changed, 232 insertions(+), 43 deletions(-) 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);