Fix runtime preventDefault / stopPropagation break.

- The Blazor runtime doesn't support adding attributes prior to any sort of content frames being applied. This change ensures that `ComponentAttributes` (how preventDefault / stopPropagation are represented) are handled like other HTML attributes (applied first).
- Updated existing tests and their baselines.

aspnet/AspNetCoredotnet/aspnetcore-tooling#16611
\n\nCommit migrated from 1513cd2a5b
This commit is contained in:
N. Taylor Mullen 2019-10-28 11:43:45 -07:00
parent 18457ddc85
commit e2dc96c7b9
13 changed files with 96 additions and 48 deletions

View File

@ -191,6 +191,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{ {
context.RenderNode(attribute); context.RenderNode(attribute);
} }
else if (child is ComponentAttributeIntermediateNode componentAttribute)
{
context.RenderNode(componentAttribute);
}
else if (child is SplatIntermediateNode splat) else if (child is SplatIntermediateNode splat)
{ {
context.RenderNode(splat); context.RenderNode(splat);

View File

@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public IEnumerable<IntermediateNode> Body => Children.Where(c => public IEnumerable<IntermediateNode> Body => Children.Where(c =>
{ {
return return
c as ComponentAttributeIntermediateNode == null &&
c as HtmlAttributeIntermediateNode == null && c as HtmlAttributeIntermediateNode == null &&
c as SplatIntermediateNode == null && c as SplatIntermediateNode == null &&
c as SetKeyIntermediateNode == null && c as SetKeyIntermediateNode == null &&

View File

@ -2905,7 +2905,7 @@ namespace Test
// Act // Act
var generated = CompileToCSharp(@" var generated = CompileToCSharp(@"
@using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web
<input @onclick:preventDefault @onclick:stopPropagation />"); <button @onclick:preventDefault @onclick:stopPropagation>Click Me</button>");
// Assert // Assert
AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
@ -2921,7 +2921,7 @@ namespace Test
// Act // Act
var generated = CompileToCSharp(@" var generated = CompileToCSharp(@"
@using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web
<input @onfocus:preventDefault=""true"" @onclick:stopPropagation=""Foo"" @onfocus:stopPropagation=""false"" /> <button @onclick=""() => Foo = false"" @onfocus:preventDefault=""true"" @onclick:stopPropagation=""Foo"" @onfocus:stopPropagation=""false"">Click Me</button>
@code { @code {
bool Foo { get; set; } bool Foo { get; set; }
}"); }");

View File

@ -27,10 +27,10 @@ using Microsoft.AspNetCore.Components.Web;
#pragma warning disable 1998 #pragma warning disable 1998
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{ {
__o = Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>( __o = Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this,
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
true () => Foo = false
#line default #line default
#line hidden #line hidden
@ -39,7 +39,7 @@ using Microsoft.AspNetCore.Components.Web;
__o = Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>( __o = Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>(
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
Foo true
#line default #line default
#line hidden #line hidden
@ -48,7 +48,16 @@ using Microsoft.AspNetCore.Components.Web;
__o = Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>( __o = Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>(
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
false Foo
#line default
#line hidden
#nullable disable
);
__o = Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>(
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
false
#line default #line default
#line hidden #line hidden

View File

@ -17,17 +17,24 @@ Document -
MethodDeclaration - - protected override - void - BuildRenderTree MethodDeclaration - - protected override - void - BuildRenderTree
HtmlContent - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) HtmlContent - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n IntermediateToken - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
MarkupElement - (44:1,0 [104] x:\dir\subdir\Test\TestComponent.cshtml) - input MarkupElement - (44:1,0 [149] x:\dir\subdir\Test\TestComponent.cshtml) - button
ComponentAttribute - (76:1,32 [4] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - PreventDefault - AttributeStructure.DoubleQuotes HtmlContent - (176:1,132 [8] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (176:1,132 [8] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Click Me
HtmlAttribute - (62:1,18 [17] x:\dir\subdir\Test\TestComponent.cshtml) - onclick=" - "
CSharpExpressionAttributeValue - -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this,
IntermediateToken - (62:1,18 [17] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - () => Foo = false
IntermediateToken - - CSharp - )
ComponentAttribute - (106:1,62 [4] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - PreventDefault - AttributeStructure.DoubleQuotes
CSharpExpression - CSharpExpression -
IntermediateToken - (76:1,32 [4] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - true IntermediateToken - (106:1,62 [4] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - true
ComponentAttribute - (108:1,64 [3] x:\dir\subdir\Test\TestComponent.cshtml) - onclick - StopPropagation - AttributeStructure.DoubleQuotes ComponentAttribute - (138:1,94 [3] x:\dir\subdir\Test\TestComponent.cshtml) - onclick - StopPropagation - AttributeStructure.DoubleQuotes
CSharpExpression - CSharpExpression -
IntermediateToken - (108:1,64 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Foo IntermediateToken - (138:1,94 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Foo
ComponentAttribute - (139:1,95 [5] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - StopPropagation - AttributeStructure.DoubleQuotes ComponentAttribute - (169:1,125 [5] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - StopPropagation - AttributeStructure.DoubleQuotes
CSharpExpression - CSharpExpression -
IntermediateToken - (139:1,95 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - false IntermediateToken - (169:1,125 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - false
HtmlContent - (148:1,104 [2] x:\dir\subdir\Test\TestComponent.cshtml) HtmlContent - (193:1,149 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (148:1,104 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n IntermediateToken - (193:1,149 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
CSharpCode - (157:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) CSharpCode - (202:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (157:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n bool Foo { get; set; }\n IntermediateToken - (202:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n bool Foo { get; set; }\n

View File

@ -3,26 +3,31 @@ Source Location: (1:0,1 [41] x:\dir\subdir\Test\TestComponent.cshtml)
Generated Location: (320:12,0 [41] ) Generated Location: (320:12,0 [41] )
|using Microsoft.AspNetCore.Components.Web| |using Microsoft.AspNetCore.Components.Web|
Source Location: (76:1,32 [4] x:\dir\subdir\Test\TestComponent.cshtml) Source Location: (62:1,18 [17] x:\dir\subdir\Test\TestComponent.cshtml)
|() => Foo = false|
Generated Location: (1173:32,18 [17] )
|() => Foo = false|
Source Location: (106:1,62 [4] x:\dir\subdir\Test\TestComponent.cshtml)
|true| |true|
Generated Location: (1158:32,32 [4] ) Generated Location: (1500:41,62 [4] )
|true| |true|
Source Location: (108:1,64 [3] x:\dir\subdir\Test\TestComponent.cshtml) Source Location: (138:1,94 [3] x:\dir\subdir\Test\TestComponent.cshtml)
|Foo| |Foo|
Generated Location: (1474:41,64 [3] ) Generated Location: (1846:50,94 [3] )
|Foo| |Foo|
Source Location: (139:1,95 [5] x:\dir\subdir\Test\TestComponent.cshtml) Source Location: (169:1,125 [5] x:\dir\subdir\Test\TestComponent.cshtml)
|false| |false|
Generated Location: (1820:50,95 [5] ) Generated Location: (2222:59,125 [5] )
|false| |false|
Source Location: (157:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) Source Location: (202:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml)
| |
bool Foo { get; set; } bool Foo { get; set; }
| |
Generated Location: (2019:60,7 [30] ) Generated Location: (2421:69,7 [30] )
| |
bool Foo { get; set; } bool Foo { get; set; }
| |

View File

@ -17,6 +17,8 @@ Document -
MethodDeclaration - - protected override - void - BuildRenderTree MethodDeclaration - - protected override - void - BuildRenderTree
HtmlContent - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) HtmlContent - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n IntermediateToken - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
MarkupElement - (44:1,0 [58] x:\dir\subdir\Test\TestComponent.cshtml) - input MarkupElement - (44:1,0 [74] x:\dir\subdir\Test\TestComponent.cshtml) - button
HtmlContent - (101:1,57 [8] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (101:1,57 [8] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Click Me
ComponentAttribute - - onclick - PreventDefault - AttributeStructure.Minimized ComponentAttribute - - onclick - PreventDefault - AttributeStructure.Minimized
ComponentAttribute - - onclick - StopPropagation - AttributeStructure.Minimized ComponentAttribute - - onclick - StopPropagation - AttributeStructure.Minimized

View File

@ -21,8 +21,7 @@ using Microsoft.AspNetCore.Components.Web;
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{ {
__builder.OpenElement(0, "input"); __builder.OpenElement(0, "input");
__builder.AddAttribute(1, "@onclick:preventDefault", true); __builder.AddEventPreventDefaultAttribute(1, "onclick",
__builder.AddEventPreventDefaultAttribute(2, "onclick",
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
true true
@ -31,6 +30,7 @@ using Microsoft.AspNetCore.Components.Web;
#line hidden #line hidden
#nullable disable #nullable disable
); );
__builder.AddAttribute(2, "@onclick:preventDefault", true);
__builder.CloseElement(); __builder.CloseElement();
} }
#pragma warning restore 1998 #pragma warning restore 1998

View File

@ -20,34 +20,44 @@ using Microsoft.AspNetCore.Components.Web;
#pragma warning disable 1998 #pragma warning disable 1998
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{ {
__builder.OpenElement(0, "input"); __builder.OpenElement(0, "button");
__builder.AddEventPreventDefaultAttribute(1, "onfocus", __builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this,
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
true () => Foo = false
#line default
#line hidden
#nullable disable
));
__builder.AddEventPreventDefaultAttribute(2, "onfocus",
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
true
#line default #line default
#line hidden #line hidden
#nullable disable #nullable disable
); );
__builder.AddEventStopPropagationAttribute(2, "onclick", __builder.AddEventStopPropagationAttribute(3, "onclick",
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
Foo Foo
#line default #line default
#line hidden #line hidden
#nullable disable #nullable disable
); );
__builder.AddEventStopPropagationAttribute(3, "onfocus", __builder.AddEventStopPropagationAttribute(4, "onfocus",
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
false false
#line default #line default
#line hidden #line hidden
#nullable disable #nullable disable
); );
__builder.AddContent(5, "Click Me");
__builder.CloseElement(); __builder.CloseElement();
} }
#pragma warning restore 1998 #pragma warning restore 1998

View File

@ -8,15 +8,22 @@ Document -
UsingDirective - (1:0,1 [43] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web UsingDirective - (1:0,1 [43] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web
ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
MethodDeclaration - - protected override - void - BuildRenderTree MethodDeclaration - - protected override - void - BuildRenderTree
MarkupElement - (44:1,0 [104] x:\dir\subdir\Test\TestComponent.cshtml) - input MarkupElement - (44:1,0 [149] x:\dir\subdir\Test\TestComponent.cshtml) - button
ComponentAttribute - (76:1,32 [4] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - PreventDefault - AttributeStructure.DoubleQuotes HtmlContent - (176:1,132 [8] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (176:1,132 [8] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Click Me
HtmlAttribute - (62:1,18 [17] x:\dir\subdir\Test\TestComponent.cshtml) - onclick=" - "
CSharpExpressionAttributeValue - -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this,
IntermediateToken - (62:1,18 [17] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - () => Foo = false
IntermediateToken - - CSharp - )
ComponentAttribute - (106:1,62 [4] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - PreventDefault - AttributeStructure.DoubleQuotes
CSharpExpression - CSharpExpression -
IntermediateToken - (76:1,32 [4] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - true IntermediateToken - (106:1,62 [4] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - true
ComponentAttribute - (108:1,64 [3] x:\dir\subdir\Test\TestComponent.cshtml) - onclick - StopPropagation - AttributeStructure.DoubleQuotes ComponentAttribute - (138:1,94 [3] x:\dir\subdir\Test\TestComponent.cshtml) - onclick - StopPropagation - AttributeStructure.DoubleQuotes
CSharpExpression - CSharpExpression -
IntermediateToken - (108:1,64 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Foo IntermediateToken - (138:1,94 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Foo
ComponentAttribute - (139:1,95 [5] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - StopPropagation - AttributeStructure.DoubleQuotes ComponentAttribute - (169:1,125 [5] x:\dir\subdir\Test\TestComponent.cshtml) - onfocus - StopPropagation - AttributeStructure.DoubleQuotes
CSharpExpression - CSharpExpression -
IntermediateToken - (139:1,95 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - false IntermediateToken - (169:1,125 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - false
CSharpCode - (157:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) CSharpCode - (202:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (157:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n bool Foo { get; set; }\n IntermediateToken - (202:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n bool Foo { get; set; }\n

View File

@ -1,8 +1,8 @@
Source Location: (157:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml) Source Location: (202:2,7 [30] x:\dir\subdir\Test\TestComponent.cshtml)
| |
bool Foo { get; set; } bool Foo { get; set; }
| |
Generated Location: (1720:55,7 [30] ) Generated Location: (2205:65,7 [30] )
| |
bool Foo { get; set; } bool Foo { get; set; }
| |

View File

@ -20,9 +20,10 @@ using Microsoft.AspNetCore.Components.Web;
#pragma warning disable 1998 #pragma warning disable 1998
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{ {
__builder.OpenElement(0, "input"); __builder.OpenElement(0, "button");
__builder.AddEventPreventDefaultAttribute(1, "onclick", true); __builder.AddEventPreventDefaultAttribute(1, "onclick", true);
__builder.AddEventStopPropagationAttribute(2, "onclick", true); __builder.AddEventStopPropagationAttribute(2, "onclick", true);
__builder.AddContent(3, "Click Me");
__builder.CloseElement(); __builder.CloseElement();
} }
#pragma warning restore 1998 #pragma warning restore 1998

View File

@ -8,6 +8,8 @@ Document -
UsingDirective - (1:0,1 [43] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web UsingDirective - (1:0,1 [43] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web
ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
MethodDeclaration - - protected override - void - BuildRenderTree MethodDeclaration - - protected override - void - BuildRenderTree
MarkupElement - (44:1,0 [58] x:\dir\subdir\Test\TestComponent.cshtml) - input MarkupElement - (44:1,0 [74] x:\dir\subdir\Test\TestComponent.cshtml) - button
HtmlContent - (101:1,57 [8] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (101:1,57 [8] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Click Me
ComponentAttribute - - onclick - PreventDefault - AttributeStructure.Minimized ComponentAttribute - - onclick - PreventDefault - AttributeStructure.Minimized
ComponentAttribute - - onclick - StopPropagation - AttributeStructure.Minimized ComponentAttribute - - onclick - StopPropagation - AttributeStructure.Minimized