Skip to content
Open
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
6 changes: 6 additions & 0 deletions SampleApps/WebView2APISample/AppWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include "ScenarioSaveAs.h"
#include "ScenarioScreenCapture.h"
#include "ScenarioSensitivityLabel.h"
#include "ScenarioServiceWorkerWRR.h"
#include "ScenarioSharedBuffer.h"
#include "ScenarioSharedWorkerWRR.h"
#include "ScenarioThrottlingControl.h"
Expand Down Expand Up @@ -611,6 +612,11 @@ bool AppWindow::ExecuteWebViewCommands(WPARAM wParam, LPARAM lParam)
NewComponent<ScenarioSharedWorkerWRR>(this);
return true;
}
case IDM_SCENARIO_SERVICE_WORKER_WRR:
{
NewComponent<ScenarioServiceWorkerWRR>(this);
return true;
}
case IDM_SCENARIO_SHARED_BUFFER:
{
NewComponent<ScenarioSharedBuffer>(this);
Expand Down
3 changes: 2 additions & 1 deletion SampleApps/WebView2APISample/AppWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ class AppWindow
{
return m_webviewOption;
}

private:
static PCWSTR GetWindowClass();

Expand Down Expand Up @@ -291,6 +290,7 @@ class AppWindow

bool m_CustomCrashReportingEnabled = false;
bool m_TrackingPreventionEnabled = true;
private:
// Fullscreen related code
RECT m_previousWindowRect;
HMENU m_hMenu;
Expand All @@ -299,6 +299,7 @@ class AppWindow
bool m_isPopupWindow = false;
void EnterFullScreen();
void ExitFullScreen();

// Compositor creation helper methods
HRESULT DCompositionCreateDevice2(IUnknown* renderingDevice, REFIID riid, void** ppv);
HRESULT TryCreateDispatcherQueue();
Expand Down
100 changes: 100 additions & 0 deletions SampleApps/WebView2APISample/ScenarioServiceWorkerWRR.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// 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 "ScenarioServiceWorkerWRR.h"

#include "AppWindow.h"
#include "CheckFailure.h"

#include "shlwapi.h"

using namespace Microsoft::WRL;

static constexpr WCHAR c_samplePath[] =
L"https://mdn.github.io/dom-examples/service-worker/simple-service-worker/";
static constexpr WCHAR c_wrrUrlPattern[] = L"*";

ScenarioServiceWorkerWRR::ScenarioServiceWorkerWRR(AppWindow* appWindow)
: m_appWindow(appWindow), m_webView(appWindow->GetWebView()), m_sampleUri(c_samplePath)
{
wil::com_ptr<ICoreWebView2_22> webView_22 = m_webView.try_query<ICoreWebView2_22>();
CHECK_FEATURE_RETURN_EMPTY(webView_22);

webView_22->AddWebResourceRequestedFilterWithRequestSourceKinds(
c_wrrUrlPattern, COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL,
COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_ALL);
webView_22->add_WebResourceRequested(
Callback<ICoreWebView2WebResourceRequestedEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2WebResourceRequestedEventArgs* args)
-> HRESULT
{
COREWEBVIEW2_WEB_RESOURCE_CONTEXT resourceContext;
args->get_ResourceContext(&resourceContext);
wil::com_ptr<ICoreWebView2WebResourceRequest> request;
CHECK_FAILURE(args->get_Request(&request));
wil::unique_cotaskmem_string uri;
CHECK_FAILURE(request->get_Uri(&uri));
if (wcscmp(uri.get(), c_samplePath) != 0)
{
return S_OK;
}

wil::com_ptr<IStream> stream;
// Create a stream with some text content
std::string content = "<html><head><script>"
"navigator.serviceWorker.register('sw.js')"
"</script></head><body><h1>Response from WV2 "
"interceptor!</h1></body></html>";

stream.attach(SHCreateMemStream(
reinterpret_cast<const BYTE*>(content.c_str()),
static_cast<UINT>(content.size())));

wil::com_ptr<ICoreWebView2WebResourceResponse> response;
wil::com_ptr<ICoreWebView2Environment> environment;
wil::com_ptr<ICoreWebView2_2> webview2;
m_webView->QueryInterface(IID_PPV_ARGS(&webview2));
webview2->get_Environment(&environment);
environment->CreateWebResourceResponse(
stream.get(), 200, L"OK", L"Content-Type: text/html", &response);
args->put_Response(response.get());
return S_OK;
})
.Get(),
&m_webResourceRequestedToken);

// 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));

CHECK_FAILURE(m_webView->Navigate(m_sampleUri.c_str()));
}

ScenarioServiceWorkerWRR::~ScenarioServiceWorkerWRR()
{
wil::com_ptr<ICoreWebView2_22> webView_22 = m_webView.try_query<ICoreWebView2_22>();
if (webView_22)
{
CHECK_FAILURE(webView_22->RemoveWebResourceRequestedFilterWithRequestSourceKinds(
c_wrrUrlPattern, COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL,
COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_ALL));
}

CHECK_FAILURE(m_webView->remove_WebResourceRequested(m_webResourceRequestedToken));
m_webView->remove_ContentLoading(m_contentLoadingToken);
}
26 changes: 26 additions & 0 deletions SampleApps/WebView2APISample/ScenarioServiceWorkerWRR.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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 <string>

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

// This sample demonstrates how to intercept Service Worker requests with
// WebResourceRequested event.
class ScenarioServiceWorkerWRR : public ComponentBase
{
public:
ScenarioServiceWorkerWRR(AppWindow* appWindow);
~ScenarioServiceWorkerWRR() override;

private:
AppWindow* m_appWindow;
wil::com_ptr<ICoreWebView2> m_webView;
std::wstring m_sampleUri;
EventRegistrationToken m_contentLoadingToken = {};
EventRegistrationToken m_webResourceRequestedToken = {};
};
11 changes: 7 additions & 4 deletions SampleApps/WebView2APISample/WebView2APISample.rc
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,13 @@ BEGIN
MENUITEM "Install Default Extensions", IDM_SCENARIO_EXTENSIONS_MANAGEMENT_INSTALL_DEFAULT
MENUITEM "Offload Default Extensions", IDM_SCENARIO_EXTENSIONS_MANAGEMENT_OFFLOAD_DEFAULT
END
MENUITEM "Custom scheme WebResourceRequested CORS", IDM_SCENARIO_CUSTOM_SCHEME
MENUITEM "Navigate to custom scheme via WebResourceRequested", IDM_SCENARIO_CUSTOM_SCHEME_NAVIGATE
MENUITEM "Shared worker WebResourceRequested", IDM_SCENARIO_SHARED_WORKER
POPUP "WebResourceRequested"
BEGIN
MENUITEM "Custom scheme WebResourceRequested CORS", IDM_SCENARIO_CUSTOM_SCHEME
MENUITEM "Navigate to custom scheme via WebResourceRequested", IDM_SCENARIO_CUSTOM_SCHEME_NAVIGATE
MENUITEM "Service worker WebResourceRequested", IDM_SCENARIO_SERVICE_WORKER_WRR
MENUITEM "Shared worker WebResourceRequested", IDM_SCENARIO_SHARED_WORKER
END
POPUP "Custom Download Experience"
BEGIN
MENUITEM "Use Deferred Download Dialog", IDM_SCENARIO_USE_DEFERRED_DOWNLOAD
Expand Down Expand Up @@ -297,7 +301,6 @@ BEGIN
MENUITEM "Web Messaging", IDM_SCENARIO_POST_WEB_MESSAGE
MENUITEM "WebView Event Monitor", IDM_SCENARIO_WEB_VIEW_EVENT_MONITOR
MENUITEM "WebView Window Controls Overlay", IDM_SCENARIO_WINDOW_CONTROLS_OVERLAY

MENUITEM "Dropped file path", IDM_SCENARIO_DROPPED_FILE_PATH
POPUP "Save As"
BEGIN
Expand Down
9 changes: 7 additions & 2 deletions SampleApps/WebView2APISample/WebView2APISample.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@
<ClInclude Include="ScenarioSensitivityLabel.h" />
<ClInclude Include="ScenarioServiceWorkerManager.h" />
<ClInclude Include="ScenarioServiceWorkerPostMessage.h" />
<ClInclude Include="ScenarioServiceWorkerWRR.h" />
<ClInclude Include="ScenarioSharedBuffer.h" />
<ClInclude Include="ScenarioSharedWorkerManager.h" />
<ClInclude Include="ScenarioSharedWorkerWRR.h" />
Expand Down Expand Up @@ -315,6 +316,7 @@
<ClCompile Include="ScenarioSensitivityLabel.cpp" />
<ClCompile Include="ScenarioServiceWorkerManager.cpp" />
<ClCompile Include="ScenarioServiceWorkerPostMessage.cpp" />
<ClCompile Include="ScenarioServiceWorkerWRR.cpp" />
<ClCompile Include="ScenarioSharedBuffer.cpp" />
<ClCompile Include="ScenarioSharedWorkerManager.cpp" />
<ClCompile Include="ScenarioSharedWorkerWRR.cpp" />
Expand Down Expand Up @@ -451,6 +453,9 @@
<CopyFileToFolders Include="assets/ScenarioThrottlingControlMonitor.js">
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
</CopyFileToFolders>
<CopyFileToFolders Include="assets/ScenarioWebrtcUdpPortConfiguration.html">
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
</CopyFileToFolders>
<CopyFileToFolders Include="assets/ScenarioWindowControlsOverlay.html">
<DestinationFolders>$(OutDir)\assets</DestinationFolders>
</CopyFileToFolders>
Expand Down Expand Up @@ -525,13 +530,13 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.3590-prerelease\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.3590-prerelease\build\native\Microsoft.Web.WebView2.targets')" />
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.3650-prerelease\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.3650-prerelease\build\native\Microsoft.Web.WebView2.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.3590-prerelease\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.3590-prerelease\build\native\Microsoft.Web.WebView2.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.3650-prerelease\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.3650-prerelease\build\native\Microsoft.Web.WebView2.targets'))" />
</Target>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,119 +2,69 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Sensitivity Label Changed Scenario</title>
<title>Sensitivity Label API Sample</title>
<link rel="stylesheet" href="ScenarioSensitivityLabelChanged.css">
</head>
<body>
<div class="container">
<h1>Sensitivity Label Changed Event Scenario</h1>
<h1>Sensitivity Label API Sample</h1>

<!-- Info box for the feature -->
<div class="info-box">
<h3>About This Scenario</h3>
<p>This scenario demonstrates the <strong>SensitivityLabelChanged</strong> event in WebView2. This event is fired when the sensitivity label of the document changes, typically used in Microsoft Information Protection (MIP) scenarios.</p>

<p>The WebView2 control has registered an event handler that will show a popup dialog whenever a sensitivity label change is detected.</p>
</div>

<div id="pirmWarningBox" class="error-box" style="display: none;">
<h3>❌ PageInteractionRestrictionManager Not Available</h3>
<p><strong>The navigator.pageInteractionRestrictionManager API is not available on this page.</strong></p>
<p>To enable this API, you need to add this URL to the PageInteractionRestrictionManager allowlist:</p>
<div class="code">
<strong>URL to Add:</strong> <span id="currentUrl"></span>
</div>
<p><strong>How to fix:</strong></p>
<ol>
<li>Go to <strong>Scenario → Sensitivity Label → Set Allowlist</strong> in the menu</li>
<li>Add the URL shown above to the allowlist</li>
<li>Refresh this page to try again</li>
</ol>
<h3>About This Sample</h3>
<p>This sample demonstrates how to use the <strong>PageInteractionRestrictionManager API</strong> to add and remove sensitivity labels, which triggers the <strong>SensitivityInfoChanged</strong> event in WebView2.</p>
</div>

<div id="pirmAvailableBox" class="info-box" style="display: none;">
<h3>✅ PageInteractionRestrictionManager Available</h3>
<p>The navigator.pageInteractionRestrictionManager API is available and ready to use!</p>
<!-- Status box for API availability -->
<div id="pirmStatus" class="status-box">
<h3>API Status</h3>
<p id="pirmStatusText">Checking PageInteractionRestrictionManager availability...</p>
</div>

<!-- Form for adding sensitivity labels -->
<div class="form-container">
<h3>Add Sensitivity Label</h3>
<p>Enter the Label ID GUID and Organization ID GUID to apply a sensitivity label to this page:</p>

<div class="form-group">
<label for="labelIdInput">Label ID GUID:</label>
<input type="text" id="labelIdInput" placeholder="e.g., 12345678-1234-1234-1234-123456789abc" />
</div>

<div class="form-group">
<label for="orgIdInput">Organization ID GUID:</label>
<input type="text" id="orgIdInput" placeholder="e.g., 87654321-4321-4321-4321-cba987654321" />
</div>

<button id="addLabelBtn" onclick="applySensitivityLabel()">Add Sensitivity Label</button>
<label for="labelId">Label ID GUID:</label>
<input type="text" id="labelId" placeholder="12345678-1234-1234-1234-123456789abc" />

<div id="resultBox" class="result-box">
<strong>Success:</strong> <span id="resultMessage"></span>
</div>
<label for="orgId">Organization ID GUID:</label>
<input type="text" id="orgId" placeholder="87654321-4321-4321-4321-cba987654321" />

<div id="errorBox" class="error-box">
<strong>Error:</strong> <span id="errorMessage"></span>
</div>
<button onclick="addLabel()">Add Label</button>
</div>

<!-- Form for removing sensitivity labels -->
<div class="form-container">
<h3>Remove Sensitivity Label</h3>
<p>Select a label ID from the list below to remove an existing sensitivity label:</p>
<label for="labelSelect">Select Label to Remove:</label>
<select id="labelSelect">
<option value="">No labels available</option>
</select>

<div class="form-group">
<label for="removeLabelSelect">Select Label ID to Remove:</label>
<select id="removeLabelSelect" disabled>
<option value="">No labels available</option>
</select>
</div>

<button id="removeLabelBtn" onclick="removeSensitivityLabel()" disabled>Remove Selected Label</button>
<button onclick="removeLabel()">Remove Label</button>
</div>

<h3>Test the Event</h3>
<p>The sample app scenario can be tested with the following steps:</p>
<ol>
<li>Enter valid Label ID GUID and Organization ID GUID in the "Add Sensitivity Label" form above</li>
<li>Click the "Add Sensitivity Label" button to apply a label (you can add multiple labels with different IDs)</li>
<li>Select a label ID from the dropdown in the "Remove Sensitivity Label" section</li>
<li>Click the "Remove Selected Label" button to remove the chosen label</li>
<li>Observe the popup dialog that appears when the SensitivityLabelChanged event fires for both add and remove operations</li>
<li>Alternatively, navigate to a document or website that supports Microsoft Information Protection</li>
</ol>
<!-- Logs of actions -->
<div>
<h3>Last Operation Status</h3>
<p id="output" class="output"></p>
</div>

<div class="code">
<h4>JavaScript API Calls:</h4>
<!-- Code sample for API usage -->
<div class="code-sample">
<h3>API Usage</h3>
<pre>
// API call for adding a label (executed when you click "Add Sensitivity Label")
let lm = await navigator.pageInteractionRestrictionManager.requestLabelManager();
let label_ = await lm.addLabel('MicrosoftSensitivityLabel', {
// Add a sensitivity label
const labelManager = await navigator.pageInteractionRestrictionManager.requestLabelManager();
const label = await labelManager.addLabel('MicrosoftSensitivityLabel', {
label: 'your-label-guid',
organization: 'your-org-guid'
});

// API call for removing a label (executed when you click "Remove Sensitivity Label")
// Note: remove() is called on the label object returned by addLabel
let result = await label_.remove();

// Both operations will trigger the SensitivityLabelChanged event in the WebView2 control
// Remove a sensitivity label
await label.remove();
</pre>
</div>

<h3>Event Handler Details</h3>
<p>The C++ event handler registered for this scenario:</p>
<ul>
<li>Captures the new sensitivity label value</li>
<li>Shows a popup dialog with the label information</li>
<li>Includes timestamp for when the event occurred</li>
<li>Provides context about Microsoft Information Protection</li>
</ul>

<p><em>Navigate to a page with Microsoft Information Protection to see the event in action!</em></p>

</div>

<script src="ScenarioSensitivityLabelChanged.js"></script>
Expand Down
Loading
Loading