@@ -36,8 +36,8 @@ void ToggleServiceWorkerJsApiSetting()
3636 {
3737 // Toggle the service worker post message setting.
3838 BOOL isEnabled;
39- CHECK_FAILURE (webViewSettingsStaging->get_IsServiceWorkerJSAPIsEnabled (&isEnabled));
40- CHECK_FAILURE(webViewSettingsStaging->put_IsServiceWorkerJSAPIsEnabled (!isEnabled));
39+ CHECK_FAILURE (webViewSettingsStaging->get_IsWebViewScriptApisForServiceWorkerEnabled (&isEnabled));
40+ CHECK_FAILURE(webViewSettingsStaging->put_IsWebViewScriptApisForServiceWorkerEnabled (!isEnabled));
4141
4242 MessageBox(
4343 nullptr,
@@ -51,6 +51,114 @@ void ToggleServiceWorkerJsApiSetting()
5151 // check if chrome and webview objects are available in service worker script.
5252 m_sampleUri = m_appWindow->GetLocalUri(L"index.html");
5353 CHECK_FAILURE (m_webView->Navigate(m_sampleUri.c_str()));
54+
55+ // Setup WebMessageReceived event to receive message from main thread.
56+ m_webView->add_WebMessageReceived(
57+ Callback<ICoreWebView2WebMessageReceivedEventHandler>(
58+ [this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT
59+ {
60+ wil::unique_cotaskmem_string message;
61+ CHECK_FAILURE (args->TryGetWebMessageAsString(&message));
62+
63+ std::wstring msgStr = message.get();
64+ if (msgStr == L"MessageFromMainThread")
65+ {
66+ std::wstringstream message{};
67+ 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");
69+ }
70+ return S_OK;
71+ })
72+ .Get(),
73+ &m_webMessageReceivedToken);
74+
75+ // Get ServiceWorkerManager from profile and setup events to listen to service worker post messages.
76+ auto webView2_13 = m_webView.try_query<ICoreWebView2_13>();
77+ CHECK_FEATURE_RETURN_EMPTY (webView2_13);
78+
79+ wil::com_ptr<ICoreWebView2Profile> webView2Profile;
80+ CHECK_FAILURE (webView2_13->get_Profile(&webView2Profile));
81+ auto webViewExperimentalProfile13 =
82+ webView2Profile.try_query<ICoreWebView2ExperimentalProfile13 >();
83+ CHECK_FEATURE_RETURN_EMPTY(webViewExperimentalProfile13);
84+ CHECK_FAILURE(
85+ webViewExperimentalProfile13->get_ServiceWorkerManager(&m_serviceWorkerManager));
86+
87+ CHECK_FAILURE (m_serviceWorkerManager->add_ServiceWorkerRegistered(
88+ Callback<ICoreWebView2ExperimentalServiceWorkerRegisteredEventHandler >(
89+ [ this] (
90+ ICoreWebView2ExperimentalServiceWorkerManager* sender,
91+ ICoreWebView2ExperimentalServiceWorkerRegisteredEventArgs* args)
92+ {
93+ wil::com_ptr<ICoreWebView2ExperimentalServiceWorkerRegistration >
94+ serviceWorkerRegistration;
95+ CHECK_FAILURE(args->get_ServiceWorkerRegistration(&serviceWorkerRegistration));
96+
97+ if (serviceWorkerRegistration)
98+ {
99+ wil::unique_cotaskmem_string scopeUri;
100+ CHECK_FAILURE (serviceWorkerRegistration->get_ScopeUri(&scopeUri));
101+ std::wstring scopeUriStr(scopeUri.get());
102+
103+ wil::com_ptr<ICoreWebView2ExperimentalServiceWorker> serviceWorker;
104+ CHECK_FAILURE (
105+ serviceWorkerRegistration->get_ActiveServiceWorker(&serviceWorker));
106+
107+ if (serviceWorker)
108+ {
109+ SetupEventsOnServiceWorker (serviceWorker);
110+ }
111+ else
112+ {
113+ CHECK_FAILURE(serviceWorkerRegistration->add_ServiceWorkerActivated(
114+ Callback<
115+ ICoreWebView2ExperimentalServiceWorkerActivatedEventHandler>(
116+ [ this] (
117+ ICoreWebView2ExperimentalServiceWorkerRegistration* sender,
118+ ICoreWebView2ExperimentalServiceWorkerActivatedEventArgs*
119+ args) -> HRESULT
120+ {
121+ wil::com_ptr<ICoreWebView2ExperimentalServiceWorker >
122+ serviceWorker;
123+ CHECK_FAILURE(
124+ args->get_ActiveServiceWorker(&serviceWorker));
125+ SetupEventsOnServiceWorker(serviceWorker);
126+
127+ return S_OK;
128+ })
129+ .Get(),
130+ nullptr));
131+ }
132+ }
133+
134+ return S_OK;
135+ })
136+ .Get(),
137+ &m_serviceWorkerRegisteredToken));
138+ }
139+
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);
54162}
55163
56164```
@@ -88,41 +196,31 @@ void ToggleServiceWorkerJsApiSetting()
88196 navigator.serviceWorker.addEventListener('message', function(event) {
89197 console.log("Message received from service worker:", event.data);
90198
91- // Display the result in the HTML element
92- const resultElement = document .getElementById (' result' );
93- if (event .data === ' chromeWebViewAvailable' ) {
94- resultElement .textContent = ' chrome.webview is AVAILABLE in Service Worker' ;
95- resultElement .style .color = ' green' ;
96- } else if (event .data === ' chromeWebViewNotAvailable' ) {
97- resultElement .textContent = ' chrome.webview is NOT AVAILABLE in Service Worker' ;
98- resultElement .style .color = ' red' ;
99- } else {
100- resultElement .textContent = ' Received: ' + event .data ;
101- resultElement .style .color = ' blue' ;
199+ if (event.data === 'chromeWebViewNotAvailable') {
200+ self.chrome.webview.postMessage('MessageFromMainThread');
102201 }
103202 });
104203 </script>
105204</head>
106205<body>
107206 <h1>Service Worker Post Message Setting</h1>
108207 <p>This page registers a service worker, posts a message to it, and listens for responses.</p>
109- <p >Check the console for debug information.</p >
110- <div id =" result" style =" font-size : 18px ; font-weight : bold ; margin-top : 20px ; padding : 10px ; border : 2px solid #ccc ; border-radius : 5px ;" >
111- Waiting for service worker response...
112- </div >
113208</body>
114209</html>
115210```
116211
117212** service_worker.js**
118213``` js
119214self .addEventListener (' message' , (event ) => {
120- if (event .data .command === ' CHECK_CHROME_WEBVIEW' ) {
121- if (self .chrome && self .chrome .webview ) {
122- event .source .postMessage (' chromeWebViewAvailable' );
123- } else {
124- event .source .postMessage (' chromeWebViewNotAvailable' );
125- }
215+ if (self .chrome && self .chrome .webview ) {
216+ event .source .postMessage (' chromeWebViewAvailable' );
217+ // When self.chrome.webview is available, message can be directly posted
218+ // to service worker object on host.
219+ self .chrome .webview .postMessage (' Service Worker Message directly from service worker thread' );
220+ } else {
221+ // When self.chrome.webview is not available, message can be posted back
222+ // to main thread, which can then forward it to host.
223+ event .source .postMessage (' chromeWebViewNotAvailable' );
126224 }
127225});
128226```
@@ -142,10 +240,10 @@ private void ToggleServiceWorkerJsApiSetting()
142240 });" );
143241
144242 // Toggle the service worker post message setting.
145- WebViewSettings .IsServiceWorkerJSAPIsEnabled = ! WebViewSettings .IsServiceWorkerJSAPIsEnabled ;
243+ WebViewSettings .IsWebViewScriptApisForServiceWorkerEnabled = ! WebViewSettings .IsWebViewScriptApisForServiceWorkerEnabled ;
146244
147245 MessageBox .Show (this ,
148- $" IsServiceWorkerJSAPIsEnabled is now set to: {WebViewSettings .IsServiceWorkerJSAPIsEnabled }" ,
246+ $" IsWebViewScriptApisForServiceWorkerEnabled is now set to: {WebViewSettings .IsWebViewScriptApisForServiceWorkerEnabled }" ,
149247 " Service Worker JS API Setting" , MessageBoxButtons .OK , MessageBoxIcon .Information );
150248
151249 // Navigate to index.html which will register a new service worker and
@@ -162,15 +260,15 @@ private void ToggleServiceWorkerJsApiSetting()
162260## Win32 C++
163261``` cpp
164262interface ICoreWebView2Settings : IUnknown {
165- /// Gets the ` IsServiceWorkerJSAPIsEnabled ` property.
166- [ propget] HRESULT IsServiceWorkerJSAPIsEnabled ([ out, retval] BOOL* value);
263+ /// Gets the ` IsWebViewScriptApisForServiceWorkerEnabled ` property.
264+ [ propget] HRESULT IsWebViewScriptApisForServiceWorkerEnabled ([ out, retval] BOOL* value);
167265
168266 /// Enables or disables webview2 specific Service Worker JS APIs in the WebView2.
169267 /// When set to ` TRUE ` , chrome and webview objects are available in Service Workers .
170268 /// chrome.webview exposes APIs to interact with the WebView from Service Workers.
171269 /// The default value is ` FALSE ` .
172270 /// When enabled, this setting takes effect for all the newly installed Service Workers.
173- [ propput] HRESULT IsServiceWorkerJSAPIsEnabled ([ in] BOOL value)
271+ [ propput] HRESULT IsWebViewScriptApisForServiceWorkerEnabled ([ in] BOOL value)
174272}
175273
176274```
@@ -183,7 +281,7 @@ namespace Microsoft.Web.WebView2.Core
183281 {
184282 [interface_name (" Microsoft.Web.WebView2.Core.ICoreWebView2StagingSettings" )]
185283 {
186- Boolean IsServiceWorkerJSAPIsEnabled { get; set; };
284+ Boolean IsWebViewScriptApisForServiceWorkerEnabled { get; set; };
187285 }
188286 }
189287}
0 commit comments