diff --git a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.cs b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.cs
index 5486d3d4e8..8da02adc94 100644
--- a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.cs
+++ b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.cs
@@ -134,12 +134,35 @@ namespace Microsoft.AspNet.Razor.Parser
{
if (last != null)
{
+ // Don't render the whitespace between the start of the line and the razor comment.
+ if (startOfLine && last.Type == HtmlSymbolType.WhiteSpace)
+ {
+ AddMarkerSymbolIfNecessary();
+ // Output the symbols that may have been accepted prior to the whitespace.
+ Output(SpanKind.Markup);
+
+ Span.ChunkGenerator = SpanChunkGenerator.Null;
+ }
+
Accept(last);
last = null;
}
+
AddMarkerSymbolIfNecessary();
Output(SpanKind.Markup);
+
RazorComment();
+
+ // Handle the whitespace and newline at the end of a razor comment.
+ if (startOfLine &&
+ (At(HtmlSymbolType.NewLine) ||
+ (At(HtmlSymbolType.WhiteSpace) && NextIs(HtmlSymbolType.NewLine))))
+ {
+ AcceptWhile(IsSpacingToken(includeNewLines: false));
+ AcceptAndMoveNext();
+ Span.ChunkGenerator = SpanChunkGenerator.Null;
+ Output(SpanKind.Markup);
+ }
}
else
{
diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpRazorCommentsTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpRazorCommentsTest.cs
index b89b61c3dc..a49e5077a3 100644
--- a/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpRazorCommentsTest.cs
+++ b/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpRazorCommentsTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Test.Framework;
@@ -128,7 +129,8 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new MarkupBlock(
new MarkupTagBlock(
Factory.MarkupTransition("
")), + Factory.Markup(Environment.NewLine), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + string.Empty, + HtmlSymbolType.Unknown)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null), + new MarkupTagBlock( + Factory.Markup("
")) + )); + } + + [Fact] + public void MultipleRazorCommentInMarkup() + { + ParseDocumentTest( + "" + Environment.NewLine + + " @**@ " + Environment.NewLine + + "@**@" + Environment.NewLine + + "
", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("")), + Factory.Markup(Environment.NewLine), + Factory.Markup(" ").With(SpanChunkGenerator.Null), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + string.Empty, + HtmlSymbolType.Unknown)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(" " + Environment.NewLine).With(SpanChunkGenerator.Null), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + string.Empty, + HtmlSymbolType.Unknown)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null), + new MarkupTagBlock( + Factory.Markup("
")) + )); + } + + [Fact] + public void MultipleRazorCommentsInSameLineInMarkup() + { + ParseDocumentTest( + "" + Environment.NewLine + + "@**@ @**@" + Environment.NewLine + + "
", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("")), + Factory.Markup(Environment.NewLine), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + string.Empty, + HtmlSymbolType.Unknown)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.EmptyHtml(), + Factory.Markup(" ").With(SpanChunkGenerator.Null), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + string.Empty, + HtmlSymbolType.Unknown)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null), + new MarkupTagBlock( + Factory.Markup("
")) + )); + } + + [Fact] + public void RazorCommentsSurroundingMarkup() + { + ParseDocumentTest( + "" + Environment.NewLine + + "@* hello *@ content @* world *@" + Environment.NewLine + + "
", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("")), + Factory.Markup(Environment.NewLine), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + " hello ", + HtmlSymbolType.RazorComment)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(" content "), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + " world ", + HtmlSymbolType.RazorComment)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(Environment.NewLine), + new MarkupTagBlock( + Factory.Markup("
")) + )); + } + + [Fact] + public void RazorCommentWithExtraNewLineInMarkup() + { + ParseDocumentTest( + "" + Environment.NewLine + Environment.NewLine + + "@* content *@" + Environment.NewLine + + "@*" + Environment.NewLine + + "content" + Environment.NewLine + + "*@" + Environment.NewLine + Environment.NewLine + + "
", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("")), + Factory.Markup(Environment.NewLine + Environment.NewLine), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + " content ", + HtmlSymbolType.RazorComment)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null), + new CommentBlock( + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.Span(SpanKind.Comment, new HtmlSymbol( + Factory.LocationTracker.CurrentLocation, + Environment.NewLine + "content" + Environment.NewLine, + HtmlSymbolType.RazorComment)) + .Accepts(AcceptedCharacters.Any), + Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar) + .Accepts(AcceptedCharacters.None), + Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition) + .Accepts(AcceptedCharacters.None)), + Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null), + Factory.Markup(Environment.NewLine), + new MarkupTagBlock( + Factory.Markup("
")) + )); + } } } diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs index 78243fcdb8..73437adf9d 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs @@ -156,9 +156,8 @@ WriteTo(__razor_template_writer, item); #line default #line hidden - Instrumentation.BeginContext(574, 93, true); - WriteLiteralTo(__razor_template_writer, "\r\n