-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
BlazorWebViewHandler.cs
131 lines (116 loc) · 4.06 KB
/
BlazorWebViewHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
{
/// <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
}
}