diff --git a/SampleApps/WebView2APISample/AppWindow.cpp b/SampleApps/WebView2APISample/AppWindow.cpp index 02ad74c..1c33cbb 100644 --- a/SampleApps/WebView2APISample/AppWindow.cpp +++ b/SampleApps/WebView2APISample/AppWindow.cpp @@ -39,6 +39,7 @@ #include "ScenarioDedicatedWorker.h" #include "ScenarioDedicatedWorkerPostMessage.h" #include "ScenarioDefaultBackgroundColor.h" +#include "ScenarioDiagnosticMonitor.h" #include "ScenarioDragDrop.h" #include "ScenarioDragDropOverride.h" #include "ScenarioExtensionsManagement.h" @@ -48,12 +49,12 @@ #include "ScenarioNavigateWithWebResourceRequest.h" #include "ScenarioNonClientRegionSupport.h" #include "ScenarioNotificationReceived.h" +#include "ScenarioOriginConfigurationAPI.h" #include "ScenarioPermissionManagement.h" #include "ScenarioServiceWorkerManager.h" #include "ScenarioServiceWorkerPostMessage.h" #include "ScenarioServiceWorkerPostMessageSetting.h" #include "ScenarioSharedWorkerManager.h" -#include "ScenarioOriginConfigurationAPI.h" #include "ScenarioSaveAs.h" #include "ScenarioScreenCapture.h" #include "ScenarioSensitivityLabel.h" @@ -620,6 +621,28 @@ bool AppWindow::ExecuteWebViewCommands(WPARAM wParam, LPARAM lParam) } return true; } + case IDM_SCENARIO_DIAGNOSTIC_CREATE_MONITOR: + { + auto* scenario = GetComponent(); + if (!scenario) + { + NewComponent(this); + scenario = GetComponent(); + } + if (scenario) + { + scenario->CreateMonitorWithDialog(); + } + return true; + } + case IDM_SCENARIO_DIAGNOSTIC_CLEAR_ALL: + { + if (auto* scenario = GetComponent()) + { + scenario->ClearAllMonitors(); + } + return true; + } case IDM_SCENARIO_CUSTOM_SCHEME: { NewComponent(this); diff --git a/SampleApps/WebView2APISample/ScenarioDiagnosticMonitor.cpp b/SampleApps/WebView2APISample/ScenarioDiagnosticMonitor.cpp new file mode 100644 index 0000000..8c858ed --- /dev/null +++ b/SampleApps/WebView2APISample/ScenarioDiagnosticMonitor.cpp @@ -0,0 +1,247 @@ +// 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 "ScenarioDiagnosticMonitor.h" + +#include +#include + +#include "App.h" +#include "CheckFailure.h" +#include "TextInputDialog.h" +#include "Util.h" +#include "resource.h" + +using namespace Microsoft::WRL; + +ScenarioDiagnosticMonitor::ScenarioDiagnosticMonitor(AppWindow* appWindow) + : m_appWindow(appWindow) +{ + wil::com_ptr env16; + HRESULT hr = m_appWindow->GetWebViewEnvironment()->QueryInterface(IID_PPV_ARGS(&env16)); + if (FAILED(hr) || !env16) + { + MessageBox( + m_appWindow->GetMainWindow(), + L"ICoreWebView2ExperimentalEnvironment16 not available. " + L"The Diagnostic API requires a newer WebView2 Runtime.", + L"Diagnostic Monitor", MB_OK); + return; + } + m_environment16 = env16; +} + +ScenarioDiagnosticMonitor::~ScenarioDiagnosticMonitor() +{ + ClearAllMonitors(); +} + +void ScenarioDiagnosticMonitor::CreateMonitorWithDialog() +{ + if (!m_environment16) + { + return; + } + + // Default monitor name. + std::wstringstream defaultName; + defaultName << L"Diagnostic Monitor " << m_nextMonitorId; + + // The filter dialog label is used both as a UI prompt and as the + // lookup key in `dialog.results`, so keep it in a single constant. + // The example matches the JSON schema documented for the + // NETWORK_REQUEST category in environment.idl. + static constexpr wchar_t kFilterLabel[] = + L"Example filter:\r\n" + L"{\r\n" + L" \"errorCode\": [-105, -7],\r\n" + L" \"statusCode\": [404, 500],\r\n" + L" \"uriPattern\": [\"https://*.contoso.com/*\"],\r\n" + L" \"httpMethod\": [\"GET\", \"POST\"]\r\n" + L"}\r\n" + L"\r\n" + L"Match any value within a field (OR).\r\n" + L"All specified fields must match (AND).\r\n" + L"Leave empty to receive all events."; + + // Show a single dialog with monitor name, category dropdown, and JSON filter. + TextInputDialog dialog = TextInputDialog::Builder( + m_appWindow->GetMainWindow(), L"Create Diagnostic Monitor", + L"Configure the monitor and its filter") + .AddTextArea(L"Monitor Name", defaultName.str(), false, 20, 24) + .AddDropDown(L"Category", {L"NETWORK_REQUEST"}, 0) + .AddTextArea(kFilterLabel, L"", false, 170, 80) + .Build(); + + if (!dialog.confirmed) + { + return; + } + + // Read user inputs from the dialog results. + std::wstring monitorName = defaultName.str(); + std::wstring jsonFilter; + + auto nameIt = dialog.results.find(L"Monitor Name"); + if (nameIt != dialog.results.end()) + { + monitorName = std::get