Skip to content

Commit 448e602

Browse files
authored
Fix fetch request in data-enhance-nav="false" for same-page anchors (#63449)
1 parent 0e1065a commit 448e602

File tree

5 files changed

+61
-6
lines changed

5 files changed

+61
-6
lines changed

src/Components/Web.JS/src/Services/NavigationEnhancement.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
import { synchronizeDomContent } from '../Rendering/DomMerging/DomSync';
5-
import { attachProgrammaticEnhancedNavigationHandler, handleClickForNavigationInterception, hasInteractiveRouter, isForSamePath, isSamePageWithHash, notifyEnhancedNavigationListeners, performScrollToElementOnTheSamePage } from './NavigationUtils';
5+
import { attachProgrammaticEnhancedNavigationHandler, handleClickForNavigationInterception, hasInteractiveRouter, isForSamePath, notifyEnhancedNavigationListeners, performScrollToElementOnTheSamePage, isSamePageWithHash } from './NavigationUtils';
66
import { resetScrollAfterNextBatch, resetScrollIfNeeded } from '../Rendering/Renderer';
77

88
/*
@@ -99,7 +99,7 @@ function onDocumentClick(event: MouseEvent) {
9999
handleClickForNavigationInterception(event, absoluteInternalHref => {
100100
const originalLocation = location.href;
101101

102-
const shouldScrollToHash = isSamePageWithHash(absoluteInternalHref);
102+
const shouldScrollToHash = isSamePageWithHash(originalLocation, absoluteInternalHref);
103103
history.pushState(null, /* ignored title */ '', absoluteInternalHref);
104104

105105
if (shouldScrollToHash) {
@@ -120,6 +120,11 @@ function onPopState(state: PopStateEvent) {
120120
return;
121121
}
122122

123+
if (state.state == null && isSamePageWithHash(currentContentUrl, location.href)) {
124+
currentContentUrl = location.href;
125+
return;
126+
}
127+
123128
// load the new page
124129
performEnhancedPageLoad(location.href, /* interceptedLink */ false);
125130
}

src/Components/Web.JS/src/Services/NavigationManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ function performExternalNavigation(uri: string, replace: boolean) {
150150
async function performInternalNavigation(absoluteInternalHref: string, interceptedLink: boolean, replace: boolean, state: string | undefined = undefined, skipLocationChangingCallback = false) {
151151
ignorePendingNavigation();
152152

153-
if (isSamePageWithHash(absoluteInternalHref)) {
153+
if (isSamePageWithHash(location.href, absoluteInternalHref)) {
154154
saveToBrowserHistory(absoluteInternalHref, replace, state);
155155
performScrollToElementOnTheSamePage(absoluteInternalHref);
156156
return;

src/Components/Web.JS/src/Services/NavigationUtils.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ export function isWithinBaseUriSpace(href: string) {
4747
&& (nextChar === '' || nextChar === '/' || nextChar === '?' || nextChar === '#');
4848
}
4949

50-
export function isSamePageWithHash(absoluteHref: string): boolean {
51-
const url = new URL(absoluteHref);
52-
return url.hash !== '' && location.origin === url.origin && location.pathname === url.pathname && location.search === url.search;
50+
export function isSamePageWithHash(oldUrl: string, newUrl: string): boolean {
51+
const a = new URL(oldUrl);
52+
const b = new URL(newUrl);
53+
return a.origin === b.origin && a.pathname === b.pathname
54+
&& a.search === b.search && b.hash !== '';
5355
}
5456

5557
export function isForSamePath(url1: string, url2: string) {

src/Components/test/E2ETest/ServerRenderingTests/EnhancedNavigationTest.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Microsoft.AspNetCore.InternalTesting;
1111
using OpenQA.Selenium;
1212
using OpenQA.Selenium.BiDi.Communication;
13+
using OpenQA.Selenium.DevTools;
1314
using OpenQA.Selenium.Support.Extensions;
1415
using TestServer;
1516
using Xunit.Abstractions;
@@ -195,6 +196,40 @@ public void CanScrollToHashWithoutPerformingFullNavigation()
195196
.EndsWith("scroll-to-hash", StringComparison.Ordinal));
196197
}
197198

199+
[Fact]
200+
public void NonEnhancedNavCanScrollToHashWithoutFetchingPageAnchor()
201+
{
202+
Navigate($"{ServerPathBase}/nav/scroll-to-hash");
203+
var originalTextElem = Browser.Exists(By.CssSelector("#anchor #text"));
204+
Browser.Equal("Text", () => originalTextElem.Text);
205+
206+
Browser.Exists(By.CssSelector("#anchor #scroll-anchor")).Click();
207+
Browser.True(() => Browser.GetScrollY() > 500);
208+
Browser.True(() => Browser
209+
.Exists(By.CssSelector("#anchor #uri-on-page-load"))
210+
.GetDomAttribute("data-value")
211+
.EndsWith("scroll-to-hash", StringComparison.Ordinal));
212+
213+
Browser.Equal("Text", () => originalTextElem.Text);
214+
}
215+
216+
[Fact]
217+
public void NonEnhancedNavCanScrollToHashWithoutFetchingPageNavLink()
218+
{
219+
Navigate($"{ServerPathBase}/nav/scroll-to-hash");
220+
var originalTextElem = Browser.Exists(By.CssSelector("#navlink #text"));
221+
Browser.Equal("Text", () => originalTextElem.Text);
222+
223+
Browser.Exists(By.CssSelector("#navlink #scroll-anchor")).Click();
224+
Browser.True(() => Browser.GetScrollY() > 500);
225+
Browser.True(() => Browser
226+
.Exists(By.CssSelector("#navlink #uri-on-page-load"))
227+
.GetDomAttribute("data-value")
228+
.EndsWith("scroll-to-hash", StringComparison.Ordinal));
229+
230+
Browser.Equal("Text", () => originalTextElem.Text);
231+
}
232+
198233
[Theory]
199234
[InlineData("server")]
200235
[InlineData("webassembly")]

src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/EnhancedNav/PageForScrollingToHash.razor

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@page "/nav/scroll-to-hash"
22
@attribute [StreamRendering]
33
@inject NavigationManager NavigationManager
4+
@using Microsoft.AspNetCore.Components.Forms
45

56
<PageTitle>Page for scrolling to hash</PageTitle>
67

@@ -13,6 +14,18 @@
1314
<div id="uri-on-page-load" style="display: none" data-value="@uriOnPageLoad"></div>
1415
</p>
1516

17+
<div data-enhance-nav="false" id="anchor">
18+
<a id="scroll-anchor" href="nav/scroll-to-hash#some-content">Scroll via anchor</a>
19+
<div id="uri-on-page-load" style="display: none" data-value="@uriOnPageLoad"></div>
20+
<p id="text">Text</p>
21+
</div>
22+
23+
<div data-enhance-nav="false" id="navlink">
24+
<NavLink id="scroll-anchor" href="nav/scroll-to-hash#some-content">Scroll via NavLink</NavLink>
25+
<div id="uri-on-page-load" style="display: none" data-value="@uriOnPageLoad"></div>
26+
<p id="text">Text</p>
27+
</div>
28+
1629
<div style="height: 2000px; border: 2px dashed red;">spacer</div>
1730

1831
@if (showContent)

0 commit comments

Comments
 (0)