diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperBlockRewriter.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperBlockRewriter.cs
index ff156ca870..3bda1518c2 100644
--- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperBlockRewriter.cs
+++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperBlockRewriter.cs
@@ -378,12 +378,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
var htmlSymbol = firstChild.Symbols[firstChild.Symbols.Count - 1] as HtmlSymbol;
switch (htmlSymbol.Type)
{
- // Treat NoQuotes and DoubleQuotes equivalently. We purposefully do not persist NoQuotes
- // ValueStyles at code generation time to protect users from rendering dynamic content with spaces
- // that can break attributes.
- // Ex: where @value results in the test "hello world".
- // This way, the above code would render .
case HtmlSymbolType.Equals:
+ if (builder.Children.Count == 2 &&
+ builder.Children[1] is Span value &&
+ value.Kind == SpanKindInternal.Markup)
+ {
+ // Attribute value is a string literal. Eg: .
+ result.AttributeValueStyle = HtmlAttributeValueStyle.NoQuotes;
+ }
+ else
+ {
+ // Could be an expression, treat NoQuotes and DoubleQuotes equivalently. We purposefully do not persist NoQuotes
+ // ValueStyles at code generation time to protect users from rendering dynamic content with spaces
+ // that can break attributes.
+ // Ex: where @value results in the test "hello world".
+ // This way, the above code would render .
+ result.AttributeValueStyle = HtmlAttributeValueStyle.DoubleQuotes;
+ }
+ break;
case HtmlSymbolType.DoubleQuote:
result.AttributeValueStyle = HtmlAttributeValueStyle.DoubleQuotes;
break;
diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs
index 0c087b7d47..f975bbbdf7 100644
--- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs
+++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs
@@ -460,7 +460,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new TagHelperAttributeNode(
"bar",
factory.Markup("false"),
- HtmlAttributeValueStyle.DoubleQuotes)
+ HtmlAttributeValueStyle.NoQuotes)
})),
new []
{
@@ -556,7 +556,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("btn"))
+ new TagHelperAttributeNode("class", factory.Markup("btn"), HtmlAttributeValueStyle.NoQuotes)
})),
new []
{
@@ -572,7 +572,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("btn"))
+ new TagHelperAttributeNode("class", factory.Markup("btn"), HtmlAttributeValueStyle.NoQuotes)
})),
new []
{
@@ -757,7 +757,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("some"))
+ new TagHelperAttributeNode("class", factory.Markup("some"), HtmlAttributeValueStyle.NoQuotes)
})),
new []
{
@@ -1238,7 +1238,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("class", factory.Markup("foo"), HtmlAttributeValueStyle.NoQuotes),
new TagHelperAttributeNode(
"dynamic",
new MarkupBlock(
@@ -1254,7 +1254,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharactersInternal.NonWhiteSpace)))),
HtmlAttributeValueStyle.DoubleQuotes),
- new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), HtmlAttributeValueStyle.NoQuotes)
},
new MarkupTagHelperBlock("strong")),
blockFactory.MarkupTagBlock("")),
@@ -2467,9 +2467,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("class", factory.Markup("foo"), HtmlAttributeValueStyle.NoQuotes),
new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
- new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), HtmlAttributeValueStyle.NoQuotes)
}))
};
yield return new object[]
@@ -2479,9 +2479,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("class", factory.Markup("foo"), HtmlAttributeValueStyle.NoQuotes),
new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
- new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), HtmlAttributeValueStyle.NoQuotes)
},
factory.Markup("Hello World")))
};
@@ -2492,7 +2492,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("class", factory.Markup("foo"), HtmlAttributeValueStyle.NoQuotes),
new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
new TagHelperAttributeNode(
"style",
@@ -2513,7 +2513,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("class", factory.Markup("foo"), HtmlAttributeValueStyle.NoQuotes),
new TagHelperAttributeNode("dynamic", dateTimeNow(21))
},
factory.Markup("Hello")),
@@ -2521,7 +2521,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("style", factory.Markup("color:red;")),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), HtmlAttributeValueStyle.NoQuotes),
new TagHelperAttributeNode("dynamic", dateTimeNow(73))
},
factory.Markup("World")))
@@ -2533,9 +2533,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p",
new List
{
- new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("class", factory.Markup("foo"), HtmlAttributeValueStyle.NoQuotes),
new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
- new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), HtmlAttributeValueStyle.NoQuotes)
},
factory.Markup("Hello World "),
new MarkupTagBlock(
diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt
index 0b6d78075e..c9bec0b781 100644
--- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt
+++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt
@@ -60,6 +60,6 @@ Document -
SetTagHelperProperty - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml)
RazorIRToken - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - password
- AddTagHelperHtmlAttribute - - data-content - HtmlAttributeValueStyle.DoubleQuotes
+ AddTagHelperHtmlAttribute - - data-content - HtmlAttributeValueStyle.NoQuotes
HtmlContent - (270:14,31 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
RazorIRToken - (270:14,31 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - blah
diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs
index 5c73f1aba6..f2b390a120 100644
--- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs
+++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs
@@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-content", new global::Microsoft.AspNetCore.Html.HtmlString("hello"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-content", new global::Microsoft.AspNetCore.Html.HtmlString("hello2"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "password", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
- private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-content", new global::Microsoft.AspNetCore.Html.HtmlString("blah"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-content", new global::Microsoft.AspNetCore.Html.HtmlString("blah"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.NoQuotes);
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt
index 2f231c1c29..32e54b7981 100644
--- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt
+++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt
@@ -7,7 +7,7 @@ Document -
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 - data-content - hello - HtmlAttributeValueStyle.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3 - data-content - hello2 - HtmlAttributeValueStyle.SingleQuotes
DeclarePreallocatedTagHelperAttribute - - __tagHelperAttribute_4 - type - password - HtmlAttributeValueStyle.DoubleQuotes
- DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5 - data-content - blah - HtmlAttributeValueStyle.DoubleQuotes
+ DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5 - data-content - blah - HtmlAttributeValueStyle.NoQuotes
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2
MethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (33:1,0 [2] TagHelpersWithWeirdlySpacedAttributes.cshtml)