#nullable enable using System.Diagnostics.CodeAnalysis; using System.Reflection; using Connected.Interop; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; namespace Connected { [ExcludeFromCodeCoverage] public static class ElementReferenceExtensions { private static readonly PropertyInfo? jsRuntimeProperty = typeof(WebElementReferenceContext).GetProperty("JSRuntime", BindingFlags.Instance | BindingFlags.NonPublic); internal static IJSRuntime? GetJSRuntime(this ElementReference elementReference) { if (elementReference.Context is not WebElementReferenceContext context) { return null; } return (IJSRuntime?)jsRuntimeProperty?.GetValue(context); } public static ValueTask FocusFirstAsync(this ElementReference elementReference, int skip = 0, int min = 0) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.focusFirst", elementReference, skip, min) ?? ValueTask.CompletedTask; public static ValueTask FocusLastAsync(this ElementReference elementReference, int skip = 0, int min = 0) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.focusLast", elementReference, skip, min) ?? ValueTask.CompletedTask; public static ValueTask SaveFocusAsync(this ElementReference elementReference) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.saveFocus", elementReference) ?? ValueTask.CompletedTask; public static ValueTask RestoreFocusAsync(this ElementReference elementReference) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.restoreFocus", elementReference) ?? ValueTask.CompletedTask; public static ValueTask BlurAsync(this ElementReference elementReference) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.blur", elementReference) ?? ValueTask.CompletedTask; public static ValueTask SelectAsync(this ElementReference elementReference) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.select", elementReference) ?? ValueTask.CompletedTask; public static ValueTask SelectRangeAsync(this ElementReference elementReference, int pos1, int pos2) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.selectRange", elementReference, pos1, pos2) ?? ValueTask.CompletedTask; public static ValueTask ChangeCssAsync(this ElementReference elementReference, string css) => elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.changeCss", elementReference, css) ?? ValueTask.CompletedTask; public static ValueTask MudGetBoundingClientRectAsync(this ElementReference elementReference) => elementReference.GetJSRuntime()?.InvokeAsync("elementRef.getBoundingClientRect", elementReference) ?? ValueTask.FromResult(new BoundingClientRect()); public static ValueTask AddDefaultPreventingHandlers(this ElementReference elementReference, string[] eventNames) => elementReference.GetJSRuntime()?.InvokeAsync("elementRef.addDefaultPreventingHandlers", elementReference, eventNames) ?? new ValueTask(Array.Empty()); public static ValueTask RemoveDefaultPreventingHandlers(this ElementReference elementReference, string[] eventNames, int[] listenerIds) { if (eventNames.Length != listenerIds.Length) { throw new ArgumentException($"Number of elements in {nameof(eventNames)} and {nameof(listenerIds)} has to match."); } return elementReference.GetJSRuntime()?.InvokeVoidAsync("elementRef.removeDefaultPreventingHandlers", elementReference, eventNames, listenerIds) ?? ValueTask.CompletedTask; } } }