[Fixes #484] Attributes parsed correctly when newlines precedes attributes

This commit is contained in:
Ajay Bhargav Baaskaran 2015-08-24 15:44:00 -07:00
parent d0688a7e00
commit 39dda01f47
5 changed files with 107 additions and 3 deletions

View File

@ -405,9 +405,9 @@ namespace Microsoft.AspNet.Razor.Parser
private void TagContent()
{
if (!At(HtmlSymbolType.WhiteSpace))
if (!At(HtmlSymbolType.WhiteSpace) && !At(HtmlSymbolType.NewLine))
{
// We should be right after the tag name, so if there's no whitespace, something is wrong
// We should be right after the tag name, so if there's no whitespace or new line, something is wrong
RecoverToEndOfTag();
}
else

View File

@ -1483,6 +1483,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
return new TheoryData<string, string, IEnumerable<TagHelperDescriptor>>
{
{ "SingleTagHelper", null, DefaultPAndInputTagHelperDescriptors },
{ "SingleTagHelperWithNewlineBeforeAttributes", null, DefaultPAndInputTagHelperDescriptors },
{ "BasicTagHelpers", null, DefaultPAndInputTagHelperDescriptors },
{ "BasicTagHelpers.RemoveTagHelper", null, DefaultPAndInputTagHelperDescriptors },
{ "BasicTagHelpers.Prefixed", null, PrefixedPAndInputTagHelperDescriptors },

View File

@ -1,9 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Editor;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Test.Framework;
@ -60,6 +60,52 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void NewLinePrecedingAttribute()
{
ParseBlockTest($"<a{Environment.NewLine}href='Foo' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(Environment.NewLine + "href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 13, 1, 9)),
Factory.Markup(Environment.NewLine + "href='").With(SpanChunkGenerator.Null),
Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 10, 1, 6), value: new LocationTagged<string>("Foo", 10, 1, 6))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void NewLineBetweenAttributes()
{
ParseBlockTest($"<a{Environment.NewLine}href='Foo'{Environment.NewLine}abcd='Bar' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(Environment.NewLine + "href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 13, 1, 9)),
Factory.Markup(Environment.NewLine + "href='").With(SpanChunkGenerator.Null),
Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 10, 1, 6), value: new LocationTagged<string>("Foo", 10, 1, 6))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
new MarkupBlock(new AttributeBlockChunkGenerator(name: "abcd", prefix: new LocationTagged<string>(Environment.NewLine + "abcd='", 14, 1, 0), suffix: new LocationTagged<string>("'", 25, 2, 9)),
Factory.Markup(Environment.NewLine + "abcd='").With(SpanChunkGenerator.Null),
Factory.Markup("Bar").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 22, 2, 6), value: new LocationTagged<string>("Bar", 22, 2, 6))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void WhitespaceAndNewLinePrecedingAttribute()
{
ParseBlockTest($"<a {Environment.NewLine}href='Foo' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" " + Environment.NewLine + "href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 14, 1, 9)),
Factory.Markup(" " + Environment.NewLine + "href='").With(SpanChunkGenerator.Null),
Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 11, 1, 6), value: new LocationTagged<string>("Foo", 11, 1, 6))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void UnquotedLiteralAttribute()
{

View File

@ -0,0 +1,53 @@
#pragma checksum "SingleTagHelperWithNewlineBeforeAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "95e2e2bab663b8be9934a66150af50a2a6ee08e7"
namespace TestOutput
{
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using System;
using System.Threading.Tasks;
public class SingleTagHelperWithNewlineBeforeAttributes
{
#line hidden
#pragma warning disable 0414
private TagHelperContent __tagHelperStringValueBuffer = null;
#pragma warning restore 0414
private TagHelperExecutionContext __tagHelperExecutionContext = null;
private TagHelperRunner __tagHelperRunner = null;
private TagHelperScopeManager __tagHelperScopeManager = new TagHelperScopeManager();
private PTagHelper __PTagHelper = null;
#line hidden
public SingleTagHelperWithNewlineBeforeAttributes()
{
}
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
__tagHelperRunner = __tagHelperRunner ?? new TagHelperRunner();
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(73, 11, true);
WriteLiteral("Body of Tag");
Instrumentation.EndContext();
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__PTagHelper = CreateTagHelper<PTagHelper>();
__tagHelperExecutionContext.Add(__PTagHelper);
__tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw("Hello World"));
#line 4 "SingleTagHelperWithNewlineBeforeAttributes.cshtml"
__PTagHelper.Age = 1337;
#line default
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(35, 53, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
}
#pragma warning restore 1998
}
}

View File

@ -0,0 +1,4 @@
@addTagHelper "something, nice"
<p
class="Hello World" age="1337">Body of Tag</p>