aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Expose IJSRuntime instance through ElementReference

Open mkArtakMSFT opened this issue 4 years ago • 6 comments

This will help developers to implement their own extension APIs for ElementReference.

mkArtakMSFT avatar Feb 01 '21 17:02 mkArtakMSFT

Thanks for contacting us. We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ghost avatar Feb 01 '21 17:02 ghost

@mkArtakMSFT we deliberately decided not to do this at the time.

Is there any new data to for us to reconsider this decision?

ElementReference is meant to be platform agnostic and IJSRuntime only makes sense in the context of a web application.

In addition to that, we are worried about the broad implications of offering unfettered access to DOM APIs (which this would enable) in terms of potential performance issues.

We agreed at the time that if there was enough requests for something like FocusAsync we would simply add it ourselves.

javiercn avatar Feb 08 '21 15:02 javiercn

Heres a selection of things we use against GetJSRuntime for (currently we have to dig this out with reflection)

Hopefully the function names give you enough info on what we use it for

   public static ValueTask MudFocusFirstAsync(this ElementReference elementReference, int skip = 0, int min = 0) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.focusFirst", elementReference, skip, min) ?? ValueTask.CompletedTask;

        public static ValueTask MudFocusLastAsync(this ElementReference elementReference, int skip = 0, int min = 0) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.focusLast", elementReference, skip, min) ?? ValueTask.CompletedTask;

        public static ValueTask MudSaveFocusAsync(this ElementReference elementReference) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.saveFocus", elementReference) ?? ValueTask.CompletedTask;

        public static ValueTask MudRestoreFocusAsync(this ElementReference elementReference) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.restoreFocus", elementReference) ?? ValueTask.CompletedTask;

        public static ValueTask MudSelectAsync(this ElementReference elementReference) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.select", elementReference) ?? ValueTask.CompletedTask;

        public static ValueTask MudSelectRangeAsync(this ElementReference elementReference, int pos1, int pos2) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.selectRange", elementReference, pos1, pos2) ?? ValueTask.CompletedTask;

        public static ValueTask MudChangeCssAsync(this ElementReference elementReference, string css) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.changeCss", elementReference, css) ?? ValueTask.CompletedTask;

        public static ValueTask<BoundingClientRect> MudGetBoundingClientRectAsync(this ElementReference elementReference) =>
            elementReference.GetJSRuntime()?.InvokeAsync<BoundingClientRect>("mudElementRef.getBoundingClientRect", elementReference) ?? ValueTask.FromResult(new BoundingClientRect());

        public static ValueTask MudChangeCssVariableAsync(this ElementReference elementReference, string variableName, int value) =>
            elementReference.GetJSRuntime()?.InvokeVoidAsync("mudElementRef.changeCssVariable", elementReference, variableName, value) ?? ValueTask.CompletedTask;

mikes-gh avatar Feb 17 '21 20:02 mikes-gh

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost avatar Jul 20 '21 17:07 ghost

This would also be helpful for interfaces like IJSInProcessObjectReference

lskyum avatar Aug 26 '22 06:08 lskyum

Similar discussion https://github.com/dotnet/aspnetcore/issues/47197 (probably can be closed as duplicate)

Current workaround with no performance penalty:

[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<JSRuntime>k__BackingField")]
private static extern ref IJSRuntime GetJsRuntime(WebElementReferenceContext context);

internal static IJSRuntime? GetJSRuntime(this ElementReference elementReference)
{
	if (elementReference.Context is WebElementReferenceContext context)
	{
		var jsRuntime = GetJsRuntime(context);

		return jsRuntime;
	}

	return null;
}

ScarletKuro avatar Oct 19 '24 19:10 ScarletKuro

This is not a direction that we plan to take on the near future for the concerns expressed https://github.com/dotnet/aspnetcore/issues/29826#issuecomment-775246620.

javiercn avatar Sep 06 '25 10:09 javiercn