-
Notifications
You must be signed in to change notification settings - Fork 10.5k
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
attachReplacerAPI to enable custom serialization of arguments sent from JavaScript to .NET - Implemented logic to serialize DOM elements as
ElementReferenceobjects using capture IDs - Added comprehensive test coverage to validate round-tripping of
ElementReferencebetween .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
ilonatommy
left a comment
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.
javiercn
left a comment
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
ElementReferenceobjects in JavaScript interop calls between .NET and JS. It does so by adding a mechanism to serialize DOM elements asElementReferenceobjects, 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:
attachReplacerAPI and corresponding infrastructure inMicrosoft.JSInterop.tsto allow custom serialization of arguments sent from JS to .NET, enabling support for returning DOM elements asElementReferenceobjects.ElementReferenceCapture.tsto extract the capture ID from DOM elements and serialize them for interop calls, including support for both receiving and returningElementReferenceinstances.InteropComponent.razorandInteropTest.csto validate round-tripping ofElementReferencebetween .NET and JS, including updates to the test logic and result reporting.Fixes #23369