// 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 Microsoft.JSInterop; using System; namespace Microsoft.AspNetCore.Blazor.Browser.Rendering { /// /// Provides mechanisms for dispatching events to components in a . /// This is marked 'internal' because it only gets invoked from JS code. /// public static class BrowserRendererEventDispatcher { // TODO: Fix this for multi-user scenarios. Currently it doesn't stop people from // triggering events for other people by passing an arbitrary browserRendererId. // // Preferred fix: Instead of storing the Renderer instances in a static dictionary // store them within the context of a Circuit. Then we'll only look up the ones // associated with the caller's circuit. This takes care of ensuring they are // released when the circuit is closed too. // // More generally, we must move away from using statics for any per-user state // now that we have multi-user scenarios. /// /// For framework use only. /// [JSInvokable(nameof(DispatchEvent))] public static void DispatchEvent( BrowserEventDescriptor eventDescriptor, string eventArgsJson) { var eventArgs = ParseEventArgsJson(eventDescriptor.EventArgsType, eventArgsJson); var browserRenderer = BrowserRendererRegistry.CurrentUserInstance.Find(eventDescriptor.BrowserRendererId); browserRenderer.DispatchBrowserEvent( eventDescriptor.ComponentId, eventDescriptor.EventHandlerId, eventArgs); } private static UIEventArgs ParseEventArgsJson(string eventArgsType, string eventArgsJson) { switch (eventArgsType) { case "change": return Json.Deserialize(eventArgsJson); case "clipboard": return Json.Deserialize(eventArgsJson); case "drag": return Json.Deserialize(eventArgsJson); case "error": return Json.Deserialize(eventArgsJson); case "focus": return Json.Deserialize(eventArgsJson); case "keyboard": return Json.Deserialize(eventArgsJson); case "mouse": return Json.Deserialize(eventArgsJson); case "pointer": return Json.Deserialize(eventArgsJson); case "progress": return Json.Deserialize(eventArgsJson); case "touch": return Json.Deserialize(eventArgsJson); case "unknown": return Json.Deserialize(eventArgsJson); case "wheel": return Json.Deserialize(eventArgsJson); default: throw new ArgumentException($"Unsupported value '{eventArgsType}'.", nameof(eventArgsType)); } } /// /// For framework use only. /// public class BrowserEventDescriptor { /// /// For framework use only. /// public int BrowserRendererId { get; set; } /// /// For framework use only. /// public int ComponentId { get; set; } /// /// For framework use only. /// public int EventHandlerId { get; set; } /// /// For framework use only. /// public string EventArgsType { get; set; } } } }