Skip to content
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

Support calling void and "no return" functions in JS #27094

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

mattleibow
Copy link
Member

Description of Change

Currently, the HybridWebView assumes that all functions return a value and immediately tries to deserialize the result.

This PR changes that to first check to see if the value is "null" / "undefined" and then skips the deserialization since those values represent null in .NET.

There is also a new API in the HybridWebView control that provides a way to avoid having to provide a type and type info that will just be ignored.

After this PR, there will be 3 ways to invoke a void functino:

  • hybridWebView.InvokeJavaScriptAsync<TReturn>(name, TReturn info, ...)
    This is the current way, we just no longer crash if the return value is null.
  • hybridWebView.InvokeJavaScriptAsync<TReturn>(name, null, ...)
    This is a better way, we allow passing null as the type info, but we still need the generic argument - which can be anything, object, string, etc
  • hybridWebView.InvokeJavaScriptAsync(name, ...)
    This is the new API where it is not generic and does not have a return type info parameter

Issues Fixed

Fixes #26766

@Copilot Copilot bot review requested due to automatic review settings January 13, 2025 13:21
@mattleibow mattleibow requested a review from a team as a code owner January 13, 2025 13:21
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 4 out of 20 changed files in this pull request and generated 2 comments.

Files not reviewed (16)
  • src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt: Language not supported
  • src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt: Language not supported
  • src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt: Language not supported
  • src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt: Language not supported
  • src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt: Language not supported
  • src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt: Language not supported
  • src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt: Language not supported
  • src/Controls/tests/DeviceTests/Resources/Raw/HybridTestRoot/index.html: Language not supported
  • src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt: Language not supported
  • src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt: Language not supported
  • src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt: Language not supported
  • src/Core/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt: Language not supported
  • src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt: Language not supported
  • src/Core/src/PublicAPI/net/PublicAPI.Unshipped.txt: Language not supported
  • src/Core/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt: Language not supported
  • src/Core/src/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt: Language not supported
Comments suppressed due to low confidence (1)

src/Controls/src/Core/HybridWebView/HybridWebView.cs:84

  • Ensure that the new method InvokeJavaScriptAsync in HybridWebView is covered by tests.
public async Task InvokeJavaScriptAsync(string methodName, object?[]? paramValues = null, JsonTypeInfo?[]? paramJsonTypeInfos = null)

{
invokeJavaScriptRequest.SetResult(null);
}
// if there is no result or if the result was null/undefined, then reat it as null
Copy link
Preview

Copilot AI Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The word 'reat' should be 'treat'.

Suggested change
// if there is no result or if the result was null/undefined, then reat it as null
// if there is no result or if the result was null/undefined, then treat it as null

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -3,11 +3,11 @@

namespace Microsoft.Maui
{
public class HybridWebViewInvokeJavaScriptRequest(string methodName, JsonTypeInfo returnTypeJsonTypeInfo, object?[]? paramValues, JsonTypeInfo?[]? paramJsonTypeInfos)
public class HybridWebViewInvokeJavaScriptRequest(string methodName, JsonTypeInfo? returnTypeJsonTypeInfo, object?[]? paramValues, JsonTypeInfo?[]? paramJsonTypeInfos)
Copy link
Preview

Copilot AI Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change in the constructor signature to accept nullable JsonTypeInfo could be a breaking change. Ensure this is documented appropriately.

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
Comment on lines +84 to +87
public async Task InvokeJavaScriptAsync(
string methodName,
object?[]? paramValues = null,
JsonTypeInfo?[]? paramJsonTypeInfos = null)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new API that makes using it more intuitive and does not have unused parameters.

If we do not want to break ABI with .NET 9.0 GA, we can hide this and maybe the community toolkit an provide some extension methods. The existing method will work, but we have to provide an unused generic argument.

public class HybridWebViewInvokeJavaScriptRequest(string methodName, JsonTypeInfo returnTypeJsonTypeInfo, object?[]? paramValues, JsonTypeInfo?[]? paramJsonTypeInfos)
public class HybridWebViewInvokeJavaScriptRequest(string methodName, JsonTypeInfo? returnTypeJsonTypeInfo, object?[]? paramValues, JsonTypeInfo?[]? paramJsonTypeInfos)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is technically not breaking, so we can do this for .NET 9. Since this change is attribute-only, we could just secretly allow nulls and make this change later. But, since it is not breaking and the number of people creating their own handler for the hybrid web view is probably 0, we can do this and just make everything easier in the future.

Comment on lines -342 to 353
if (stringResult is null)
// if we are not looking for a return object, then return null
if (invokeJavaScriptRequest.ReturnTypeJsonTypeInfo is null)
{
invokeJavaScriptRequest.SetResult(null);
}
// if there is no result or if the result was null/undefined, then reat it as null
else if (stringResult is null || stringResult == "null" || stringResult == "undefined")
{
invokeJavaScriptRequest.SetResult(null);
}
// if we are expecting a result, then deserialize what we have
else
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the real fix, if no type info is provided and/or the return type is null/undefined (from JS) then we just return null in .NET.

@mattleibow mattleibow added this to the .NET 9 SR4 milestone Jan 13, 2025
@mattleibow mattleibow requested a review from Eilon January 13, 2025 13:41
@mattleibow mattleibow added the area-controls-hybridwebview HybridWebView control label Jan 13, 2025
@mattleibow mattleibow self-assigned this Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-hybridwebview HybridWebView control
Projects
Status: Ready To Review
1 participant