Skip to content

Commit ef19746

Browse files
Preserve quote style when rendering markup content (#33548)
* Preserve quote style when rendering markup content * Replace Contains check with EndsWith check * Provide StringComparison arg to appease the linter * Update src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentMarkupBlockPass.cs Co-authored-by: campersau <[email protected]> * Back to strings since char overload is not supported * Update test baselines Co-authored-by: campersau <[email protected]>
1 parent 37ff6e8 commit ef19746

File tree

8 files changed

+45
-8
lines changed

8 files changed

+45
-8
lines changed

src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentMarkupBlockPass.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,12 +327,17 @@ public override void VisitHtmlAttribute(HtmlAttributeIntermediateNode node)
327327
return;
328328
}
329329

330-
Builder.Append("=\"");
330+
// We examine the node.Prefix (e.g. " onfocus='" or " on focus=\"")
331+
// to preserve the quote type that is used in the original markup.
332+
var quoteType = node.Prefix.EndsWith("'", StringComparison.Ordinal) ? "'" : "\"";
333+
334+
Builder.Append('=');
335+
Builder.Append(quoteType);
331336

332337
// Visit Children
333338
base.VisitDefault(node);
334339

335-
Builder.Append('"');
340+
Builder.Append(quoteType);
336341
}
337342

338343
public override void VisitHtmlAttributeValue(HtmlAttributeValueIntermediateNode node)

src/Razor/Microsoft.AspNetCore.Razor.Language/test/Components/ComponentMarkupBlockPassTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ public void Execute_CanRewriteHtml_OptionWithNoSelectAncestor()
347347
</html>");
348348

349349
var expected = NormalizeContent(@"
350-
<head cool=""beans""><option value=""1"">One</option>
351-
<option selected value=""2"">Two</option></head>");
350+
<head cool=""beans""><option value='1'>One</option>
351+
<option selected value='2'>Two</option></head>");
352352

353353
var documentNode = Lower(document);
354354

src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6674,6 +6674,9 @@ public void EventHandlerTagHelper_EscapeQuotes()
66746674
// Act
66756675
var generated = CompileToCSharp(@"
66766676
<input onfocus='alert(""Test"");' />
6677+
<input onfocus=""alert(""Test"");"" />
6678+
<input onfocus=""alert('Test');"" />
6679+
<p data-options='{direction: ""fromtop"", animation_duration: 25, direction: ""reverse""}'></p>
66776680
");
66786681

66796682
// Assert

src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/EventHandlerTagHelper_EscapeQuotes/TestComponent.ir.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,32 @@ Document -
2020
LazyIntermediateToken - (16:0,16 [14] x:\dir\subdir\Test\TestComponent.cshtml) - Html - alert("Test");
2121
HtmlContent - (34:0,34 [2] x:\dir\subdir\Test\TestComponent.cshtml)
2222
LazyIntermediateToken - (34:0,34 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
23+
MarkupElement - (36:1,0 [34] x:\dir\subdir\Test\TestComponent.cshtml) - input
24+
HtmlAttribute - (42:1,6 [17] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus=" - "
25+
HtmlAttributeValue - (52:1,16 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
26+
LazyIntermediateToken - (52:1,16 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - alert(
27+
HtmlAttribute - (59:1,23 [8] x:\dir\subdir\Test\TestComponent.cshtml) - Test");" -
28+
HtmlContent - (70:1,34 [2] x:\dir\subdir\Test\TestComponent.cshtml)
29+
LazyIntermediateToken - (70:1,34 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
30+
MarkupElement - (72:2,0 [34] x:\dir\subdir\Test\TestComponent.cshtml) - input
31+
HtmlAttribute - (78:2,6 [25] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus=" - "
32+
HtmlAttributeValue - (88:2,16 [14] x:\dir\subdir\Test\TestComponent.cshtml) -
33+
LazyIntermediateToken - (88:2,16 [14] x:\dir\subdir\Test\TestComponent.cshtml) - Html - alert('Test');
34+
HtmlContent - (106:2,34 [2] x:\dir\subdir\Test\TestComponent.cshtml)
35+
LazyIntermediateToken - (106:2,34 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
36+
MarkupElement - (108:3,0 [91] x:\dir\subdir\Test\TestComponent.cshtml) - p
37+
HtmlAttribute - (110:3,2 [84] x:\dir\subdir\Test\TestComponent.cshtml) - data-options=' - '
38+
HtmlAttributeValue - (125:3,17 [11] x:\dir\subdir\Test\TestComponent.cshtml) -
39+
LazyIntermediateToken - (125:3,17 [11] x:\dir\subdir\Test\TestComponent.cshtml) - Html - {direction:
40+
HtmlAttributeValue - (136:3,28 [11] x:\dir\subdir\Test\TestComponent.cshtml) -
41+
LazyIntermediateToken - (137:3,29 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - "fromtop",
42+
HtmlAttributeValue - (147:3,39 [20] x:\dir\subdir\Test\TestComponent.cshtml) -
43+
LazyIntermediateToken - (148:3,40 [19] x:\dir\subdir\Test\TestComponent.cshtml) - Html - animation_duration:
44+
HtmlAttributeValue - (167:3,59 [4] x:\dir\subdir\Test\TestComponent.cshtml) -
45+
LazyIntermediateToken - (168:3,60 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - 25,
46+
HtmlAttributeValue - (171:3,63 [11] x:\dir\subdir\Test\TestComponent.cshtml) -
47+
LazyIntermediateToken - (172:3,64 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - direction:
48+
HtmlAttributeValue - (182:3,74 [11] x:\dir\subdir\Test\TestComponent.cshtml) -
49+
LazyIntermediateToken - (183:3,75 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - "reverse"}
50+
HtmlContent - (199:3,91 [2] x:\dir\subdir\Test\TestComponent.cshtml)
51+
LazyIntermediateToken - (199:3,91 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n

src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.codegen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Renderin
1717
__builder.AddAttribute(1, "MyAttr", "abc");
1818
__builder.AddAttribute(2, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
1919
__builder2.AddContent(3, "Some text");
20-
__builder2.AddMarkupContent(4, "<some-child a=\"1\">Nested text</some-child>");
20+
__builder2.AddMarkupContent(4, "<some-child a=\'1\'>Nested text</some-child>");
2121
}
2222
));
2323
__builder.CloseComponent();

src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_WithChildContent/TestComponent.ir.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Document -
1111
ComponentChildContent - - ChildContent - context
1212
HtmlContent - (26:0,26 [9] x:\dir\subdir\Test\TestComponent.cshtml)
1313
LazyIntermediateToken - (26:0,26 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Some text
14-
MarkupBlock - - <some-child a="1">Nested text</some-child>
14+
MarkupBlock - - <some-child a='1'>Nested text</some-child>
1515
ComponentAttribute - (21:0,21 [3] x:\dir\subdir\Test\TestComponent.cshtml) - MyAttr - MyAttr - AttributeStructure.DoubleQuotes
1616
HtmlContent - (21:0,21 [3] x:\dir\subdir\Test\TestComponent.cshtml)
1717
LazyIntermediateToken - (21:0,21 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - abc

src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/EventHandlerTagHelper_EscapeQuotes/TestComponent.codegen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBa
1313
#pragma warning disable 1998
1414
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
1515
{
16-
__builder.AddMarkupContent(0, "<input onfocus=\"alert(\"Test\");\">");
16+
__builder.AddMarkupContent(0, "<input onfocus=\'alert(\"Test\");\'>\r\n<input onfocus=\"alert(\" Test\");\">\r\n<input onfocus=\"alert(\'Test\');\">\r\n<p data-options=\'{direction: \"fromtop\", animation_duration: 25, direction: \"reverse\"}\'></p>");
1717
}
1818
#pragma warning restore 1998
1919
}

src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/EventHandlerTagHelper_EscapeQuotes/TestComponent.ir.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ Document -
77
UsingDirective - (104:5,1 [39] ) - Microsoft.AspNetCore.Components
88
ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
99
MethodDeclaration - - protected override - void - BuildRenderTree
10-
MarkupBlock - - <input onfocus="alert("Test");">
10+
MarkupBlock - - <input onfocus='alert("Test");'>\n<input onfocus="alert(" Test");">\n<input onfocus="alert('Test');">\n<p data-options='{direction: "fromtop", animation_duration: 25, direction: "reverse"}'></p>

0 commit comments

Comments
 (0)