diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs index 332023b775..fc675b6e47 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs @@ -207,10 +207,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy if (last != null) { Accept(last); - if (At(HtmlSymbolType.OpenAngle) && last.Type == HtmlSymbolType.Text) - { - Output(SpanKindInternal.Markup); - } } } @@ -501,31 +497,57 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy using (Context.Builder.StartBlock(BlockKindInternal.HtmlComment)) { AcceptAndMoveNext(); + Output(SpanKindInternal.Markup, AcceptedCharactersInternal.None); - Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any; + Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.WhiteSpace; while (!EndOfFile) { SkipToAndParseCode(HtmlSymbolType.DoubleHyphen); if (At(HtmlSymbolType.DoubleHyphen)) { - AcceptWhile(HtmlSymbolType.DoubleHyphen); + var lastDoubleHyphen = CurrentSymbol; + AcceptWhile(s => + { + if (NextIs(HtmlSymbolType.DoubleHyphen)) + { + lastDoubleHyphen = s; + return true; + } + + NextToken(); + EnsureCurrent(); + return false; + }); if (At(HtmlSymbolType.Text) && string.Equals(CurrentSymbol.Content, "-", StringComparison.Ordinal)) { + // Doing this here to maintain the order of symbols + if (!NextIs(HtmlSymbolType.CloseAngle)) + { + Accept(lastDoubleHyphen); + lastDoubleHyphen = null; + } + AcceptAndMoveNext(); } if (At(HtmlSymbolType.CloseAngle)) { - // This is the end of a comment block - Accept(this.CurrentSymbol); - Output(SpanKindInternal.Markup); + // Output the content in the comment block as a separate markup + Output(SpanKindInternal.Markup, AcceptedCharactersInternal.WhiteSpace); + + // This is the end of a comment block + Accept(lastDoubleHyphen); + AcceptAndMoveNext(); + Output(SpanKindInternal.Markup, AcceptedCharactersInternal.None); - NextToken(); - //AcceptAndMoveNext(); return true; } + else if (lastDoubleHyphen != null) + { + Accept(lastDoubleHyphen); + } } } } @@ -1486,6 +1508,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Checking to see if we meet the conditions of a special '!' tag: ")), + BlockFactory.HtmlCommentBlock(" "), + Factory.EmptyHtml()), Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), Factory.EmptyHtml())); } @@ -630,7 +631,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( - Factory.Markup("")), + BlockFactory.HtmlCommentBlock(" > \" '"), + Factory.EmptyHtml()), Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), Factory.EmptyHtml())); } @@ -655,7 +657,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.Markup(Environment.NewLine), new MarkupTagBlock( Factory.Markup(" \" '-->")), + BlockFactory.HtmlCommentBlock(" > \" '"), + Factory.EmptyHtml()), Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), Factory.EmptyHtml())); } diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs index f54ba50d37..f8d4b0fcd9 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.Code(Environment.NewLine).AsStatement().AutoCompleteWith(null), new MarkupBlock( Factory.Markup(" "), - Factory.Markup("").Accepts(AcceptedCharactersInternal.None), + BlockFactory.HtmlCommentBlock(" Hello, I'm a comment that shouldn't break razor -"), Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)), Factory.EmptyCSharp().AsStatement(), Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), @@ -333,7 +333,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy [Fact] public void ParseBlockSupportsCommentAsBlock() { - SingleSpanBlockTest("", BlockKindInternal.Markup, SpanKindInternal.Markup, acceptedCharacters: AcceptedCharactersInternal.None); + ParseBlockTest("", new MarkupBlock( BlockFactory.HtmlCommentBlock(" foo "))); } [Fact] @@ -344,8 +344,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new MarkupTagBlock( Factory.Markup("").Accepts(AcceptedCharactersInternal.None)), Factory.Markup("bar"), - Factory.Markup("").Accepts(AcceptedCharactersInternal.None), - Factory.Markup("baz"), + BlockFactory.HtmlCommentBlock(" zoop "), + Factory.Markup("baz").Accepts(AcceptedCharactersInternal.None), new MarkupTagBlock( Factory.Markup("").Accepts(AcceptedCharactersInternal.None)))); } @@ -355,7 +355,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy get { var factory = new SpanFactory(); - + var blockFactory = new BlockFactory(factory); return new TheoryData { { @@ -363,7 +363,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new MarkupBlock( new MarkupTagBlock( factory.Markup("
").Accepts(AcceptedCharactersInternal.None)), - factory.Markup("").Accepts(AcceptedCharactersInternal.None), + blockFactory.HtmlCommentBlock("- Hello World -"), new MarkupTagBlock( factory.Markup("
").Accepts(AcceptedCharactersInternal.None))) }, @@ -372,7 +372,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new MarkupBlock( new MarkupTagBlock( factory.Markup("
").Accepts(AcceptedCharactersInternal.None)), - factory.Markup("").Accepts(AcceptedCharactersInternal.None), + blockFactory.HtmlCommentBlock("-- Hello World --"), new MarkupTagBlock( factory.Markup("
").Accepts(AcceptedCharactersInternal.None))) }, @@ -381,7 +381,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new MarkupBlock( new MarkupTagBlock( factory.Markup("
").Accepts(AcceptedCharactersInternal.None)), - factory.Markup("").Accepts(AcceptedCharactersInternal.None), + blockFactory.HtmlCommentBlock("--- Hello World ---"), new MarkupTagBlock( factory.Markup("
").Accepts(AcceptedCharactersInternal.None))) }, @@ -390,7 +390,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new MarkupBlock( new MarkupTagBlock( factory.Markup("
").Accepts(AcceptedCharactersInternal.None)), - factory.Markup("").Accepts(AcceptedCharactersInternal.None), + blockFactory.HtmlCommentBlock("--- Hello < --- > World
---"), new MarkupTagBlock( factory.Markup("").Accepts(AcceptedCharactersInternal.None))) }, @@ -410,19 +410,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy [Fact] public void ParseBlockProperlyBalancesCommentStartAndEndTags() { - SingleSpanBlockTest("", BlockKindInternal.Markup, SpanKindInternal.Markup, acceptedCharacters: AcceptedCharactersInternal.None); + ParseBlockTest("", new MarkupBlock(BlockFactory.HtmlCommentBlock(""))); } [Fact] public void ParseBlockTerminatesAtEOFWhenParsingComment() { - SingleSpanBlockTest("", BlockKindInternal.Markup, SpanKindInternal.Markup, acceptedCharacters: AcceptedCharactersInternal.None); + ParseBlockTest("", new MarkupBlock(BlockFactory.HtmlCommentBlock("--"))); } [Fact] @@ -432,8 +437,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new MarkupBlock( new MarkupTagBlock( Factory.Markup("").Accepts(AcceptedCharactersInternal.None)), - Factory.Markup("").Accepts(AcceptedCharactersInternal.None), - Factory.Markup("-->"), + BlockFactory.HtmlCommentBlock("").Accepts(AcceptedCharactersInternal.None), new MarkupTagBlock( Factory.Markup("").Accepts(AcceptedCharactersInternal.None)))); } diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs index 45a1ffa907..ceca9e86f2 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs @@ -1114,8 +1114,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Arrangestring documentContent, IEnumerable allowedChildren = new List { "b" }; string literal = "asdf"; - string commentOutput = ""; - string expectedOutput = $"

{literal}{commentOutput}

"; + string commentOutput = "Hello World"; + string expectedOutput = $"

{literal}

"; var pTagHelperBuilder = TagHelperDescriptorBuilder .Create("PTagHelper", "SomeAssembly") @@ -1138,7 +1138,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy blockFactory.MarkupTagBlock(""), factory.Markup(literal), blockFactory.MarkupTagBlock(""), - new HtmlCommentBlock(factory.Markup(commentOutput)))); + blockFactory.HtmlCommentBlock(commentOutput))); // Act & Assert EvaluateData( @@ -1185,9 +1185,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var expectedMarkup = new MarkupBlock( new MarkupTagHelperBlock("p", - new HtmlCommentBlock(factory.Markup($"")), + blockFactory.HtmlCommentBlock(comment1), factory.Markup(literal), - new HtmlCommentBlock(factory.Markup($"")))); + blockFactory.HtmlCommentBlock(comment2))); // Act & Assert EvaluateData( @@ -1251,10 +1251,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Arrangestring documentContent, IEnumerable allowedChildren = new List { "b" }; string literal = "asdf"; - string part1 = ""; - string expectedOutput = $"

{literal}{part1}@{part2}{part3}

"; + string commentStart = ""; + string expectedOutput = $"

{literal}{commentStart}{part1}@{part2}{commentEnd}

"; var pTagHelperBuilder = TagHelperDescriptorBuilder .Create("PTagHelper", "SomeAssembly") @@ -1277,13 +1278,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy 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)))); + blockFactory.HtmlCommentBlock( + factory.Markup(part1).Accepts(AcceptedCharactersInternal.WhiteSpace), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(part2) + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace))))); // Act & Assert EvaluateData( @@ -4086,14 +4087,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy get { var factory = new SpanFactory(); - + var blockFactory = new BlockFactory(factory); yield return new object[] { "", new MarkupBlock( new MarkupTagBlock( factory.Markup("")), - new HtmlCommentBlock( factory.Markup("")), + blockFactory.HtmlCommentBlock (" Hello World "), new MarkupTagBlock( factory.Markup(""))) }; @@ -4103,13 +4104,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new MarkupBlock( new MarkupTagBlock( factory.Markup("")), - new HtmlCommentBlock(factory.Markup("")), + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" ").Accepts(AcceptedCharactersInternal.WhiteSpace)), new MarkupTagBlock( factory.Markup(""))) }; @@ -4185,8 +4187,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new ExpressionBlock( factory.CodeTransition(), factory.Code("foo") - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), factory.Markup(" ]]>"), new MarkupTagBlock( factory.Markup("
"))) diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperParseTreeRewriterTests.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperParseTreeRewriterTests.cs new file mode 100644 index 0000000000..a24a9c8d4f --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperParseTreeRewriterTests.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Razor.Language.Test +{ + public class TagHelperParseTreeRewriterTests + { + public void IsComment_ReturnsTrueForSpanInHtmlCommentBlock() + { + // Arrange + SpanFactory spanFactory = new SpanFactory(); + + Span content = spanFactory.Markup(""); + Block commentBlock = new HtmlCommentBlock(content); + + // Act + bool actualResult = TagHelperParseTreeRewriter.IsComment(content); + + // Assert + Assert.True(actualResult); + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt index aa6a00864d..615f0fce97 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt @@ -10,7 +10,8 @@ Document - IntermediateToken - - CSharp - #pragma warning restore 0414 MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Double.cshtml) - IntermediateToken - (0:0,0 [12] HtmlCommentWithQuote_Double.cshtml) - Html - \n + IntermediateToken - (0:0,0 [10] HtmlCommentWithQuote_Double.cshtml) - Html - + IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Double.cshtml) - Html - \n IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Double.cshtml) - Html - diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt index 343985c189..7adfc1650b 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt @@ -5,7 +5,8 @@ Document - ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Double_Runtime - - MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Double.cshtml) - IntermediateToken - (0:0,0 [12] HtmlCommentWithQuote_Double.cshtml) - Html - \n + IntermediateToken - (0:0,0 [10] HtmlCommentWithQuote_Double.cshtml) - Html - + IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Double.cshtml) - Html - \n IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Double.cshtml) - Html - diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt index 04795676d1..0e342fcf51 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt @@ -10,7 +10,8 @@ Document - IntermediateToken - - CSharp - #pragma warning restore 0414 MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Single.cshtml) - IntermediateToken - (0:0,0 [12] HtmlCommentWithQuote_Single.cshtml) - Html - \n + IntermediateToken - (0:0,0 [10] HtmlCommentWithQuote_Single.cshtml) - Html - + IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Single.cshtml) - Html - \n IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Single.cshtml) - Html - diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt index 65aafb6fe7..137c2a042c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt @@ -5,7 +5,8 @@ Document - ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Single_Runtime - - MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Single.cshtml) - IntermediateToken - (0:0,0 [12] HtmlCommentWithQuote_Single.cshtml) - Html - \n + IntermediateToken - (0:0,0 [10] HtmlCommentWithQuote_Single.cshtml) - Html - + IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Single.cshtml) - Html - \n IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Single.cshtml) - Html - diff --git a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockFactory.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockFactory.cs index 5c2ee95394..a58d3b0c87 100644 --- a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockFactory.cs +++ b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockFactory.cs @@ -55,6 +55,27 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy ); } + public HtmlCommentBlock HtmlCommentBlock(string content) + { + return new HtmlCommentBlock(new SyntaxTreeNode[] { + _factory.Markup("").Accepts(AcceptedCharactersInternal.None) }); + } + + public HtmlCommentBlock HtmlCommentBlock(params SyntaxTreeNode[] syntaxTreeNodes) + { + var nodes = new List(); + nodes.Add(_factory.Markup("").Accepts(AcceptedCharactersInternal.None)); + + return new HtmlCommentBlock(nodes.ToArray()); + } + public Block TagHelperBlock( string tagName, TagMode tagMode,