Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Commit 39dda01

Browse files
committed
[Fixes #484] Attributes parsed correctly when newlines precedes attributes
1 parent d0688a7 commit 39dda01

File tree

5 files changed

+107
-3
lines changed

5 files changed

+107
-3
lines changed

src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,9 @@ private bool IsTagRecoveryStopPoint(HtmlSymbol sym)
405405

406406
private void TagContent()
407407
{
408-
if (!At(HtmlSymbolType.WhiteSpace))
408+
if (!At(HtmlSymbolType.WhiteSpace) && !At(HtmlSymbolType.NewLine))
409409
{
410-
// We should be right after the tag name, so if there's no whitespace, something is wrong
410+
// We should be right after the tag name, so if there's no whitespace or new line, something is wrong
411411
RecoverToEndOfTag();
412412
}
413413
else

test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,7 @@ public static TheoryData RuntimeTimeTagHelperTestData
14831483
return new TheoryData<string, string, IEnumerable<TagHelperDescriptor>>
14841484
{
14851485
{ "SingleTagHelper", null, DefaultPAndInputTagHelperDescriptors },
1486+
{ "SingleTagHelperWithNewlineBeforeAttributes", null, DefaultPAndInputTagHelperDescriptors },
14861487
{ "BasicTagHelpers", null, DefaultPAndInputTagHelperDescriptors },
14871488
{ "BasicTagHelpers.RemoveTagHelper", null, DefaultPAndInputTagHelperDescriptors },
14881489
{ "BasicTagHelpers.Prefixed", null, PrefixedPAndInputTagHelperDescriptors },

test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlAttributeTest.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.Linq;
56
using Microsoft.AspNet.Razor.Chunks.Generators;
6-
using Microsoft.AspNet.Razor.Editor;
77
using Microsoft.AspNet.Razor.Parser;
88
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
99
using Microsoft.AspNet.Razor.Test.Framework;
@@ -60,6 +60,52 @@ public void DoubleQuotedLiteralAttribute()
6060
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
6161
}
6262

63+
[Fact]
64+
public void NewLinePrecedingAttribute()
65+
{
66+
ParseBlockTest($"<a{Environment.NewLine}href='Foo' />",
67+
new MarkupBlock(
68+
new MarkupTagBlock(
69+
Factory.Markup("<a"),
70+
new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(Environment.NewLine + "href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 13, 1, 9)),
71+
Factory.Markup(Environment.NewLine + "href='").With(SpanChunkGenerator.Null),
72+
Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 10, 1, 6), value: new LocationTagged<string>("Foo", 10, 1, 6))),
73+
Factory.Markup("'").With(SpanChunkGenerator.Null)),
74+
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
75+
}
76+
77+
[Fact]
78+
public void NewLineBetweenAttributes()
79+
{
80+
ParseBlockTest($"<a{Environment.NewLine}href='Foo'{Environment.NewLine}abcd='Bar' />",
81+
new MarkupBlock(
82+
new MarkupTagBlock(
83+
Factory.Markup("<a"),
84+
new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(Environment.NewLine + "href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 13, 1, 9)),
85+
Factory.Markup(Environment.NewLine + "href='").With(SpanChunkGenerator.Null),
86+
Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 10, 1, 6), value: new LocationTagged<string>("Foo", 10, 1, 6))),
87+
Factory.Markup("'").With(SpanChunkGenerator.Null)),
88+
new MarkupBlock(new AttributeBlockChunkGenerator(name: "abcd", prefix: new LocationTagged<string>(Environment.NewLine + "abcd='", 14, 1, 0), suffix: new LocationTagged<string>("'", 25, 2, 9)),
89+
Factory.Markup(Environment.NewLine + "abcd='").With(SpanChunkGenerator.Null),
90+
Factory.Markup("Bar").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 22, 2, 6), value: new LocationTagged<string>("Bar", 22, 2, 6))),
91+
Factory.Markup("'").With(SpanChunkGenerator.Null)),
92+
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
93+
}
94+
95+
[Fact]
96+
public void WhitespaceAndNewLinePrecedingAttribute()
97+
{
98+
ParseBlockTest($"<a {Environment.NewLine}href='Foo' />",
99+
new MarkupBlock(
100+
new MarkupTagBlock(
101+
Factory.Markup("<a"),
102+
new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" " + Environment.NewLine + "href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 14, 1, 9)),
103+
Factory.Markup(" " + Environment.NewLine + "href='").With(SpanChunkGenerator.Null),
104+
Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 11, 1, 6), value: new LocationTagged<string>("Foo", 11, 1, 6))),
105+
Factory.Markup("'").With(SpanChunkGenerator.Null)),
106+
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
107+
}
108+
63109
[Fact]
64110
public void UnquotedLiteralAttribute()
65111
{
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#pragma checksum "SingleTagHelperWithNewlineBeforeAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "95e2e2bab663b8be9934a66150af50a2a6ee08e7"
2+
namespace TestOutput
3+
{
4+
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
5+
using System;
6+
using System.Threading.Tasks;
7+
8+
public class SingleTagHelperWithNewlineBeforeAttributes
9+
{
10+
#line hidden
11+
#pragma warning disable 0414
12+
private TagHelperContent __tagHelperStringValueBuffer = null;
13+
#pragma warning restore 0414
14+
private TagHelperExecutionContext __tagHelperExecutionContext = null;
15+
private TagHelperRunner __tagHelperRunner = null;
16+
private TagHelperScopeManager __tagHelperScopeManager = new TagHelperScopeManager();
17+
private PTagHelper __PTagHelper = null;
18+
#line hidden
19+
public SingleTagHelperWithNewlineBeforeAttributes()
20+
{
21+
}
22+
23+
#pragma warning disable 1998
24+
public override async Task ExecuteAsync()
25+
{
26+
__tagHelperRunner = __tagHelperRunner ?? new TagHelperRunner();
27+
Instrumentation.BeginContext(33, 2, true);
28+
WriteLiteral("\r\n");
29+
Instrumentation.EndContext();
30+
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
31+
Instrumentation.BeginContext(73, 11, true);
32+
WriteLiteral("Body of Tag");
33+
Instrumentation.EndContext();
34+
}
35+
, StartTagHelperWritingScope, EndTagHelperWritingScope);
36+
__PTagHelper = CreateTagHelper<PTagHelper>();
37+
__tagHelperExecutionContext.Add(__PTagHelper);
38+
__tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw("Hello World"));
39+
#line 4 "SingleTagHelperWithNewlineBeforeAttributes.cshtml"
40+
__PTagHelper.Age = 1337;
41+
42+
#line default
43+
#line hidden
44+
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
45+
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
46+
Instrumentation.BeginContext(35, 53, false);
47+
await WriteTagHelperAsync(__tagHelperExecutionContext);
48+
Instrumentation.EndContext();
49+
__tagHelperExecutionContext = __tagHelperScopeManager.End();
50+
}
51+
#pragma warning restore 1998
52+
}
53+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@addTagHelper "something, nice"
2+
3+
<p
4+
class="Hello World" age="1337">Body of Tag</p>

0 commit comments

Comments
 (0)