| File: BlazorWebViewHandler.cs | Web Access |
| Project: src\src\BlazorWebView\src\Maui\Microsoft.AspNetCore.Components.WebView.Maui.csproj (Microsoft.AspNetCore.Components.WebView.Maui) |
using System; using System.Linq; using System.Runtime.Versioning; using Microsoft.AspNetCore.Components.WebView; using Microsoft.Extensions.DependencyInjection; using Microsoft.Maui; using Microsoft.Maui.Handlers; namespace Microsoft.AspNetCore.Components.WebView.Maui { #if ANDROID [SupportedOSPlatform("android23.0")] #endif public partial class BlazorWebViewHandler { private const string UseBlockingDisposalSwitch = "BlazorWebView.UseBlockingDisposal"; private static bool IsBlockingDisposalEnabled => AppContext.TryGetSwitch(UseBlockingDisposalSwitch, out var enabled) && enabled; /// <summary> /// This field is part of MAUI infrastructure and is not intended for use by application code. /// </summary> public static PropertyMapper<IBlazorWebView, BlazorWebViewHandler> BlazorWebViewMapper = new(ViewMapper) { [nameof(IBlazorWebView.HostPage)] = MapHostPage, [nameof(IBlazorWebView.RootComponents)] = MapRootComponents, }; /// <summary> /// Initializes a new instance of <see cref="BlazorWebViewHandler"/> with default mappings. /// </summary> public BlazorWebViewHandler() : this(BlazorWebViewMapper) { } /// <summary> /// Initializes a new instance of <see cref="BlazorWebViewHandler"/> using the specified mappings. /// </summary> /// <param name="mapper">The property mappings.</param> public BlazorWebViewHandler(PropertyMapper? mapper) : base(mapper ?? BlazorWebViewMapper) { } internal BlazorWebViewDeveloperTools DeveloperTools => MauiContext!.Services.GetRequiredService<BlazorWebViewDeveloperTools>(); /// <summary> /// Maps the <see cref="IBlazorWebView.HostPage"/> property to the specified handler. /// </summary> /// <param name="handler">The <see cref="BlazorWebViewHandler"/>.</param> /// <param name="webView">The <see cref="IBlazorWebView"/>.</param> public static void MapHostPage(BlazorWebViewHandler handler, IBlazorWebView webView) { #if !(NETSTANDARD || !PLATFORM) handler.HostPage = webView.HostPage; handler.StartWebViewCoreIfPossible(); #endif } /// <summary> /// Maps the <see cref="IBlazorWebView.RootComponents"/> property to the specified handler. /// </summary> /// <param name="handler">The <see cref="BlazorWebViewHandler"/>.</param> /// <param name="webView">The <see cref="IBlazorWebView"/>.</param> public static void MapRootComponents(BlazorWebViewHandler handler, IBlazorWebView webView) { #if !(NETSTANDARD || !PLATFORM) handler.RootComponents = webView.RootComponents; handler.StartWebViewCoreIfPossible(); #endif } #if !(NETSTANDARD || !PLATFORM) private string? HostPage { get; set; } internal void UrlLoading(UrlLoadingEventArgs args) => VirtualView.UrlLoading(args); private RootComponentsCollection? _rootComponents; private RootComponentsCollection? RootComponents { get => _rootComponents; set { if (_rootComponents != null) { // Remove any previously-known root components and unhook events _rootComponents.Clear(); _rootComponents.CollectionChanged -= OnRootComponentsCollectionChanged; } _rootComponents = value; if (_rootComponents != null) { // Add new root components and hook events if (_rootComponents.Count > 0 && _webviewManager != null) { _webviewManager.Dispatcher.AssertAccess(); foreach (var component in _rootComponents) { _ = component.AddToWebViewManagerAsync(_webviewManager); } } _rootComponents.CollectionChanged += OnRootComponentsCollectionChanged; } } } private void OnRootComponentsCollectionChanged(object? sender, global::System.Collections.Specialized.NotifyCollectionChangedEventArgs eventArgs) { // If we haven't initialized yet, this is a no-op if (_webviewManager != null) { // Dispatch because this is going to be async, and we want to catch any errors _ = _webviewManager.Dispatcher.InvokeAsync(async () => { var newItems = eventArgs.NewItems!.Cast<RootComponent>(); var oldItems = eventArgs.OldItems!.Cast<RootComponent>(); foreach (var item in newItems.Except(oldItems)) { await item.AddToWebViewManagerAsync(_webviewManager); } foreach (var item in oldItems.Except(newItems)) { await item.RemoveFromWebViewManagerAsync(_webviewManager); } }); } } #endif } }