diff --git a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs index 281092d90c..09e7f06b40 100644 --- a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs +++ b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs @@ -463,6 +463,7 @@ namespace Microsoft.AspNet.Razor.Parser // http://dev.w3.org/html5/spec/tokenization.html#attribute-name-state // Read the 'name' (i.e. read until the '=' or whitespace/newline) var name = Enumerable.Empty(); + var whitespaceAfterAttributeName = Enumerable.Empty(); if (At(HtmlSymbolType.Text)) { name = ReadWhile(sym => @@ -472,6 +473,10 @@ namespace Microsoft.AspNet.Razor.Parser sym.Type != HtmlSymbolType.CloseAngle && sym.Type != HtmlSymbolType.OpenAngle && (sym.Type != HtmlSymbolType.ForwardSlash || !NextIs(HtmlSymbolType.CloseAngle))); + + // capture whitespace after attribute name (if any) + whitespaceAfterAttributeName = ReadWhile( + sym => sym.Type == HtmlSymbolType.WhiteSpace || sym.Type == HtmlSymbolType.NewLine); } else { @@ -485,6 +490,10 @@ namespace Microsoft.AspNet.Razor.Parser { // Minimized attribute + // We are at the prefix of the next attribute or the end of tag. Put it back so it is parsed later. + PutCurrentBack(); + PutBack(whitespaceAfterAttributeName); + // Output anything prior to the attribute, in most cases this will be the tag name: // |. If in-between other attributes this will noop or output malformed attribute // content (if the previous attribute was malformed). @@ -507,11 +516,14 @@ namespace Microsoft.AspNet.Razor.Parser // Start a new markup block for the attribute using (Context.StartBlock(BlockType.Markup)) { - AttributePrefix(whitespace, name); + AttributePrefix(whitespace, name, whitespaceAfterAttributeName); } } - private void AttributePrefix(IEnumerable whitespace, IEnumerable nameSymbols) + private void AttributePrefix( + IEnumerable whitespace, + IEnumerable nameSymbols, + IEnumerable whitespaceAfterAttributeName) { // First, determine if this is a 'data-' attribute (since those can't use conditional attributes) var name = nameSymbols.GetContent(Span.Start); @@ -520,14 +532,27 @@ namespace Microsoft.AspNet.Razor.Parser // Accept the whitespace and name Accept(whitespace); Accept(nameSymbols); + + // Since this is not a minimized attribute, the whitespace after attribute name belongs to this attribute. + Accept(whitespaceAfterAttributeName); Assert(HtmlSymbolType.Equals); // We should be at "=" AcceptAndMoveNext(); + + var whitespaceAfterEquals = ReadWhile(sym => sym.Type == HtmlSymbolType.WhiteSpace || sym.Type == HtmlSymbolType.NewLine); var quote = HtmlSymbolType.Unknown; if (At(HtmlSymbolType.SingleQuote) || At(HtmlSymbolType.DoubleQuote)) { + // Found a quote, the whitespace belongs to this attribute. + Accept(whitespaceAfterEquals); quote = CurrentSymbol.Type; AcceptAndMoveNext(); } + else if (whitespaceAfterEquals.Any()) + { + // No quotes found after the whitespace. Put it back so that it can be parsed later. + PutCurrentBack(); + PutBack(whitespaceAfterEquals); + } // We now have the prefix: (i.e. ' foo="') var prefix = Span.GetContent(); @@ -537,10 +562,15 @@ namespace Microsoft.AspNet.Razor.Parser Span.ChunkGenerator = SpanChunkGenerator.Null; // The block chunk generator will render the prefix Output(SpanKind.Markup); - // Read the values - while (!EndOfFile && !IsEndOfAttributeValue(quote, CurrentSymbol)) + // Read the attribute value only if the value is quoted + // or if there is no whitespace between '=' and the unquoted value. + if (quote != HtmlSymbolType.Unknown || !whitespaceAfterEquals.Any()) { - AttributeValue(quote); + // Read the attribute value. + while (!EndOfFile && !IsEndOfAttributeValue(quote, CurrentSymbol)) + { + AttributeValue(quote); + } } // Capture the suffix @@ -567,6 +597,11 @@ namespace Microsoft.AspNet.Razor.Parser // Output the attribute name, the equals and optional quote. Ex: foo=" Output(SpanKind.Markup); + if (quote == HtmlSymbolType.Unknown && whitespaceAfterEquals.Any()) + { + return; + } + // Not a "conditional" attribute, so just read the value SkipToAndParseCode(sym => IsEndOfAttributeValue(quote, sym)); diff --git a/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs index 8ef66f62d6..d2cbc48b7a 100644 --- a/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs +++ b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs @@ -206,23 +206,32 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal // The goal here is to consume the equal sign and the optional single/double-quote. // The coming symbols will either be a quote or value (in the case that the value is unquoted). - // Spaces after/before the equal symbol are not yet supported: - // https://github.com/aspnet/Razor/issues/123 // TODO: Handle malformed tags, if there's an '=' then there MUST be a value. // https://github.com/aspnet/Razor/issues/104 SourceLocation symbolStartLocation; + // Skip the whitespace preceding the start of the attribute value. + var valueStartIndex = i + 1; // Start from the symbol after '='. + while (valueStartIndex < htmlSymbols.Length && + (htmlSymbols[valueStartIndex].Type == HtmlSymbolType.WhiteSpace || + htmlSymbols[valueStartIndex].Type == HtmlSymbolType.NewLine)) + { + valueStartIndex++; + } + // Check for attribute start values, aka single or double quote - if ((i + 1) < htmlSymbols.Length && IsQuote(htmlSymbols[i + 1])) + if (valueStartIndex < htmlSymbols.Length && IsQuote(htmlSymbols[valueStartIndex])) { // Move past the attribute start so we can accept the true value. - i++; - symbolStartLocation = htmlSymbols[i].Start; + valueStartIndex++; + symbolStartLocation = htmlSymbols[valueStartIndex].Start; // If there's a start quote then there must be an end quote to be valid, skip it. symbolOffset = 1; + + i = valueStartIndex - 1; } else { diff --git a/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs b/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs index cd9c86b89b..90f4b3a627 100644 --- a/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs @@ -848,32 +848,36 @@ namespace Microsoft.AspNet.Razor.Test.Generator DefaultPAndInputTagHelperDescriptors, new List { - BuildLineMapping(documentAbsoluteIndex: 14, - documentLineIndex: 0, - generatedAbsoluteIndex: 493, - generatedLineIndex: 15, - characterOffsetIndex: 14, - contentLength: 11), - BuildLineMapping(documentAbsoluteIndex: 62, - documentLineIndex: 3, - documentCharacterOffsetIndex: 26, - generatedAbsoluteIndex: 1289, - generatedLineIndex: 39, - generatedCharacterOffsetIndex: 28, - contentLength: 0), - BuildLineMapping(documentAbsoluteIndex: 122, - documentLineIndex: 5, - generatedAbsoluteIndex: 1634, - generatedLineIndex: 48, - characterOffsetIndex: 30, - contentLength: 0), - BuildLineMapping(documentAbsoluteIndex: 88, - documentLineIndex: 4, - documentCharacterOffsetIndex: 12, - generatedAbsoluteIndex: 1789, - generatedLineIndex: 54, - generatedCharacterOffsetIndex: 19, - contentLength: 0) + BuildLineMapping( + documentAbsoluteIndex: 14, + documentLineIndex: 0, + generatedAbsoluteIndex: 493, + generatedLineIndex: 15, + characterOffsetIndex: 14, + contentLength: 11), + BuildLineMapping( + documentAbsoluteIndex: 63, + documentLineIndex: 3, + documentCharacterOffsetIndex: 27, + generatedAbsoluteIndex: 1289, + generatedLineIndex: 39, + generatedCharacterOffsetIndex: 28, + contentLength: 0), + BuildLineMapping( + documentAbsoluteIndex: 122, + documentLineIndex: 5, + generatedAbsoluteIndex: 1634, + generatedLineIndex: 48, + characterOffsetIndex: 30, + contentLength: 0), + BuildLineMapping( + documentAbsoluteIndex: 89, + documentLineIndex: 4, + documentCharacterOffsetIndex: 13, + generatedAbsoluteIndex: 1789, + generatedLineIndex: 54, + generatedCharacterOffsetIndex: 19, + contentLength: 0), } }, { @@ -1484,6 +1488,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator { { "SingleTagHelper", null, DefaultPAndInputTagHelperDescriptors }, { "SingleTagHelperWithNewlineBeforeAttributes", null, DefaultPAndInputTagHelperDescriptors }, + { "TagHelpersWithWeirdlySpacedAttributes", null, DefaultPAndInputTagHelperDescriptors }, { "BasicTagHelpers", null, DefaultPAndInputTagHelperDescriptors }, { "BasicTagHelpers.RemoveTagHelper", null, DefaultPAndInputTagHelperDescriptors }, { "BasicTagHelpers.Prefixed", null, PrefixedPAndInputTagHelperDescriptors }, diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlAttributeTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlAttributeTest.cs index 0cf8e4a63d..fadf3defa1 100644 --- a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlAttributeTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlAttributeTest.cs @@ -21,9 +21,56 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html new MarkupBlock( new MarkupTagBlock( Factory.Markup("(" href='", 2, 0, 2), suffix: new LocationTagged("'", 12, 0, 12)), + new MarkupBlock( + new AttributeBlockChunkGenerator( + name: "href", prefix: new LocationTagged(" href='", 2, 0, 2), suffix: new LocationTagged("'", 12, 0, 12)), Factory.Markup(" href='").With(SpanChunkGenerator.Null), - Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged(string.Empty, 9, 0, 9), value: new LocationTagged("Foo", 9, 0, 9))), + Factory.Markup("Foo").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 9, 0, 9), value: new LocationTagged("Foo", 9, 0, 9))), + Factory.Markup("'").With(SpanChunkGenerator.Null)), + Factory.Markup(" />").Accepts(AcceptedCharacters.None)))); + } + + [Fact] + public void SimpleLiteralAttributeWithWhitespaceSurroundingEquals() + { + ParseBlockTest("", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("(" href \f\r\n= \t\n'", 2, 0, 2), + suffix: new LocationTagged("'", 19, 2, 4)), + Factory.Markup(" href \f\r\n= \t\n'").With(SpanChunkGenerator.Null), + Factory.Markup("Foo").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 16, 2, 1), value: new LocationTagged("Foo", 16, 2, 1))), + Factory.Markup("'").With(SpanChunkGenerator.Null)), + Factory.Markup(" />").Accepts(AcceptedCharacters.None)))); + } + + [Fact] + public void DynamicAttributeWithWhitespaceSurroundingEquals() + { + ParseBlockTest("", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("(" href \n= \r\n'", 2, 0, 2), + suffix: new LocationTagged("'", 18, 2, 5)), + Factory.Markup(" href \n= \r\n'").With(SpanChunkGenerator.Null), + new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged(string.Empty, 14, 2, 1), 14, 2, 1), + new ExpressionBlock( + Factory.CodeTransition(), + Factory.Code("Foo") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("'").With(SpanChunkGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None)))); } @@ -63,20 +110,20 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html [Fact] public void NewLinePrecedingAttribute() { - ParseBlockTest($"", + ParseBlockTest("", new MarkupBlock( new MarkupTagBlock( Factory.Markup("(Environment.NewLine + "href='", 2, 0, 2), - suffix: new LocationTagged("'", 11 + Environment.NewLine.Length, 1, 9)), - Factory.Markup(Environment.NewLine + "href='").With(SpanChunkGenerator.Null), + prefix: new LocationTagged("\r\nhref='", 2, 0, 2), + suffix: new LocationTagged("'", 13, 1, 9)), + Factory.Markup("\r\nhref='").With(SpanChunkGenerator.Null), Factory.Markup("Foo").With( new LiteralAttributeChunkGenerator( - prefix: new LocationTagged(string.Empty, 8 + Environment.NewLine.Length, 1, 6), - value: new LocationTagged("Foo", 8 + Environment.NewLine.Length, 1, 6))), + prefix: new LocationTagged(string.Empty, 10, 1, 6), + value: new LocationTagged("Foo", 10, 1, 6))), Factory.Markup("'").With(SpanChunkGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None)))); } @@ -84,30 +131,30 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html [Fact] public void NewLineBetweenAttributes() { - ParseBlockTest($"", + ParseBlockTest("", new MarkupBlock( new MarkupTagBlock( Factory.Markup("(Environment.NewLine + "href='", 2, 0, 2), - suffix: new LocationTagged("'", 11 + Environment.NewLine.Length, 1, 9)), - Factory.Markup(Environment.NewLine + "href='").With(SpanChunkGenerator.Null), + prefix: new LocationTagged("\nhref='", 2, 0, 2), + suffix: new LocationTagged("'", 12, 1, 9)), + Factory.Markup("\nhref='").With(SpanChunkGenerator.Null), Factory.Markup("Foo").With( new LiteralAttributeChunkGenerator( - prefix: new LocationTagged(string.Empty, 8 + Environment.NewLine.Length, 1, 6), - value: new LocationTagged("Foo", 8 + Environment.NewLine.Length, 1, 6))), + prefix: new LocationTagged(string.Empty, 9, 1, 6), + value: new LocationTagged("Foo", 9, 1, 6))), Factory.Markup("'").With(SpanChunkGenerator.Null)), new MarkupBlock( new AttributeBlockChunkGenerator( name: "abcd", - prefix: new LocationTagged(Environment.NewLine + "abcd='", 12 + Environment.NewLine.Length, 1, 10), - suffix: new LocationTagged("'", 21 + Environment.NewLine.Length * 2, 2, 9)), - Factory.Markup(Environment.NewLine + "abcd='").With(SpanChunkGenerator.Null), + prefix: new LocationTagged("\r\nabcd='", 13, 1, 10), + suffix: new LocationTagged("'", 24, 2, 9)), + Factory.Markup("\r\nabcd='").With(SpanChunkGenerator.Null), Factory.Markup("Bar").With( new LiteralAttributeChunkGenerator( - prefix: new LocationTagged(string.Empty, 18 + Environment.NewLine.Length * 2, 2, 6), - value: new LocationTagged("Bar", 18 + Environment.NewLine.Length * 2, 2, 6))), + prefix: new LocationTagged(string.Empty, 21, 2, 6), + value: new LocationTagged("Bar", 21, 2, 6))), Factory.Markup("'").With(SpanChunkGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None)))); } @@ -115,20 +162,20 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html [Fact] public void WhitespaceAndNewLinePrecedingAttribute() { - ParseBlockTest($"", + ParseBlockTest("", new MarkupBlock( new MarkupTagBlock( Factory.Markup("(" " + Environment.NewLine + "href='", 2, 0, 2), - suffix: new LocationTagged("'", 12 + Environment.NewLine.Length, 1, 9)), - Factory.Markup(" " + Environment.NewLine + "href='").With(SpanChunkGenerator.Null), + prefix: new LocationTagged(" \t\r\nhref='", 2, 0, 2), + suffix: new LocationTagged("'", 15, 1, 9)), + Factory.Markup(" \t\r\nhref='").With(SpanChunkGenerator.Null), Factory.Markup("Foo").With( new LiteralAttributeChunkGenerator( - prefix: new LocationTagged(string.Empty, 9 + Environment.NewLine.Length, 1, 6), - value: new LocationTagged("Foo", 9 + Environment.NewLine.Length, 1, 6))), + prefix: new LocationTagged(string.Empty, 12, 1, 6), + value: new LocationTagged("Foo", 12, 1, 6))), Factory.Markup("'").With(SpanChunkGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None)))); } @@ -373,6 +420,26 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html Factory.Markup("").Accepts(AcceptedCharacters.None)))); } + [Fact] + public void ConditionalAttributesWithWeirdSpacingAreDisabledForDataAttributesInBlock() + { + ParseBlockTest("", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("").Accepts(AcceptedCharacters.None)), + new MarkupTagBlock( + Factory.Markup("").Accepts(AcceptedCharacters.None)))); + } + [Fact] public void ConditionalAttributesAreDisabledForDataAttributesInDocument() { @@ -392,5 +459,24 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html new MarkupTagBlock( Factory.Markup("")))); } + + [Fact] + public void ConditionalAttributesWithWeirdSpacingAreDisabledForDataAttributesInDocument() + { + ParseDocumentTest("", + new MarkupBlock( + new MarkupTagBlock( + Factory.Markup("")), + new MarkupTagBlock( + Factory.Markup("")))); + } } } diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs index ed2df24a9e..e87afa8e1f 100644 --- a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs @@ -104,9 +104,11 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html BlockFactory.MarkupTagBlock("
"), new MarkupTagBlock( Factory.Markup("")), + new MarkupBlock(new AttributeBlockChunkGenerator(name: "class", prefix: new LocationTagged(" class = '", 8, 0, 8), suffix: new LocationTagged("'", 21, 0, 21)), + Factory.Markup(" class = '").With(SpanChunkGenerator.Null), + Factory.Markup("bar").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged(string.Empty, 18, 0, 18), value: new LocationTagged("bar", 18, 0, 18))), + Factory.Markup("'").With(SpanChunkGenerator.Null)), + Factory.Markup(">")), Factory.Markup(" Foo "), BlockFactory.MarkupTagBlock("

"), BlockFactory.MarkupTagBlock("
"))); diff --git a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs index 842cb4bb49..4656299e28 100644 --- a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs @@ -1761,7 +1761,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers new KeyValuePair("class1", new MarkupBlock()), new KeyValuePair( "class2", - factory.Markup("").With(SpanChunkGenerator.Null)), + factory.Markup(string.Empty).With(SpanChunkGenerator.Null)), new KeyValuePair("class3", new MarkupBlock()), })) }, @@ -1776,7 +1776,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers new KeyValuePair("class2", new MarkupBlock()), new KeyValuePair( "class3", - factory.Markup("").With(SpanChunkGenerator.Null)), + factory.Markup(string.Empty).With(SpanChunkGenerator.Null)), })) }, }; diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/TagHelpersWithWeirdlySpacedAttributes.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/TagHelpersWithWeirdlySpacedAttributes.cs new file mode 100644 index 0000000000..0f2f0c8524 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/TagHelpersWithWeirdlySpacedAttributes.cs @@ -0,0 +1,121 @@ +#pragma checksum "TagHelpersWithWeirdlySpacedAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "61ec0611b60d88357a6c3b6551513ebf6223f6ee" +namespace TestOutput +{ + using Microsoft.AspNet.Razor.Runtime.TagHelpers; + using System; + using System.Threading.Tasks; + + public class TagHelpersWithWeirdlySpacedAttributes + { + #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; + private InputTagHelper __InputTagHelper = null; + private InputTagHelper2 __InputTagHelper2 = null; + #line hidden + public TagHelpersWithWeirdlySpacedAttributes() + { + } + + #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(105, 11, true); + WriteLiteral("Body of Tag"); + Instrumentation.EndContext(); + } + , StartTagHelperWritingScope, EndTagHelperWritingScope); + __PTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__PTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw("Hello World")); +#line 6 "TagHelpersWithWeirdlySpacedAttributes.cshtml" + __PTagHelper.Age = 1337; + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age); + StartTagHelperWritingScope(); +#line 7 "TagHelpersWithWeirdlySpacedAttributes.cshtml" +Write(true); + +#line default +#line hidden + __tagHelperStringValueBuffer = EndTagHelperWritingScope(); + __tagHelperExecutionContext.AddHtmlAttribute("data-content", Html.Raw(__tagHelperStringValueBuffer.ToString())); + __tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + Instrumentation.BeginContext(35, 85, false); + await WriteTagHelperAsync(__tagHelperExecutionContext); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + Instrumentation.BeginContext(120, 4, true); + WriteLiteral("\r\n\r\n"); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => { + } + , StartTagHelperWritingScope, EndTagHelperWritingScope); + __InputTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTagHelper); + __InputTagHelper2 = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTagHelper2); + __InputTagHelper.Type = "text"; + __tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type); + __InputTagHelper2.Type = __InputTagHelper.Type; + __tagHelperExecutionContext.AddHtmlAttribute("data-content", Html.Raw("hello")); + __tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + Instrumentation.BeginContext(124, 47, false); + await WriteTagHelperAsync(__tagHelperExecutionContext); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + Instrumentation.BeginContext(171, 4, true); + WriteLiteral("\r\n\r\n"); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => { + } + , StartTagHelperWritingScope, EndTagHelperWritingScope); + __PTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__PTagHelper); +#line 11 "TagHelpersWithWeirdlySpacedAttributes.cshtml" +__PTagHelper.Age = 1234; + +#line default +#line hidden + __tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age); + __tagHelperExecutionContext.AddHtmlAttribute("data-content", Html.Raw("hello2")); + __tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + Instrumentation.BeginContext(175, 46, false); + await WriteTagHelperAsync(__tagHelperExecutionContext); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + Instrumentation.BeginContext(221, 4, true); + WriteLiteral("\r\n\r\n"); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => { + } + , StartTagHelperWritingScope, EndTagHelperWritingScope); + __InputTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTagHelper); + __InputTagHelper2 = CreateTagHelper(); + __tagHelperExecutionContext.Add(__InputTagHelper2); + __InputTagHelper.Type = "password"; + __tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type); + __InputTagHelper2.Type = __InputTagHelper.Type; + __tagHelperExecutionContext.AddHtmlAttribute("data-content", Html.Raw("blah")); + __tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + Instrumentation.BeginContext(225, 51, false); + await WriteTagHelperAsync(__tagHelperExecutionContext); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Source/TagHelpersWithWeirdlySpacedAttributes.cshtml b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Source/TagHelpersWithWeirdlySpacedAttributes.cshtml new file mode 100644 index 0000000000..b391e560e1 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Source/TagHelpersWithWeirdlySpacedAttributes.cshtml @@ -0,0 +1,15 @@ +@addTagHelper "something, nice" + +

Body of Tag

+ + + +

+ + \ No newline at end of file