| File: Services\WebViewNavigationManager.cs | Web Access |
| Project: src\aspnetcore\src\Components\WebView\WebView\src\Microsoft.AspNetCore.Components.WebView.csproj (Microsoft.AspNetCore.Components.WebView) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Components.Routing; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Components.WebView.Services; internal sealed partial class WebViewNavigationManager : NavigationManager { private readonly ILogger _logger; private IpcSender _ipcSender; public WebViewNavigationManager(ILogger<WebViewNavigationManager> logger) { _logger = logger; } public void AttachToWebView(IpcSender ipcSender, string baseUrl, string initialUrl) { _ipcSender = ipcSender; Initialize(baseUrl, initialUrl); } public void LocationUpdated(string newUrl, string? state, bool intercepted) { Uri = newUrl; HistoryEntryState = state; NotifyLocationChanged(intercepted); } public void HandleLocationChanging(int callId, string uri, string? state, bool intercepted) { _ = HandleLocationChangingAsync(); async Task HandleLocationChangingAsync() { try { var shouldContinueNavigation = await NotifyLocationChangingAsync(uri, state, intercepted); if (!shouldContinueNavigation) { Log.NavigationCanceled(_logger, uri); } _ipcSender.EndLocationChanging(callId, shouldContinueNavigation); } catch (Exception ex) { // We shouldn't ever reach this since exceptions thrown from handlers are caught in InvokeLocationChangingHandlerAsync. // But if some other exception gets thrown, we still want to know about it. Log.NavigationFailed(_logger, uri, ex); _ipcSender.NotifyUnhandledException(ex); } } } protected override void NavigateToCore(string uri, NavigationOptions options) { _ = PerformNavigationAsync(); async Task PerformNavigationAsync() { try { var shouldContinueNavigation = await NotifyLocationChangingAsync(uri, options.HistoryEntryState, false); if (!shouldContinueNavigation) { Log.NavigationCanceled(_logger, uri); return; } _ipcSender.Navigate(uri, options); } catch (Exception ex) { // We shouldn't ever reach this since exceptions thrown from handlers are handled in HandleLocationChangingHandlerException. // But if some other exception gets thrown, we still want to know about it. Log.NavigationFailed(_logger, uri, ex); _ipcSender.NotifyUnhandledException(ex); } } } /// <inheritdoc /> public override void Refresh(bool forceReload = false) { _ipcSender.Refresh(forceReload); } protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context) { Log.NavigationFailed(_logger, context.TargetLocation, ex); _ipcSender.NotifyUnhandledException(ex); } protected override void SetNavigationLockState(bool value) { _ipcSender.SetHasLocationChangingListeners(value); } private static partial class Log { [LoggerMessage(1, LogLevel.Debug, "Navigation canceled when changing the location to {Uri}", EventName = "NavigationCanceled")] public static partial void NavigationCanceled(ILogger logger, string uri); [LoggerMessage(2, LogLevel.Error, "Navigation failed when changing the location to {Uri}", EventName = "NavigationFailed")] public static partial void NavigationFailed(ILogger logger, string uri, Exception exception); } }