Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

import { synchronizeDomContent } from '../Rendering/DomMerging/DomSync';
import { attachProgrammaticEnhancedNavigationHandler, handleClickForNavigationInterception, hasInteractiveRouter, isForSamePath, isSamePageWithHash, notifyEnhancedNavigationListeners, performScrollToElementOnTheSamePage } from './NavigationUtils';
import { attachProgrammaticEnhancedNavigationHandler, handleClickForNavigationInterception, hasInteractiveRouter, isForSamePath, isSamePageWithHash, notifyEnhancedNavigationListeners, performScrollToElementOnTheSamePage, isHashOnlyChange } from './NavigationUtils';
import { resetScrollAfterNextBatch, resetScrollIfNeeded } from '../Rendering/Renderer';

/*
Expand Down Expand Up @@ -120,6 +120,10 @@ function onPopState(state: PopStateEvent) {
return;
}

if (isHashOnlyChange(currentContentUrl, location.href)){
return;
}

// load the new page
performEnhancedPageLoad(location.href, /* interceptedLink */ false);
}
Expand Down
11 changes: 11 additions & 0 deletions src/Components/Web.JS/src/Services/NavigationUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ export function isSamePageWithHash(absoluteHref: string): boolean {
return url.hash !== '' && location.origin === url.origin && location.pathname === url.pathname && location.search === url.search;
}

export function isHashOnlyChange(oldUrl: string, newUrl: string): boolean {
try {
const a = new URL(oldUrl);
const b = new URL(newUrl);
return a.origin === b.origin && a.pathname === b.pathname
&& a.search === b.search && a.hash !== b.hash;
} catch {
return false;
}
}

export function isForSamePath(url1: string, url2: string) {
// We are going to use the scheme, host, port and path to determine if the two URLs are compatible.
// We do not account for the query string as we want to allow for the query string to change.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.AspNetCore.InternalTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi.Communication;
using OpenQA.Selenium.DevTools;
using OpenQA.Selenium.Support.Extensions;
using TestServer;
using Xunit.Abstractions;
Expand Down Expand Up @@ -195,6 +196,34 @@ public void CanScrollToHashWithoutPerformingFullNavigation()
.EndsWith("scroll-to-hash", StringComparison.Ordinal));
}

[Fact]
public void NonEnhancedNavCanScrollToHashWithoutFetchingPage()
{
Navigate($"{ServerPathBase}/nav/scroll-to-hash");
Browser.Equal("Scroll to hash", () => Browser.Exists(By.TagName("h1")).Text);

var javascript = (IJavaScriptExecutor)Browser;
javascript.ExecuteScript(@"
window.testFetchCalls = [];
const originalFetch = window.fetch;
window.fetch = function(...args) {
window.testFetchCalls.push(args[0]);
return originalFetch.apply(this, args);
};");

Browser.Exists(By.Id("scroll-anchor-enhance-nav-false")).Click();
Browser.True(() => Browser.GetScrollY() > 500);
Browser.True(() => Browser
.Exists(By.Id("uri-on-page-load-enhance-nav-false"))
.GetDomAttribute("data-value")
.EndsWith("scroll-to-hash", StringComparison.Ordinal));

var fetchCalls = javascript.ExecuteScript("return window.testFetchCalls;") as IEnumerable<object>;
var relevantCalls = fetchCalls?.Where(call => call.ToString().Contains("scroll-to-hash")) ?? Enumerable.Empty<object>();

Assert.Empty(relevantCalls);
}

[Theory]
[InlineData("server")]
[InlineData("webassembly")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
<div id="uri-on-page-load" style="display: none" data-value="@uriOnPageLoad"></div>
</p>

<p data-enhance-nav="false">
<a id="scroll-anchor-enhance-nav-false" href="nav/scroll-to-hash#some-content">Scroll via anchor</a>
<div id="uri-on-page-load-enhance-nav-false" style="display: none" data-value="@uriOnPageLoad"></div>
</p>

<div style="height: 2000px; border: 2px dashed red;">spacer</div>

@if (showContent)
Expand Down
Loading