Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/Components/Components/src/LayoutComponentBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using static Microsoft.AspNetCore.Internal.LinkerFlags;

namespace Microsoft.AspNetCore.Components
{
/// <summary>
Expand All @@ -17,5 +21,12 @@ public abstract class LayoutComponentBase : ComponentBase
/// </summary>
[Parameter]
public RenderFragment? Body { get; set; }

/// <inheritdoc />
// Derived instances of LayoutComponentBase do not appear in any statically analyzable
// calls of OpenComponent<T> where T is well-known. Consequently we have to explicitly provide a hint to the trimmer to preserve
// properties.
[DynamicDependency(Component, typeof(LayoutComponentBase))]
public override Task SetParametersAsync(ParameterView parameters) => base.SetParametersAsync(parameters);
}
}
1 change: 1 addition & 0 deletions src/Components/Components/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Microsoft.AspNetCore.Components.CascadingTypeParameterAttribute
Microsoft.AspNetCore.Components.CascadingTypeParameterAttribute.CascadingTypeParameterAttribute(string! name) -> void
Microsoft.AspNetCore.Components.CascadingTypeParameterAttribute.Name.get -> string!
Microsoft.AspNetCore.Components.RenderTree.Renderer.GetEventArgsType(ulong eventHandlerId) -> System.Type!
override Microsoft.AspNetCore.Components.LayoutComponentBase.SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) -> System.Threading.Tasks.Task!
static Microsoft.AspNetCore.Components.ParameterView.FromDictionary(System.Collections.Generic.IDictionary<string!, object?>! parameters) -> Microsoft.AspNetCore.Components.ParameterView
virtual Microsoft.AspNetCore.Components.RenderTree.Renderer.DispatchEventAsync(ulong eventHandlerId, Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo? fieldInfo, System.EventArgs! eventArgs) -> System.Threading.Tasks.Task!
*REMOVED*readonly Microsoft.AspNetCore.Components.RenderTree.RenderTreeEdit.RemovedAttributeName -> string
50 changes: 23 additions & 27 deletions src/Components/Shared/src/WebEventData.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#nullable enable

using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using Microsoft.AspNetCore.Components.RenderTree;
using static Microsoft.AspNetCore.Internal.LinkerFlags;
#nullable enable

namespace Microsoft.AspNetCore.Components.Web
{
internal class WebEventData
Expand Down Expand Up @@ -61,21 +63,13 @@ private static EventArgs ParseEventArgsJson(Renderer renderer, ulong eventHandle
{
try
{
if (TryGetStandardWebEventArgsType(eventName, out var eventArgsType))
{
// Special case for ChangeEventArgs because its value type can be one of
// several types, and System.Text.Json doesn't pick types dynamically
if (eventArgsType == typeof(ChangeEventArgs))
{
return DeserializeChangeEventArgs(eventArgsJson);
}
}
else
if (TryDeserializeStandardWebEventArgs(eventName, eventArgsJson, out var eventArgs))
{
// For custom events, the args type is determined from the associated delegate
eventArgsType = renderer.GetEventArgsType(eventHandlerId);
return eventArgs;
}

// For custom events, the args type is determined from the associated delegate
var eventArgsType = renderer.GetEventArgsType(eventHandlerId);
return (EventArgs)JsonSerializer.Deserialize(eventArgsJson, eventArgsType, JsonSerializerOptionsProvider.Options)!;
}
catch (Exception e)
Expand All @@ -84,7 +78,7 @@ private static EventArgs ParseEventArgsJson(Renderer renderer, ulong eventHandle
}
}

private static bool TryGetStandardWebEventArgsType(string eventName, [MaybeNullWhen(false)] out Type type)
private static bool TryDeserializeStandardWebEventArgs(string eventName, string eventArgsJson, [NotNullWhen(true)] out EventArgs? eventArgs)
{
// For back-compatibility, we recognize the built-in list of web event names and hard-code
// rules about the deserialization type for their eventargs. This makes it possible to declare
Expand All @@ -97,13 +91,15 @@ private static bool TryGetStandardWebEventArgsType(string eventName, [MaybeNullW
{
case "input":
case "change":
type = typeof(ChangeEventArgs);
// Special case for ChangeEventArgs because its value type can be one of
// several types, and System.Text.Json doesn't pick types dynamically
eventArgs = DeserializeChangeEventArgs(eventArgsJson);
return true;

case "copy":
case "cut":
case "paste":
type = typeof(ClipboardEventArgs);
eventArgs = Deserialize<ClipboardEventArgs>(eventArgsJson);
return true;

case "drag":
Expand All @@ -113,20 +109,20 @@ private static bool TryGetStandardWebEventArgsType(string eventName, [MaybeNullW
case "dragover":
case "dragstart":
case "drop":
type = typeof(DragEventArgs);
eventArgs = Deserialize<DragEventArgs>(eventArgsJson);
return true;

case "focus":
case "blur":
case "focusin":
case "focusout":
type = typeof(FocusEventArgs);
eventArgs = Deserialize<FocusEventArgs>(eventArgsJson);
return true;

case "keydown":
case "keyup":
case "keypress":
type = typeof(KeyboardEventArgs);
eventArgs = Deserialize<KeyboardEventArgs>(eventArgsJson);
return true;

case "contextmenu":
Expand All @@ -137,11 +133,11 @@ private static bool TryGetStandardWebEventArgsType(string eventName, [MaybeNullW
case "mousedown":
case "mouseup":
case "dblclick":
type = typeof(MouseEventArgs);
eventArgs = Deserialize<MouseEventArgs>(eventArgsJson);
return true;

case "error":
type = typeof(ErrorEventArgs);
eventArgs = Deserialize<ErrorEventArgs>(eventArgsJson);
return true;

case "loadstart":
Expand All @@ -150,7 +146,7 @@ private static bool TryGetStandardWebEventArgsType(string eventName, [MaybeNullW
case "load":
case "loadend":
case "progress":
type = typeof(ProgressEventArgs);
eventArgs = Deserialize<ProgressEventArgs>(eventArgsJson);
return true;

case "touchcancel":
Expand All @@ -159,7 +155,7 @@ private static bool TryGetStandardWebEventArgsType(string eventName, [MaybeNullW
case "touchenter":
case "touchleave":
case "touchstart":
type = typeof(TouchEventArgs);
eventArgs = Deserialize<TouchEventArgs>(eventArgsJson);
return true;

case "gotpointercapture":
Expand All @@ -172,22 +168,22 @@ private static bool TryGetStandardWebEventArgsType(string eventName, [MaybeNullW
case "pointerout":
case "pointerover":
case "pointerup":
type = typeof(PointerEventArgs);
eventArgs = Deserialize<PointerEventArgs>(eventArgsJson);
return true;

case "wheel":
case "mousewheel":
type = typeof(WheelEventArgs);
eventArgs = Deserialize<WheelEventArgs>(eventArgsJson);
return true;

case "toggle":
type = typeof(EventArgs);
eventArgs = Deserialize<EventArgs>(eventArgsJson);
return true;

default:
// For custom event types, there are no built-in rules, so the deserialization type is
// determined by the parameter declared on the delegate.
type = null;
eventArgs = null;
return false;
}
}
Expand Down