@@ -2,13 +2,23 @@ Service Worker PostMessage Setting
22===
33# Background
44
5- This API provides a setting to expose the webview2 specific JS APIs on service worker script.
5+ This API provides a setting to expose the webview2 specific JS APIs on service
6+ worker script.
67
78# Description
89
9- We propose adding the ` WebViewScriptApisForServiceWorkerEnabled ` setting API to control the exposure of WebView2-specific JavaScript APIs in service worker scripts. When enabled, developers can use WebView2's service worker postmessage APIs to communicate directly between service worker scripts and the WebView2 host.
10+ We propose adding the ` AreWebViewScriptApisEnabledForServiceWorkers ` setting
11+ API to control the exposure of WebView2-specific JavaScript APIs in service
12+ worker scripts. When enabled, developers can use WebView2's service worker
13+ postmessage APIs to communicate directly between service worker scripts and
14+ the WebView2 host.
1015
11- Previously, WebView2-specific JavaScript APIs were only exposed to service worker scripts when developers subscribed to the ` ServiceWorkerRegistered ` event. This approach was unreliable because developers could obtain service worker registrations through the ` GetServiceWorkerRegistrations ` API and attempt to use service worker postmessage APIs, which would fail since the JavaScript APIs were not exposed.
16+ Previously, WebView2-specific JavaScript APIs were only exposed to service
17+ worker scripts when developers subscribed to the ` ServiceWorkerRegistered `
18+ event. This approach was unreliable because developers could obtain service
19+ worker registrations through the ` GetServiceWorkerRegistrations ` API and
20+ attempt to use service worker postmessage APIs, which would fail since the
21+ JavaScript APIs were not exposed.
1222
1323# Examples
1424
@@ -40,18 +50,40 @@ void ToggleServiceWorkerJsApiSetting()
4050 CHECK_FAILURE(webViewSettingsStaging->put_IsWebViewScriptApisForServiceWorkerEnabled(!isEnabled));
4151
4252 MessageBox(
43- nullptr ,
53+ reinterpret_cast< HWND >(m_appWindow.Id().Value) ,
4454 (std::wstring(L"Service Worker JS API setting has been ") +
4555 (!isEnabled ? L"enabled." : L"disabled."))
4656 .c_str(),
4757 L"Service Worker JS API Setting", MB_OK);
4858 }
59+ }
4960
50- // Navigate to index.html which will register a new service worker and
51- // check if chrome and webview objects are available in service worker script.
52- m_sampleUri = m_appWindow->GetLocalUri(L"index.html");
53- CHECK_FAILURE (m_webView->Navigate(m_sampleUri.c_str()));
61+ void SetupEventsOnServiceWorker (
62+ wil::com_ptr<ICoreWebView2ExperimentalServiceWorker> serviceWorker)
63+ {
64+ serviceWorker->add_WebMessageReceived(
65+ Callback<ICoreWebView2ExperimentalServiceWorkerWebMessageReceivedEventHandler >(
66+ [ this] (
67+ ICoreWebView2ExperimentalServiceWorker* sender,
68+ ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT
69+ {
70+
71+ wil::unique_cotaskmem_string messageRaw;
72+ CHECK_FAILURE(args->TryGetWebMessageAsString(&messageRaw));
73+ std::wstring messageFromWorker = messageRaw.get();
74+
75+ std::wstringstream message{};
76+ message << L"Message: " << std::endl << messageFromWorker << std::endl;
77+ m_appWindow->AsyncMessageBox(message.str(), L"Message from Service Worker");
5478
79+ return S_OK;
80+ })
81+ .Get(),
82+ nullptr);
83+ }
84+
85+ void SetUpEventsAndNavigate()
86+ {
5587 // Setup WebMessageReceived event to receive message from main thread.
5688 m_webView->add_WebMessageReceived(
5789 Callback<ICoreWebView2WebMessageReceivedEventHandler >(
@@ -65,7 +97,7 @@ void ToggleServiceWorkerJsApiSetting()
6597 {
6698 std::wstringstream message{};
6799 message << L"Message: " << std::endl << L"Service Worker Message from Main thread" << std::endl;
68- m_appWindow->AsyncMessageBox(message.str(), L"Message from Service Worker");
100+ m_appWindow->AsyncMessageBox(message.str(), L"Message from Service Worker (relayed by Main Thread) ");
69101 }
70102 return S_OK;
71103 })
@@ -96,10 +128,6 @@ void ToggleServiceWorkerJsApiSetting()
96128
97129 if (serviceWorkerRegistration)
98130 {
99- wil::unique_cotaskmem_string scopeUri;
100- CHECK_FAILURE (serviceWorkerRegistration->get_ScopeUri(&scopeUri));
101- std::wstring scopeUriStr(scopeUri.get());
102-
103131 wil::com_ptr<ICoreWebView2ExperimentalServiceWorker> serviceWorker;
104132 CHECK_FAILURE(
105133 serviceWorkerRegistration->get_ActiveServiceWorker(&serviceWorker));
@@ -135,32 +163,12 @@ void ToggleServiceWorkerJsApiSetting()
135163 })
136164 .Get(),
137165 &m_serviceWorkerRegisteredToken));
138- }
139166
140- void SetupEventsOnServiceWorker (
141- wil::com_ptr<ICoreWebView2ExperimentalServiceWorker> serviceWorker)
142- {
143- serviceWorker->add_WebMessageReceived(
144- Callback<ICoreWebView2ExperimentalServiceWorkerWebMessageReceivedEventHandler >(
145- [ this] (
146- ICoreWebView2ExperimentalServiceWorker* sender,
147- ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT
148- {
149-
150- wil::unique_cotaskmem_string messageRaw;
151- CHECK_FAILURE(args->TryGetWebMessageAsString(&messageRaw));
152- std::wstring messageFromWorker = messageRaw.get();
153-
154- std::wstringstream message{};
155- message << L"Message: " << std::endl << messageFromWorker << std::endl;
156- m_appWindow->AsyncMessageBox(message.str(), L"Message from Service Worker");
157-
158- return S_OK;
159- })
160- .Get(),
161- nullptr);
167+ // Navigate to index.html which will register a new service worker and
168+ // check if chrome and webview objects are available in service worker script.
169+ m_sampleUri = m_appWindow->GetLocalUri(L"index.html");
170+ CHECK_FAILURE(m_webView->Navigate(m_sampleUri.c_str()));
162171}
163-
164172```
165173
166174**index.html**:
@@ -232,25 +240,76 @@ private void ToggleServiceWorkerJsApiSetting()
232240{
233241 // Unregister every service worker so that for all the newly installed service worker
234242 // the new settings can be applied.
235- webView .CoreWebView2 .ExecuteScriptAsync (
243+ _ = await webView .CoreWebView2 .ExecuteScriptAsync (
236244 @" navigator.serviceWorker.getRegistrations().then(function(registrations) {
237245 for(let registration of registrations) {
238246 registration.unregister();
239247 }
240248 });" );
241249
242250 // Toggle the service worker post message setting.
243- WebViewSettings .IsWebViewScriptApisForServiceWorkerEnabled = ! WebViewSettings .IsWebViewScriptApisForServiceWorkerEnabled ;
251+ var settings = webView .CoreWebView2 .Settings ;
252+ settings .AreWebViewScriptApisEnabledForServiceWorkers = ! settings .AreWebViewScriptApisEnabledForServiceWorkers ;
244253
245254 MessageBox .Show (this ,
246- $" IsWebViewScriptApisForServiceWorkerEnabled is now set to: {WebViewSettings . IsWebViewScriptApisForServiceWorkerEnabled }" ,
255+ $" AreWebViewScriptApisEnabledForServiceWorkers is now set to: {settings . AreWebViewScriptApisEnabledForServiceWorkers }" ,
247256 " Service Worker JS API Setting" , MessageBoxButtons .OK , MessageBoxIcon .Information );
257+ }
258+
259+ private void SetupEventsOnServiceWorker (CoreWebView2ServiceWorker serviceWorker )
260+ {
261+ serviceWorker .WebMessageReceived += (sender , args ) =>
262+ {
263+ string messageFromWorker = args .TryGetWebMessageAsString ();
264+ MessageBox .Show (this , $" Message: \n {messageFromWorker }" , " Message from Service Worker" );
265+ };
266+ }
267+
268+ private void SetUpEventsAndNavigate ()
269+ {
270+ // Setup WebMessageReceived event to receive message from main thread.
271+ webView .CoreWebView2 .WebMessageReceived += (sender , args ) =>
272+ {
273+ string message = args .TryGetWebMessageAsString ();
274+ if (message == " MessageFromMainThread" )
275+ {
276+ MessageBox .Show (this ,
277+ " Message: \n Service Worker Message from Main thread" ,
278+ " Message from Service Worker (relayed by Main Thread)" );
279+ }
280+ };
281+
282+ // Get ServiceWorkerManager from profile and setup events to listen to service worker post messages.
283+ var serviceWorkerManager = webView .CoreWebView2 .Profile .ServiceWorkerManager ;
284+
285+ serviceWorkerManager .ServiceWorkerRegistered += (sender , args ) =>
286+ {
287+ var serviceWorkerRegistration = args .ServiceWorkerRegistration ;
288+
289+ if (serviceWorkerRegistration != null )
290+ {
291+ var serviceWorker = serviceWorkerRegistration .ActiveServiceWorker ;
292+
293+ if (serviceWorker != null )
294+ {
295+ SetupEventsOnServiceWorker (serviceWorker );
296+ }
297+ else
298+ {
299+ serviceWorkerRegistration .ServiceWorkerActivated += (s , e ) =>
300+ {
301+ SetupEventsOnServiceWorker (e .ActiveServiceWorker );
302+ };
303+ }
304+ }
305+ };
248306
249307 // Navigate to index.html which will register a new service worker and
250308 // check if chrome and webview objects are available in service worker script.
251309 sampleUri = GetLocalUri (" index.html" );
252310 webView .CoreWebView2 .Navigate (sampleUri );
253311}
312+
254313```
255314
256315** index.html** and ** service_worker.js** : Same as the Win32 C++ example above.
@@ -259,16 +318,16 @@ private void ToggleServiceWorkerJsApiSetting()
259318
260319## Win32 C++
261320``` cpp
262- interface ICoreWebView2Settings : IUnknown {
263- /// Gets the ` IsWebViewScriptApisForServiceWorkerEnabled ` property.
264- [ propget] HRESULT IsWebViewScriptApisForServiceWorkerEnabled ([ out, retval] BOOL* value);
321+ interface ICoreWebView2Settings10 : ICoreWebView2Settings9 {
322+ /// Gets the ` AreWebViewScriptApisEnabledForServiceWorkers ` property.
323+ [ propget] HRESULT AreWebViewScriptApisEnabledForServiceWorkers ([ out, retval] BOOL* value);
265324
266325 /// Enables or disables webview2 specific Service Worker JS APIs in the WebView2.
267326 /// When set to ` TRUE ` , chrome and webview objects are available in Service Workers .
268327 /// chrome.webview exposes APIs to interact with the WebView from Service Workers.
269328 /// The default value is ` FALSE ` .
270329 /// When enabled, this setting takes effect for all the newly installed Service Workers.
271- [ propput] HRESULT IsWebViewScriptApisForServiceWorkerEnabled ([ in] BOOL value)
330+ [ propput] HRESULT AreWebViewScriptApisEnabledForServiceWorkers ([ in] BOOL value)
272331}
273332
274333```
@@ -279,9 +338,9 @@ namespace Microsoft.Web.WebView2.Core
279338{
280339 runtimeclass CoreWebView2Settings
281340 {
282- [interface_name (" Microsoft.Web.WebView2.Core.ICoreWebView2StagingSettings " )]
341+ [interface_name (" Microsoft.Web.WebView2.Core.ICoreWebView2Settings10 " )]
283342 {
284- Boolean IsWebViewScriptApisForServiceWorkerEnabled { get; set; };
343+ Boolean AreWebViewScriptApisEnabledForServiceWorkers { get; set; };
285344 }
286345 }
287346}
0 commit comments