diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/BlockKindInternal.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/BlockKindInternal.cs index c515770ca7..9f9886164c 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/BlockKindInternal.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/BlockKindInternal.cs @@ -18,6 +18,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Special Comment = 8, - Tag = 9 + Tag = 9, + + HtmlComment = 10 } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs index 4fdee1322f..332023b775 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs @@ -207,6 +207,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy if (last != null) { Accept(last); + if (At(HtmlSymbolType.OpenAngle) && last.Type == HtmlSymbolType.Text) + { + Output(SpanKindInternal.Markup); + } } } @@ -494,26 +498,34 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { if (CurrentSymbol.Type == HtmlSymbolType.DoubleHyphen) { - AcceptAndMoveNext(); - - Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; - while (!EndOfFile) + using (Context.Builder.StartBlock(BlockKindInternal.HtmlComment)) { - SkipToAndParseCode(HtmlSymbolType.DoubleHyphen); - if (At(HtmlSymbolType.DoubleHyphen)) + AcceptAndMoveNext(); + + Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + while (!EndOfFile) { - AcceptWhile(HtmlSymbolType.DoubleHyphen); - - if (At(HtmlSymbolType.Text) && - string.Equals(CurrentSymbol.Content, "-", StringComparison.Ordinal)) + SkipToAndParseCode(HtmlSymbolType.DoubleHyphen); + if (At(HtmlSymbolType.DoubleHyphen)) { - AcceptAndMoveNext(); - } + AcceptWhile(HtmlSymbolType.DoubleHyphen); - if (At(HtmlSymbolType.CloseAngle)) - { - AcceptAndMoveNext(); - return true; + if (At(HtmlSymbolType.Text) && + string.Equals(CurrentSymbol.Content, "-", StringComparison.Ordinal)) + { + AcceptAndMoveNext(); + } + + if (At(HtmlSymbolType.CloseAngle)) + { + // This is the end of a comment block + Accept(this.CurrentSymbol); + Output(SpanKindInternal.Markup); + + NextToken(); + //AcceptAndMoveNext(); + return true; + } } } } @@ -1476,6 +1488,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { AcceptAndMoveNext(); // Accept '<' BangTag(); + return; } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs index 930b928949..6cac8b46ea 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs @@ -488,7 +488,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy private void ValidateParentAllowsContent(Span child, ErrorSink errorSink) { - if (HasAllowedChildren() && !IsComment(child)) + if (HasAllowedChildren() && !IsComment(child) && child.Kind != SpanKindInternal.Transition && child.Kind != SpanKindInternal.Code) { var content = child.Content; if (!string.IsNullOrWhiteSpace(content)) @@ -817,14 +817,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return relevantSymbol.Type == HtmlSymbolType.ForwardSlash; } - private static bool IsComment(Span span) + internal static bool IsComment(Span span) { - bool isHtmlComment = span.Content?.StartsWith(""; + string commentOutput = ""; string expectedOutput = $"
{literal}{commentOutput}
"; var pTagHelperBuilder = TagHelperDescriptorBuilder @@ -1138,7 +1138,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy blockFactory.MarkupTagBlock(""), factory.Markup(literal), blockFactory.MarkupTagBlock(""), - factory.Markup(commentOutput))); + new HtmlCommentBlock(factory.Markup(commentOutput)))); // Act & Assert EvaluateData( @@ -1148,6 +1148,58 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Array.Empty{literal}
"; + + var pTagHelperBuilder = TagHelperDescriptorBuilder + .Create("PTagHelper", "SomeAssembly") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")); + foreach (var childTag in allowedChildren) + { + pTagHelperBuilder.AllowChildTag(childTag); + } + + var descriptors = new TagHelperDescriptor[] + { + pTagHelperBuilder.Build() + }; + + var factory = new SpanFactory(); + var blockFactory = new BlockFactory(factory); + + var expectedMarkup = new MarkupBlock( + new MarkupTagHelperBlock("p", + new HtmlCommentBlock(factory.Markup($"")), + factory.Markup(literal), + new HtmlCommentBlock(factory.Markup($"")))); + + // Act & Assert + EvaluateData( + descriptors, + expectedOutput, + expectedMarkup, + new[] + { + nestedContentError("p", "b", 15, 4), + }); + } + [Fact] public void Rewrite_AllowsRazorCommentsAsChildren() { @@ -1193,6 +1245,54 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Array.Empty{literal}{part1}@{part2}{part3}
"; + + var pTagHelperBuilder = TagHelperDescriptorBuilder + .Create("PTagHelper", "SomeAssembly") + .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p")); + foreach (var childTag in allowedChildren) + { + pTagHelperBuilder.AllowChildTag(childTag); + } + + var descriptors = new TagHelperDescriptor[] + { + pTagHelperBuilder.Build() + }; + + var factory = new SpanFactory(); + var blockFactory = new BlockFactory(factory); + + var expectedMarkup = new MarkupBlock( + new MarkupTagHelperBlock("p", + blockFactory.MarkupTagBlock(""), + factory.Markup(literal), + blockFactory.MarkupTagBlock(""), + new HtmlCommentBlock(factory.Markup(part1), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(part2) + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(part3)))); + + // Act & Assert + EvaluateData( + descriptors, + expectedOutput, + expectedMarkup, + Array.Empty