[Feature]: Function to add a simple host function to the object
Describe the feature/enhancement you need
I would like to have a method similar to AddHostObjectToScript but for functions.
Right now, to add simple functions (in my case using WinUI 3) I need to follow the steps from this guide and the Custom (3rd-party) WinRT components section from the same guide to have these projects:
- WinRTAdapter
- Cpp/WinRT component with the following class that handles a function:
FuntionHandler.idl:namespace CppWinRTComponent { runtimeclass FunctionHandler { FunctionHandler(); event Windows.Foundation.EventHandler<String> Function; void InvokeFunction(String payload); }; }FuntionHandler.h:#pragma once #include "CppWinRTComponent.g.h" namespace winrt::CppWinRTComponent::implementation { struct FunctionHandler : FunctionHandlerT<FunctionHandler> { FunctionHandler() = default; winrt::event_token FunctionEvent(winrt::Windows::Foundation::EventHandler<hstring> const& handler); void FunctionEvent(winrt::event_token const& token) noexcept; void InvokeFunction(hstring const& payload); private: winrt::event<Windows::Foundation::EventHandler<hstring>> m_FunctionEvent; }; } namespace winrt::CppWinRTComponent::factory_implementation { struct FunctionHandler : FunctionHandlerT<FunctionHandler, implementation::FunctionHandler> { }; }FuntionHandler.cpp:#include "pch.h" #include "FunctionHandler.h" #include "CppWinRTComponent.g.cpp" namespace winrt::CppWinRTComponent::implementation { winrt::event_token FunctionHandler::FunctionEvent(winrt::Windows::Foundation::EventHandler<hstring> const& handler) { return m_FunctionEvent.add(handler); } void FunctionHandler::FunctionEvent(winrt::event_token const& token) noexcept { m_FunctionEvent.remove(token); } void FunctionHandler::InvokeFunction(hstring const& payload) { m_FunctionEvent(*this, payload); } }
- A component projection project
Finally add the following code to the CoreWebView2Initialized event from the WebView2 control from the main project:
using CppWinRTComponent;
private void CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
var functionHandler = new FunctionHandler();
functionHandler.FunctionEvent += (sender, payload) => Debug.WriteLine($"Function called with the following payload: {payload}");
var dispatchAdapter = new WinRTAdapter.DispatchAdapter();
WebView.CoreWebView2.AddHostObjectToScript("functionHandler", dispatchAdapter.WrapObject(functionHandler, dispatchAdapter));
}
To then call it from JavaScript using the following code:
chrome.webview.hostObjects.sync.functionHandler.InvokeFunction("Hello World!");
As you can see, complex work is required to add a simple function, maybe this work can be simplified.
The scenario/use case where you would use this feature
I would use this feature in the above mentioned scenario
How important is this request to you?
Nice to have. There are other ways to tackle this, but having official API support would be beneficial.
Suggested implementation
A function called AddHostFunctionToScript could be created, so the implementation could look as simple as this:
using CppWinRTComponent;
private void CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
WebView.CoreWebView2.AddHostFunctionToScript(
"addedFunction",
(string payload) => Debug.WriteLine($"Function called with the following payload: {payload}")
);
}
To then call it from JavaScript using the following code:
chrome.webview.hostFunctions.sync.addedFunction("Hello World!");
In .NET, it would need up to 34 method overloads due to the existence of 17 Func delegate types and 17 Action delegate types.
What does your app do? Is there a pending deadline for this request?
No response
Hi @david-risney could you take a look to see if this request is worth considering?
Looping in @nishitha-burman from #3823 as well, as I think this ties into many of the other related issues/requests due to this #2754, #4521, #4664.
I've also just been trying to look at using AddHostObjectToScript from a C# in a WinUI 3 app, I was hoping I could just follow the WPF instructions or something, and surprised I'm having to follow a whole C++ project setup and all these other steps to glue two things together.
With the original WebView in UWP and AddWebAllowedObject this was literally one line and just passing in my C# object from my current project... it's oppressively complex right now to do this.
Also stumbled upon this old issue which seems to highlight some of the issues I've faced in trying to test this from a WinUI 3 app: https://github.com/MicrosoftEdge/WebView2Feedback/issues/2937
We'll look into this. We can do some work to improve docs and samples for the existing solution in the shorter term. To make something work like AddWebAllowedObject is a much larger feature that we can look at.
Kind of out of topic, there's any way native AOT can help to simplify the process to achieve this functionality?