Skip to content

Commit

Permalink
[Blazor] Support conditionally enabling developer tools
Browse files Browse the repository at this point in the history
* Disables developer tools by default.
* Adds a new method to enable developer tools
* Adds platform specific service registration methods on the service container
* Updates the Blazor template to enable developer tools only in Debug
  • Loading branch information
javiercn authored Mar 7, 2022
1 parent 5d08654 commit cfc3fab
Show file tree
Hide file tree
Showing 21 changed files with 208 additions and 47 deletions.
11 changes: 9 additions & 2 deletions src/BlazorWebView/samples/BlazorWinFormsApp/Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ public partial class Form1 : Form
public Form1()
{
var services1 = new ServiceCollection();
services1.AddBlazorWebView();
services1.AddWindowsFormsBlazorWebView();
#if DEBUG
services1.AddBlazorWebViewDeveloperTools();
#endif
services1.AddSingleton<AppState>(_appState);

var services2 = new ServiceCollection();
services2.AddBlazorWebView();
services2.AddWindowsFormsBlazorWebView();
#if DEBUG
services2.AddBlazorWebViewDeveloperTools();
#endif

services2.AddSingleton<AppState>(_appState);

InitializeComponent();
Expand Down
12 changes: 10 additions & 2 deletions src/BlazorWebView/samples/BlazorWpfApp/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ public partial class MainWindow : Window
public MainWindow()
{
var services1 = new ServiceCollection();
services1.AddBlazorWebView();
services1.AddWpfBlazorWebView();
#if DEBUG
services1.AddBlazorWebViewDeveloperTools();
#endif

services1.AddSingleton<AppState>(_appState);
Resources.Add("services1", services1.BuildServiceProvider());

var services2 = new ServiceCollection();
services2.AddBlazorWebView();
services2.AddWpfBlazorWebView();
#if DEBUG
services2.AddBlazorWebViewDeveloperTools();
#endif

services2.AddSingleton<AppState>(_appState);
Resources.Add("services2", services2.BuildServiceProvider());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using Android.Webkit;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using AWebView = Android.Webkit.WebView;
using AUri = Android.Net.Uri;
Expand Down Expand Up @@ -33,6 +34,14 @@ public class AndroidWebKitWebViewManager : WebViewManager
public AndroidWebKitWebViewManager(AWebView webview!!, IServiceProvider services, Dispatcher dispatcher, IFileProvider fileProvider, JSComponentConfigurationStore jsComponents, string hostPageRelativePath)
: base(services, dispatcher, new Uri(AppOrigin), fileProvider, jsComponents, hostPageRelativePath)
{
#if WEBVIEW2_MAUI
if (services.GetService<MauiBlazorMarkerService>() is null)
{
throw new InvalidOperationException(
"Unable to find the required services. " +
$"Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(BlazorWebViewServiceCollectionExtensions.AddMauiBlazorWebView)}' in the application startup code.");
}
#endif
_webview = webview;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ protected override BlazorAndroidWebView CreatePlatformView()
// To allow overriding ExternalLinkMode.InsecureOpenInWebView and open links in browser with a _blank target
blazorAndroidWebView.Settings.SetSupportMultipleWindows(true);

BlazorAndroidWebView.SetWebContentsDebuggingEnabled(enabled: true);
BlazorAndroidWebView.SetWebContentsDebuggingEnabled(enabled: DeveloperTools.Enabled);

if (blazorAndroidWebView.Settings != null)
{
Expand Down
5 changes: 4 additions & 1 deletion src/BlazorWebView/src/Maui/BlazorWebViewHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Microsoft.AspNetCore.Components.WebView;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui;
using Microsoft.Maui.Handlers;

Expand All @@ -21,7 +22,7 @@ public partial class BlazorWebViewHandler
/// <summary>
/// Initializes a new instance of <see cref="BlazorWebViewHandler"/> with default mappings.
/// </summary>
public BlazorWebViewHandler() : base(BlazorWebViewMapper)
public BlazorWebViewHandler() : this(BlazorWebViewMapper)
{
}

Expand All @@ -33,6 +34,8 @@ public BlazorWebViewHandler(PropertyMapper? mapper) : base(mapper ?? BlazorWebVi
{
}

internal BlazorWebViewDeveloperTools DeveloperTools => MauiContext!.Services.GetRequiredService<BlazorWebViewDeveloperTools>();

/// <summary>
/// Maps the <see cref="IBlazorWebView.HostPage"/> property to the specified handler.
/// </summary>
Expand Down
28 changes: 0 additions & 28 deletions src/BlazorWebView/src/Maui/BlazorWebViewRegistrationExtensions.cs

This file was deleted.

9 changes: 9 additions & 0 deletions src/BlazorWebView/src/Maui/MauiBlazorMarkerService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Microsoft.AspNetCore.Components.WebView.Maui
{
internal class MauiBlazorMarkerService
{
}
}
2 changes: 1 addition & 1 deletion src/BlazorWebView/src/Maui/iOS/BlazorWebViewHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected override WKWebView CreatePlatformView()
{
var config = new WKWebViewConfiguration();

config.Preferences.SetValueForKey(NSObject.FromObject(true), new NSString("developerExtrasEnabled"));
config.Preferences.SetValueForKey(NSObject.FromObject(DeveloperTools.Enabled), new NSString("developerExtrasEnabled"));

config.UserContentController.AddScriptMessageHandler(new WebViewScriptMessageHandler(MessageReceived), "webwindowinterop");
config.UserContentController.AddUserScript(new WKUserScript(
Expand Down
8 changes: 8 additions & 0 deletions src/BlazorWebView/src/Maui/iOS/IOSWebViewManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Text.Encodings.Web;
using Foundation;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using UIKit;
using WebKit;
Expand Down Expand Up @@ -33,6 +34,13 @@ public class IOSWebViewManager : WebViewManager
public IOSWebViewManager(BlazorWebViewHandler blazorMauiWebViewHandler!!, WKWebView webview!!, IServiceProvider provider, Dispatcher dispatcher, IFileProvider fileProvider, JSComponentConfigurationStore jsComponents, string hostPageRelativePath)
: base(provider, dispatcher, new Uri(BlazorWebViewHandler.AppOrigin), fileProvider, jsComponents, hostPageRelativePath)
{
if (provider.GetService<MauiBlazorMarkerService>() is null)
{
throw new InvalidOperationException(
"Unable to find the required services. " +
$"Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(BlazorWebViewServiceCollectionExtensions.AddMauiBlazorWebView)}' in the application startup code.");
}

_blazorMauiWebViewHandler = blazorMauiWebViewHandler;
_webview = webview;

Expand Down
17 changes: 17 additions & 0 deletions src/BlazorWebView/src/SharedSource/BlazorWebViewDeveloperTools.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

#if WEBVIEW2_WINFORMS
namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
#elif WEBVIEW2_WPF
namespace Microsoft.AspNetCore.Components.WebView.Wpf
#elif WEBVIEW2_MAUI
namespace Microsoft.AspNetCore.Components.WebView.Maui
#else
#error Must define WEBVIEW2_WINFORMS, WEBVIEW2_WPF, WEBVIEW2_MAUI
#endif
{
internal class BlazorWebViewDeveloperTools
{
public bool Enabled { get; set; } = false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
#if WEBVIEW2_WINFORMS
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
#elif WEBVIEW2_WPF
using Microsoft.AspNetCore.Components.WebView.Wpf;
#elif WEBVIEW2_MAUI
using Microsoft.AspNetCore.Components.WebView.Maui;
using Microsoft.Maui.Hosting;
#else
#error Must define WEBVIEW2_WINFORMS, WEBVIEW2_WPF, WEBVIEW2_MAUI
#endif
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods to <see cref="IServiceCollection"/>.
/// </summary>
public static class BlazorWebViewServiceCollectionExtensions
{
/// <summary>
/// Configures <see cref="IServiceCollection"/> to add support for <see cref="BlazorWebView"/>.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IServiceCollection"/>.</returns>
#if WEBVIEW2_WINFORMS
public static IServiceCollection AddWindowsFormsBlazorWebView(this IServiceCollection services)
#elif WEBVIEW2_WPF
public static IServiceCollection AddWpfBlazorWebView(this IServiceCollection services)
#elif WEBVIEW2_MAUI
public static IServiceCollection AddMauiBlazorWebView(this IServiceCollection services)
#else
#error Must define WEBVIEW2_WINFORMS, WEBVIEW2_WPF, WEBVIEW2_MAUI
#endif
{
services.AddBlazorWebView();
services.TryAddSingleton(new BlazorWebViewDeveloperTools { Enabled = false });
#if WEBVIEW2_MAUI
services.TryAddSingleton<MauiBlazorMarkerService>();
services.ConfigureMauiHandlers(static handlers => handlers.AddHandler<IBlazorWebView, BlazorWebViewHandler>());
#elif WEBVIEW2_WINFORMS
services.TryAddSingleton<WindowsFormsBlazorMarkerService>();
#elif WEBVIEW2_WPF
services.TryAddSingleton<WpfBlazorMarkerService>();
#endif
return services;
}

/// <summary>
/// Enables Developer tools on the underlying WebView controls.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IServiceCollection"/>.</returns>
public static IServiceCollection AddBlazorWebViewDeveloperTools(this IServiceCollection services)
{
return services.AddSingleton<BlazorWebViewDeveloperTools>(new BlazorWebViewDeveloperTools { Enabled = true });
}
}
}
42 changes: 40 additions & 2 deletions src/BlazorWebView/src/SharedSource/WebView2WebViewManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,21 @@
using Microsoft.Extensions.FileProviders;
#if WEBVIEW2_WINFORMS
using System.Diagnostics;
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Web.WebView2;
using Microsoft.Web.WebView2.Core;
using WebView2Control = Microsoft.Web.WebView2.WinForms.WebView2;
#elif WEBVIEW2_WPF
using System.Diagnostics;
using Microsoft.AspNetCore.Components.WebView.Wpf;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Web.WebView2;
using Microsoft.Web.WebView2.Core;
using WebView2Control = Microsoft.Web.WebView2.Wpf.WebView2;
#elif WEBVIEW2_MAUI
using Microsoft.AspNetCore.Components.WebView.Maui;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Web.WebView2.Core;
using WebView2Control = Microsoft.UI.Xaml.Controls.WebView2;
using System.Runtime.InteropServices.WindowsRuntime;
Expand Down Expand Up @@ -58,6 +63,7 @@ public class WebView2WebViewManager : WebViewManager
#if WEBVIEW2_WINFORMS || WEBVIEW2_WPF
private protected CoreWebView2Environment _coreWebView2Environment;
private readonly Action<ExternalLinkNavigationEventArgs> _externalNavigationStarting;
private readonly BlazorWebViewDeveloperTools _developerTools;

/// <summary>
/// Constructs an instance of <see cref="WebView2WebViewManager"/>.
Expand All @@ -80,8 +86,25 @@ public WebView2WebViewManager(
: base(services, dispatcher, new Uri(AppOrigin), fileProvider, jsComponents, hostPageRelativePath)

{
#if WEBVIEW2_WINFORMS
if (services.GetService<WindowsFormsBlazorMarkerService>() is null)
{
throw new InvalidOperationException(
"Unable to find the required services. " +
$"Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(BlazorWebViewServiceCollectionExtensions.AddWindowsFormsBlazorWebView)}' in the application startup code.");
}
#elif WEBVIEW2_WPF
if (services.GetService<WpfBlazorMarkerService>() is null)
{
throw new InvalidOperationException(
"Unable to find the required services. " +
$"Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(BlazorWebViewServiceCollectionExtensions.AddWpfBlazorWebView)}' in the application startup code.");
}
#endif

_webview = webview;
_externalNavigationStarting = externalNavigationStarting;
_developerTools = services.GetRequiredService<BlazorWebViewDeveloperTools>();

// Unfortunately the CoreWebView2 can only be instantiated asynchronously.
// We want the external API to behave as if initalization is synchronous,
Expand Down Expand Up @@ -113,6 +136,13 @@ BlazorWebViewHandler blazorWebViewHandler
)
: base(services, dispatcher, new Uri(AppOrigin), fileProvider, jsComponents, hostPageRelativePath)
{
if (services.GetService<MauiBlazorMarkerService>() is null)
{
throw new InvalidOperationException(
"Unable to find the required services. " +
$"Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(BlazorWebViewServiceCollectionExtensions.AddMauiBlazorWebView)}' in the application startup code.");
}

_webview = webview;
_blazorWebViewHandler = blazorWebViewHandler;

Expand Down Expand Up @@ -145,7 +175,13 @@ private async Task InitializeWebView2()
#endif
.ConfigureAwait(true);
await _webview.EnsureCoreWebView2Async();
ApplyDefaultWebViewSettings();

#if WEBVIEW2_MAUI
var developerTools = _blazorWebViewHandler.DeveloperTools;
#elif WEBVIEW2_WINFORMS || WEBVIEW2_WPF
var developerTools = _developerTools;
#endif
ApplyDefaultWebViewSettings(developerTools);

_webview.CoreWebView2.AddWebResourceRequestedFilter($"{AppOrigin}*", CoreWebView2WebResourceContext.All);

Expand Down Expand Up @@ -263,8 +299,10 @@ private void LaunchUriInExternalBrowser(Uri uri)
private protected static string GetHeaderString(IDictionary<string, string> headers) =>
string.Join(Environment.NewLine, headers.Select(kvp => $"{kvp.Key}: {kvp.Value}"));

private void ApplyDefaultWebViewSettings()
private void ApplyDefaultWebViewSettings(BlazorWebViewDeveloperTools devTools)
{
_webview.CoreWebView2.Settings.AreDevToolsEnabled = devTools.Enabled;

// Desktop applications typically don't want the default web browser context menu
_webview.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;

Expand Down
1 change: 1 addition & 0 deletions src/BlazorWebView/src/WindowsForms/BlazorWebView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Reflection;
using System.Windows.Forms;
using Microsoft.AspNetCore.Components.WebView.WebView2;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using WebView2Control = Microsoft.Web.WebView2.WinForms.WebView2;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Microsoft.AspNetCore.Components.WebView.WindowsForms
{
internal class WindowsFormsBlazorMarkerService
{
}
}
1 change: 1 addition & 0 deletions src/BlazorWebView/src/Wpf/BlazorWebView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Windows;
using System.Windows.Controls;
using Microsoft.AspNetCore.Components.WebView.WebView2;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using WebView2Control = Microsoft.Web.WebView2.Wpf.WebView2;

Expand Down
9 changes: 9 additions & 0 deletions src/BlazorWebView/src/Wpf/WpfBlazorMarkerService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Microsoft.AspNetCore.Components.WebView.Wpf
{
internal class WpfBlazorMarkerService
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public async Task BasicRazorComponentClick()
{
EnsureHandlerCreated(additionalCreationActions: appBuilder =>
{
appBuilder.Services.AddBlazorWebView();
appBuilder.Services.AddMauiBlazorWebView();
});

var bwv = new BlazorWebViewWithCustomFiles
Expand Down
Loading

0 comments on commit cfc3fab

Please sign in to comment.