diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorIntermediateNodeWriter.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorIntermediateNodeWriter.cs index 3901555366..dd5b10580e 100644 --- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorIntermediateNodeWriter.cs +++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorIntermediateNodeWriter.cs @@ -220,17 +220,17 @@ namespace Microsoft.AspNetCore.Blazor.Razor case HtmlTokenType.EndTag: { var nextTag = nextToken.AsTag(); - var isComponent = false; + var tagNameOriginalCase = GetTagNameWithOriginalCase(originalHtmlContent, nextTag); + var isComponent = TryGetComponentTypeNameFromTagName(tagNameOriginalCase, out var componentTypeName); + if (nextToken.Type == HtmlTokenType.StartTag) { - var tagNameOriginalCase = GetTagNameWithOriginalCase(originalHtmlContent, nextTag); - if (TryGetComponentTypeNameFromTagName(tagNameOriginalCase, out var componentTypeName)) + if (isComponent) { codeWriter .WriteStartMethodInvocation($"{builderVarName}.{nameof(RenderTreeBuilder.OpenComponent)}<{componentTypeName}>") .Write((_sourceSequence++).ToString()) .WriteEndMethodInvocation(); - isComponent = true; } else { @@ -304,7 +304,10 @@ namespace Microsoft.AspNetCore.Blazor.Razor } private static string GetTagNameWithOriginalCase(string document, HtmlTagToken tagToken) - => document.Substring(tagToken.Position.Position, tagToken.Name.Length); + { + var offset = tagToken.Type == HtmlTokenType.EndTag ? 1 : 0; // For end tags, skip the '/' + return document.Substring(tagToken.Position.Position + offset, tagToken.Name.Length); + } private bool TryGetComponentTypeNameFromTagName(string tagName, out string componentTypeName) { diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorCompilerTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorCompilerTest.cs index f6ed94ed04..597ba8cd5d 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorCompilerTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/RazorCompilerTest.cs @@ -371,7 +371,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test // Assert Assert.Collection(frames, - frame => AssertFrame.Component(frame, 0)); + frame => AssertFrame.Component(frame, 1, 0)); } [Fact] @@ -398,7 +398,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test // This problem will probably go away on its own when we have new component // tooling. Assert.Collection(frames, - frame => AssertFrame.Component(frame, 0), + frame => AssertFrame.Component(frame, 4, 0), frame => AssertFrame.Attribute(frame, "intproperty", "123", 1), frame => AssertFrame.Attribute(frame, "stringproperty", "My string", 2), frame => @@ -408,6 +408,26 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test }); } + [Fact] + public void CanIncludeChildrenInComponents() + { + // Arrange/Act + var testComponentTypeName = typeof(TestComponent).FullName.Replace('+', '.'); + var component = CompileToComponent($"" + + $"Some text" + + $"Nested text" + + $""); + var frames = GetRenderTree(component); + + Assert.Collection(frames, + frame => AssertFrame.Component(frame, 6, 0), + frame => AssertFrame.Attribute(frame, "attr", "abc", 1), + frame => AssertFrame.Text(frame, "Some text", 2), + frame => AssertFrame.Element(frame, "some-child", 3, 3), + frame => AssertFrame.Attribute(frame, "a", "1", 4), + frame => AssertFrame.Text(frame, "Nested text", 5)); + } + [Fact] public void ComponentsDoNotHaveLayoutAttributeByDefault() { diff --git a/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs b/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs index bb44087497..f94ee50ac4 100644 --- a/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs @@ -739,8 +739,8 @@ namespace Microsoft.AspNetCore.Blazor.Test Assert.Equal(1, entry.ReferenceFrameIndex); }, entry => AssertEdit(entry, RenderTreeEditType.StepOut, 0)); - AssertFrame.ComponentWithInstance(renderBatch.ReferenceFrames.Array[0], 0, 12); - AssertFrame.ComponentWithInstance(renderBatch.ReferenceFrames.Array[1], 1, 13); + AssertFrame.ComponentWithInstance(renderBatch.ReferenceFrames.Array[0], 0, null, 12); + AssertFrame.ComponentWithInstance(renderBatch.ReferenceFrames.Array[1], 1, null, 13); } [Fact] diff --git a/test/shared/AssertFrame.cs b/test/shared/AssertFrame.cs index d1d00d72b5..6bf79c29b2 100644 --- a/test/shared/AssertFrame.cs +++ b/test/shared/AssertFrame.cs @@ -58,16 +58,20 @@ namespace Microsoft.AspNetCore.Blazor.Test.Helpers Assert.Equal(attributeValue, frame.AttributeValue); } - public static void Component(RenderTreeFrame frame, int? sequence = null) where T : IComponent + public static void Component(RenderTreeFrame frame, int? subtreeLength = null, int? sequence = null) where T : IComponent { Assert.Equal(RenderTreeFrameType.Component, frame.FrameType); Assert.Equal(typeof(T), frame.ComponentType); + if (subtreeLength.HasValue) + { + Assert.Equal(subtreeLength.Value, frame.ComponentSubtreeLength); + } AssertFrame.Sequence(frame, sequence); } - public static void ComponentWithInstance(RenderTreeFrame frame, int componentId, int? sequence = null) where T : IComponent + public static void ComponentWithInstance(RenderTreeFrame frame, int componentId, int? subtreeLength = null, int? sequence = null) where T : IComponent { - AssertFrame.Component(frame, sequence); + AssertFrame.Component(frame, subtreeLength, sequence); Assert.IsType(frame.Component); Assert.Equal(componentId, frame.ComponentId); }