Skip to content

NavManager suppressLocationChanged option #25782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/Components/Components/src/NavigationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,11 @@ protected set
/// <param name="uri">The destination URI. This can be absolute, or relative to the base URI
/// (as returned by <see cref="BaseUri"/>).</param>
/// <param name="forceLoad">If true, bypasses client-side routing and forces the browser to load the new page from the server, whether or not the URI would normally be handled by the client-side router.</param>
public void NavigateTo(string uri, bool forceLoad = false)
/// <param name="suppressLocationChanged">If true, navigation will not trigger the <see cref="LocationChanged" /> event.</param>
public void NavigateTo(string uri, bool forceLoad = false, bool suppressLocationChanged = false)
{
AssertInitialized();
NavigateToCore(uri, forceLoad);
NavigateToCore(uri, forceLoad, suppressLocationChanged);
}

/// <summary>
Expand All @@ -102,7 +103,8 @@ public void NavigateTo(string uri, bool forceLoad = false)
/// <param name="uri">The destination URI. This can be absolute, or relative to the base URI
/// (as returned by <see cref="BaseUri"/>).</param>
/// <param name="forceLoad">If true, bypasses client-side routing and forces the browser to load the new page from the server, whether or not the URI would normally be handled by the client-side router.</param>
protected abstract void NavigateToCore(string uri, bool forceLoad);
/// <param name="suppressLocationChanged">If true, navigation will not trigger the <see cref="LocationChanged" /> event.</param>
protected abstract void NavigateToCore(string uri, bool forceLoad, bool suppressLocationChanged);

/// <summary>
/// Called to initialize BaseURI and current URI before these values are used for the first time.
Expand Down
12 changes: 8 additions & 4 deletions src/Components/Server/src/Circuits/RemoteNavigationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,20 @@ public void AttachJsRuntime(IJSRuntime jsRuntime)
_jsRuntime = jsRuntime;
}

public void NotifyLocationChanged(string uri, bool intercepted)
public void NotifyLocationChanged(string uri, bool intercepted, bool suppressLocationChanged = false)
{
Log.ReceivedLocationChangedNotification(_logger, uri, intercepted);

Uri = uri;
NotifyLocationChanged(intercepted);

if (!suppressLocationChanged)
{
NotifyLocationChanged(intercepted);
}
}

/// <inheritdoc />
protected override void NavigateToCore(string uri, bool forceLoad)
protected override void NavigateToCore(string uri, bool forceLoad, bool suppressLocationChanged)
{
Log.RequestingNavigation(_logger, uri, forceLoad);

Expand All @@ -75,7 +79,7 @@ protected override void NavigateToCore(string uri, bool forceLoad)
throw new NavigationException(absoluteUriString);
}

_jsRuntime.InvokeAsync<object>(Interop.NavigateTo, uri, forceLoad);
_jsRuntime.InvokeAsync<object>(Interop.NavigateTo, uri, forceLoad, suppressLocationChanged);
}

private static class Log
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Web.JS/dist/Release/blazor.server.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Components/Web.JS/dist/Release/blazor.webassembly.js

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions src/Components/Web.JS/src/Services/NavigationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ let hasEnabledNavigationInterception = false;
let hasRegisteredNavigationEventListeners = false;

// Will be initialized once someone registers
let notifyLocationChangedCallback: ((uri: string, intercepted: boolean) => Promise<void>) | null = null;
let notifyLocationChangedCallback: ((uri: string, intercepted: boolean, suppressLocationChanged: boolean) => Promise<void>) | null = null;

// These are the functions we're making available for invocation from .NET
export const internalFunctions = {
Expand Down Expand Up @@ -72,12 +72,12 @@ export function attachToEventDelegator(eventDelegator: EventDelegator) {
});
}

export function navigateTo(uri: string, forceLoad: boolean, replace: boolean = false) {
export function navigateTo(uri: string, forceLoad: boolean, replace: boolean = false, suppressLocationChanged: boolean = false) {
const absoluteUri = toAbsoluteUri(uri);

if (!forceLoad && isWithinBaseUriSpace(absoluteUri)) {
// It's an internal URL, so do client-side navigation
performInternalNavigation(absoluteUri, false, replace);
performInternalNavigation(absoluteUri, false, replace, suppressLocationChanged);
} else if (forceLoad && location.href === uri) {
// Force-loading the same URL you're already on requires special handling to avoid
// triggering browser-specific behavior issues.
Expand All @@ -93,7 +93,7 @@ export function navigateTo(uri: string, forceLoad: boolean, replace: boolean = f
}
}

function performInternalNavigation(absoluteInternalHref: string, interceptedLink: boolean, replace: boolean = false) {
function performInternalNavigation(absoluteInternalHref: string, interceptedLink: boolean, replace: boolean = false, suppressLocationChanged: boolean = false) {
// Since this was *not* triggered by a back/forward gesture (that goes through a different
// code path starting with a popstate event), we don't want to preserve the current scroll
// position, so reset it.
Expand All @@ -106,12 +106,12 @@ function performInternalNavigation(absoluteInternalHref: string, interceptedLink
}else{
history.replaceState(null, /* ignored title */ '', absoluteInternalHref);
}
notifyLocationChanged(interceptedLink);
notifyLocationChanged(interceptedLink, suppressLocationChanged);
}

async function notifyLocationChanged(interceptedLink: boolean) {
async function notifyLocationChanged(interceptedLink: boolean, suppressLocationChanged: boolean = false) {
if (notifyLocationChangedCallback) {
await notifyLocationChangedCallback(location.href, interceptedLink);
await notifyLocationChangedCallback(location.href, interceptedLink, suppressLocationChanged);
}
}

Expand Down Expand Up @@ -141,4 +141,4 @@ function toBaseUriWithTrailingSlash(baseUri: string) {

function eventHasSpecialKey(event: MouseEvent) {
return event.ctrlKey || event.shiftKey || event.altKey || event.metaKey;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public static class JSInteropMethods
/// For framework use only.
/// </summary>
[JSInvokable(nameof(NotifyLocationChanged))]
public static void NotifyLocationChanged(string uri, bool isInterceptedLink)
public static void NotifyLocationChanged(string uri, bool isInterceptedLink, bool suppressLocationChanged)
{
WebAssemblyNavigationManager.Instance.SetLocation(uri, isInterceptedLink);
WebAssemblyNavigationManager.Instance.SetLocation(uri, isInterceptedLink, suppressLocationChanged);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,25 @@ public WebAssemblyNavigationManager(string baseUri, string uri)
Initialize(baseUri, uri);
}

public void SetLocation(string uri, bool isInterceptedLink)
public void SetLocation(string uri, bool isInterceptedLink, bool suppressLocationChanged)
{
Uri = uri;
NotifyLocationChanged(isInterceptedLink);

if (!suppressLocationChanged)
{
NotifyLocationChanged(isInterceptedLink);
}
}

/// <inheritdoc />
protected override void NavigateToCore(string uri, bool forceLoad)
protected override void NavigateToCore(string uri, bool forceLoad, bool suppressLocationChanged)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}

DefaultWebAssemblyJSRuntime.Instance.Invoke<object>(Interop.NavigateTo, uri, forceLoad);
DefaultWebAssemblyJSRuntime.Instance.Invoke<object>(Interop.NavigateTo, uri, forceLoad, suppressLocationChanged);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal class HttpNavigationManager : NavigationManager, IHostEnvironmentNaviga
{
void IHostEnvironmentNavigationManager.Initialize(string baseUri, string uri) => Initialize(baseUri, uri);

protected override void NavigateToCore(string uri, bool forceLoad)
protected override void NavigateToCore(string uri, bool forceLoad, bool suppressLocationChanged)
{
throw new NavigationException(uri);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ protected NavigationManager() { }
public event System.EventHandler<Microsoft.AspNetCore.Components.Routing.LocationChangedEventArgs> LocationChanged { add { } remove { } }
protected virtual void EnsureInitialized() { }
protected void Initialize(string baseUri, string uri) { }
public void NavigateTo(string uri, bool forceLoad = false) { }
protected abstract void NavigateToCore(string uri, bool forceLoad);
public void NavigateTo(string uri, bool forceLoad = false, bool suppressLocationChanged = false) { }
protected abstract void NavigateToCore(string uri, bool forceLoad, bool suppressLocationChanged);
protected void NotifyLocationChanged(bool isInterceptedLink) { }
public System.Uri ToAbsoluteUri(string relativeUri) { throw null; }
public string ToBaseRelativePath(string uri) { throw null; }
Expand Down