Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions SampleApps/WebView2APISample/AppWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
#include "ScenarioCustomDownloadExperience.h"
#include "ScenarioCustomScheme.h"
#include "ScenarioCustomSchemeNavigate.h"
#include "ScenarioDefaultBackgroundColor.h"
#include "ScenarioDOMContentLoaded.h"
#include "ScenarioDedicatedWorker.h"
#include "ScenarioDedicatedWorkerPostMessage.h"
#include "ScenarioDefaultBackgroundColor.h"
#include "ScenarioDragDrop.h"
#include "ScenarioDragDropOverride.h"
#include "ScenarioExtensionsManagement.h"
Expand All @@ -47,10 +49,9 @@
#include "ScenarioNonClientRegionSupport.h"
#include "ScenarioNotificationReceived.h"
#include "ScenarioPermissionManagement.h"
#include "ScenarioDedicatedWorker.h"
#include "ScenarioDedicatedWorkerPostMessage.h"
#include "ScenarioServiceWorkerManager.h"
#include "ScenarioServiceWorkerPostMessage.h"
#include "ScenarioServiceWorkerPostMessageSetting.h"
#include "ScenarioSharedWorkerManager.h"
#include "ScenarioSaveAs.h"
#include "ScenarioScreenCapture.h"
Expand Down Expand Up @@ -821,6 +822,17 @@ bool AppWindow::ExecuteWebViewCommands(WPARAM wParam, LPARAM lParam)
worker_manager->GetAllSharedWorkers();
return true;
}
case IDM_TOGGLE_SERVICE_WORKER_JS_API_SETTING:
{
auto component = GetComponent<ScenarioServiceWorkerPostMessageSetting>();
if (!component)
{
NewComponent<ScenarioServiceWorkerPostMessageSetting>(this);
component = GetComponent<ScenarioServiceWorkerPostMessageSetting>();
}
component->ToggleServiceWorkerJsApiSetting();
return true;
}
case IDM_SCENARIO_SCREEN_CAPTURE:
{
NewComponent<ScenarioScreenCapture>(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Copyright (C) Microsoft Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "stdafx.h"
#include <sstream>

#include "CheckFailure.h"

#include "ScenarioServiceWorkerPostMessageSetting.h"

using namespace Microsoft::WRL;

static constexpr WCHAR c_samplePath[] = L"scenario_sw_post_msg_scope/index2.html";

ScenarioServiceWorkerPostMessageSetting::ScenarioServiceWorkerPostMessageSetting(
AppWindow* appWindow)
: m_appWindow(appWindow), m_webView(appWindow->GetWebView())
{
SetupEventsOnWebview();
}

ScenarioServiceWorkerPostMessageSetting::~ScenarioServiceWorkerPostMessageSetting()
{
UnregisterAllServiceWorkers();
m_webView->remove_ContentLoading(m_contentLoadingToken);
m_webView->remove_WebMessageReceived(m_webMessageReceivedToken);
if (m_serviceWorkerManager)
{
m_serviceWorkerManager->remove_ServiceWorkerRegistered(m_serviceWorkerRegisteredToken);
}
}

void ScenarioServiceWorkerPostMessageSetting::UnregisterAllServiceWorkers()
{
m_webView->ExecuteScript(
L"navigator.serviceWorker.getRegistrations().then(function(registrations) {"
L" for(let registration of registrations) {"
L" registration.unregister();"
L" }"
L"});",
nullptr);
}

void ScenarioServiceWorkerPostMessageSetting::ToggleServiceWorkerJsApiSetting()
{
// Unregister all the existing service workers before toggling the setting.
// So that the setting can be applied to new service workers.
UnregisterAllServiceWorkers();
auto webView2_13 = m_webView.try_query<ICoreWebView2_13>();
CHECK_FEATURE_RETURN_EMPTY(webView2_13);

wil::com_ptr<ICoreWebView2Profile> webView2Profile;
CHECK_FAILURE(webView2_13->get_Profile(&webView2Profile));
auto webViewExperimentalProfile15 =
webView2Profile.try_query<ICoreWebView2ExperimentalProfile15>();

if (webViewExperimentalProfile15)
{
BOOL isEnabled;
//! [AreWebViewScriptApisEnabledForServiceWorkers]
CHECK_FAILURE(
webViewExperimentalProfile15->get_AreWebViewScriptApisEnabledForServiceWorkers(
&isEnabled));
CHECK_FAILURE(
webViewExperimentalProfile15->put_AreWebViewScriptApisEnabledForServiceWorkers(
!isEnabled));
//! [AreWebViewScriptApisEnabledForServiceWorkers]

MessageBox(
nullptr,
(std::wstring(L"Service Worker JS API setting has been ") +
(!isEnabled ? L"enabled." : L"disabled."))
.c_str(),
L"Service Worker JS API Setting", MB_OK);
}

// Setup events on webview2 to listen message from service worker
// main thread.
m_sampleUri = m_appWindow->GetLocalUri(c_samplePath);
CHECK_FAILURE(m_webView->Navigate(m_sampleUri.c_str()));
}

void ScenarioServiceWorkerPostMessageSetting::SetupEventsOnWebview()
{

// Turn off this scenario if we navigate away from the sample page.
CHECK_FAILURE(m_webView->add_ContentLoading(
Callback<ICoreWebView2ContentLoadingEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2ContentLoadingEventArgs* args) -> HRESULT
{
wil::unique_cotaskmem_string uri;
sender->get_Source(&uri);
if (uri.get() != m_sampleUri)
{
m_appWindow->DeleteComponent(this);
}
return S_OK;
})
.Get(),
&m_contentLoadingToken));

// Setup WebMessageReceived event to receive message from main thread.
m_webView->add_WebMessageReceived(
Callback<ICoreWebView2WebMessageReceivedEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
-> HRESULT
{
wil::unique_cotaskmem_string message;
CHECK_FAILURE(args->TryGetWebMessageAsString(&message));

std::wstring msgStr = message.get();
if (msgStr == L"MessageFromMainThread")
{
std::wstringstream message{};
message << L"Message: " << std::endl
<< L"Service Worker Message from Main thread. Service worker "
L"direct messaging disabled."
<< std::endl;
m_appWindow->AsyncMessageBox(message.str(), L"Message from Service Worker");
}
return S_OK;
})
.Get(),
&m_webMessageReceivedToken);

// Get ServiceWorkerManager from profile and setup events to listen to service worker post
// messages.
auto webView2_13 = m_webView.try_query<ICoreWebView2_13>();
CHECK_FEATURE_RETURN_EMPTY(webView2_13);

wil::com_ptr<ICoreWebView2Profile> webView2Profile;
CHECK_FAILURE(webView2_13->get_Profile(&webView2Profile));
auto webViewExperimentalProfile13 =
webView2Profile.try_query<ICoreWebView2ExperimentalProfile13>();
CHECK_FEATURE_RETURN_EMPTY(webViewExperimentalProfile13);
CHECK_FAILURE(
webViewExperimentalProfile13->get_ServiceWorkerManager(&m_serviceWorkerManager));

CHECK_FAILURE(m_serviceWorkerManager->add_ServiceWorkerRegistered(
Callback<ICoreWebView2ExperimentalServiceWorkerRegisteredEventHandler>(
[this](
ICoreWebView2ExperimentalServiceWorkerManager* sender,
ICoreWebView2ExperimentalServiceWorkerRegisteredEventArgs* args)
{
wil::com_ptr<ICoreWebView2ExperimentalServiceWorkerRegistration>
serviceWorkerRegistration;
CHECK_FAILURE(args->get_ServiceWorkerRegistration(&serviceWorkerRegistration));

if (serviceWorkerRegistration)
{
wil::com_ptr<ICoreWebView2ExperimentalServiceWorker> serviceWorker;
CHECK_FAILURE(
serviceWorkerRegistration->get_ActiveServiceWorker(&serviceWorker));

if (serviceWorker)
{
SetupEventsOnServiceWorker(serviceWorker);
}
else
{
CHECK_FAILURE(serviceWorkerRegistration->add_ServiceWorkerActivated(
Callback<
ICoreWebView2ExperimentalServiceWorkerActivatedEventHandler>(
[this](
ICoreWebView2ExperimentalServiceWorkerRegistration* sender,
ICoreWebView2ExperimentalServiceWorkerActivatedEventArgs*
args) -> HRESULT
{
wil::com_ptr<ICoreWebView2ExperimentalServiceWorker>
serviceWorker;
CHECK_FAILURE(
args->get_ActiveServiceWorker(&serviceWorker));
SetupEventsOnServiceWorker(serviceWorker);

return S_OK;
})
.Get(),
nullptr));
}
}

return S_OK;
})
.Get(),
&m_serviceWorkerRegisteredToken));
}

void ScenarioServiceWorkerPostMessageSetting::SetupEventsOnServiceWorker(
wil::com_ptr<ICoreWebView2ExperimentalServiceWorker> serviceWorker)
{
serviceWorker->add_WebMessageReceived(
Callback<ICoreWebView2ExperimentalServiceWorkerWebMessageReceivedEventHandler>(
[this](
ICoreWebView2ExperimentalServiceWorker* sender,
ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT
{
wil::unique_cotaskmem_string messageRaw;
CHECK_FAILURE(args->TryGetWebMessageAsString(&messageRaw));
std::wstring messageFromWorker = messageRaw.get();

std::wstringstream message{};
message << L"Message: " << std::endl << messageFromWorker << std::endl;
m_appWindow->AsyncMessageBox(message.str(), L"Message from Service Worker");

return S_OK;
})
.Get(),
nullptr);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (C) Microsoft Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once
#include "stdafx.h"

#include "AppWindow.h"
#include "ComponentBase.h"

class ScenarioServiceWorkerPostMessageSetting : public ComponentBase
{
public:
ScenarioServiceWorkerPostMessageSetting(AppWindow* appWindow);
~ScenarioServiceWorkerPostMessageSetting() override;
void SetupEventsOnWebview();
void SetupEventsOnServiceWorker(
wil::com_ptr<ICoreWebView2ExperimentalServiceWorker> serviceWorker);

void ToggleServiceWorkerJsApiSetting();
void UnregisterAllServiceWorkers();

private:
AppWindow* m_appWindow;
wil::com_ptr<ICoreWebView2> m_webView;
wil::com_ptr<ICoreWebView2ExperimentalServiceWorkerManager> m_serviceWorkerManager;
std::wstring m_sampleUri;
EventRegistrationToken m_serviceWorkerRegisteredToken = {};
EventRegistrationToken m_contentLoadingToken = {};
EventRegistrationToken m_webMessageReceivedToken = {};
};
80 changes: 58 additions & 22 deletions SampleApps/WebView2APISample/SettingsComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,20 +953,64 @@ bool SettingsComponent::HandleWindowMessage(
//! [ToggleSwipeNavigationEnabled]
return true;
}
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS:
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_NONE:
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_LEFT:
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_CENTER:
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_RIGHT:
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_ALL:
{
//! [ToggleHidePdfToolbarItems]
CHECK_FEATURE_RETURN(m_settings7);

COREWEBVIEW2_PDF_TOOLBAR_ITEMS hiddenPdfToolbarItems;
CHECK_FAILURE(m_settings7->get_HiddenPdfToolbarItems(&hiddenPdfToolbarItems));
if (hiddenPdfToolbarItems ==
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE)
COREWEBVIEW2_PDF_TOOLBAR_ITEMS itemsToHide =
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE;
std::wstring message;

switch (LOWORD(wParam))
{
CHECK_FAILURE(
m_settings7->put_HiddenPdfToolbarItems(
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PRINT |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_SAVE) |
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_NONE:
// Show all items (hide none)
itemsToHide =
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE;
message = L"All PDF toolbar items are shown after the next navigation.";
break;
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_LEFT:
// Left items: Bookmarks
itemsToHide = static_cast<COREWEBVIEW2_PDF_TOOLBAR_ITEMS>(
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_BOOKMARKS);
message =
L"PDF toolbar left items (Bookmarks) are hidden after the next navigation.";
break;
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_CENTER:
// Center items: Page Selector, Zoom In, Zoom Out, Fit Page, Page Layout, Rotate
itemsToHide = static_cast<COREWEBVIEW2_PDF_TOOLBAR_ITEMS>(
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::
COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PAGE_SELECTOR |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_ZOOM_IN |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_ZOOM_OUT |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_FIT_PAGE |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PAGE_LAYOUT |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_ROTATE);
message = L"PDF toolbar center items (Page Selector, Zoom, Fit Page, Page "
L"Layout, Rotate) are hidden after the next navigation.";
break;
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_RIGHT:
// Right items: Search, Print, Save, Full Screen, More Settings
itemsToHide = static_cast<COREWEBVIEW2_PDF_TOOLBAR_ITEMS>(
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_SEARCH |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PRINT |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_SAVE |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_FULL_SCREEN |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::
COREWEBVIEW2_PDF_TOOLBAR_ITEMS_MORE_SETTINGS);
message = L"PDF toolbar right items (Search, Print, Save, Full Screen, More "
L"Settings) are hidden after the next navigation.";
break;
case ID_SETTINGS_TOGGLE_HIDE_PDF_TOOLBAR_ITEMS_ALL:
// All items
itemsToHide = static_cast<COREWEBVIEW2_PDF_TOOLBAR_ITEMS>(
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PRINT |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_SAVE |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_BOOKMARKS |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_FIT_PAGE |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PAGE_LAYOUT |
Expand All @@ -980,20 +1024,12 @@ bool SettingsComponent::HandleWindowMessage(
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_FULL_SCREEN |
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::
COREWEBVIEW2_PDF_TOOLBAR_ITEMS_MORE_SETTINGS);
MessageBox(
nullptr,
L"PDF toolbar print and save buttons are hidden after the next navigation.",
L"Settings change", MB_OK);
}
else
{
CHECK_FAILURE(m_settings7->put_HiddenPdfToolbarItems(
COREWEBVIEW2_PDF_TOOLBAR_ITEMS::COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE));
MessageBox(
nullptr,
L"PDF toolbar print and save buttons are shown after the next navigation.",
L"Settings change", MB_OK);
message = L"All PDF toolbar items are hidden after the next navigation.";
break;
}

CHECK_FAILURE(m_settings7->put_HiddenPdfToolbarItems(itemsToHide));
MessageBox(nullptr, message.c_str(), L"Settings change", MB_OK);
//! [ToggleHidePdfToolbarItems]
return true;
}
Expand Down
Loading
Loading