-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Added replacers to the JSInterop #63542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added replacers to the JSInterop #63542
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request introduces bidirectional support for ElementReference
objects in JavaScript interop calls between .NET and JavaScript. The primary purpose is to enable DOM elements to be serialized and returned as ElementReference
objects from JavaScript to .NET, complementing the existing support for passing ElementReference
from .NET to JavaScript.
Key changes:
- Added a new
attachReplacer
API to enable custom serialization of arguments sent from JavaScript to .NET - Implemented logic to serialize DOM elements as
ElementReference
objects using capture IDs - Added comprehensive test coverage to validate round-tripping of
ElementReference
between .NET and JavaScript
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
Microsoft.JSInterop.ts |
Added attachReplacer API and integrated replacer logic into argument serialization |
jsinteroptests.js |
Added returnElementReference test function to support element reference testing |
InteropComponent.razor |
Added element reference and test logic for round-trip validation |
InteropTest.cs |
Updated test expectations to include element reference success case |
ElementReferenceCapture.ts |
Implemented replacer logic to serialize DOM elements as ElementReference objects |
Co-authored-by: Copilot <[email protected]>
src/Components/test/testassets/BasicTestApp/InteropComponent.razor
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The flow looks logical, I don't have more suggestions for improvements beyond cleaning console.log
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, suggested a few tweaks
DotNet.attachReplacer((key, value) => { | ||
if (value instanceof Element) { | ||
const captureId = getCaptureIdFromElement(value); | ||
if (captureId) { | ||
return { [elementRefKey]: captureId }; | ||
} | ||
} | ||
return value; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is adding some public API that I don't know we want (anything in DotNet
is public API)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of doing it like this, could we "hijack" JSObjectReference
to achieve this?
By that, I mean using the same key as
aspnetcore/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts
Lines 10 to 14 in c821481
const jsObjectIdKey = "__jsObjectId"; | |
const dotNetObjectRefKey = "__dotNetObject"; | |
const byteArrayRefKey = "__byte[]"; | |
const dotNetStreamRefKey = "__dotNetStream"; | |
const jsStreamReferenceLengthKey = "__jsStreamReferenceLength"; |
And then on the C# side (if necessary) have a custom converter for ElementReference
, or have it look for the JSObjectIdKey
too if there's already one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is more about adding an extensibility mechanism to processing values sent from JS to .NET that is symmetrical to "JSON revivers" used in the other direction (when handling arguments coming from .NET to JS). I am also not sure if we want to add that but we should evaluate it in these terms.
Alternatively, if we only care about supporting this use case with ElementReference
, we can reuse the JSObjectReference
ID representation and then special-case handling of Element
instances in createJSCallResult
in Microsoft.JSInterop.ts
(or some other related function, I haven't look at it in detail).
32accf1
to
32847a5
Compare
Added replacers to the JSInterop
Description
This pull request introduces support for returning
ElementReference
objects in JavaScript interop calls between .NET and JS. It does so by adding a mechanism to serialize DOM elements asElementReference
objects, and updates the test infrastructure to validate this new capability. The changes include updates to both the JS runtime and the .NET test components.Changes:
attachReplacer
API and corresponding infrastructure inMicrosoft.JSInterop.ts
to allow custom serialization of arguments sent from JS to .NET, enabling support for returning DOM elements asElementReference
objects.ElementReferenceCapture.ts
to extract the capture ID from DOM elements and serialize them for interop calls, including support for both receiving and returningElementReference
instances.InteropComponent.razor
andInteropTest.cs
to validate round-tripping ofElementReference
between .NET and JS, including updates to the test logic and result reporting.Fixes #23369