Skip to content

Commit 2b9bec6

Browse files
authored
Bug hash routing same page with params or query (#48994)
* switch test names * added e2e test for navigating to same page with url and hash * fix bug: update scroll position if it is same page with different query * added test with anchor with href to same url with query and hash * fix hash routing for same url with added parameters
1 parent 8973bf2 commit 2b9bec6

File tree

3 files changed

+140
-12
lines changed

3 files changed

+140
-12
lines changed

src/Components/Components/src/Routing/Router.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static readonly IReadOnlyDictionary<string, object> _emptyParametersDictionary
2626
bool _navigationInterceptionEnabled;
2727
ILogger<Router> _logger;
2828

29-
private Type? _updateScrollPositionForHashLastHandlerType;
29+
private string _updateScrollPositionForHashLastLocation;
3030
private bool _updateScrollPositionForHash;
3131

3232
private CancellationTokenSource _onNavigateCts;
@@ -194,8 +194,8 @@ internal virtual void Refresh(bool isNavigationIntercepted)
194194
return;
195195
}
196196

197-
var locationPath = NavigationManager.ToBaseRelativePath(_locationAbsolute);
198-
locationPath = TrimQueryOrHash(locationPath);
197+
var relativePath = NavigationManager.ToBaseRelativePath(_locationAbsolute);
198+
var locationPath = TrimQueryOrHash(relativePath);
199199

200200
RefreshRouteTable();
201201

@@ -217,10 +217,10 @@ internal virtual void Refresh(bool isNavigationIntercepted)
217217
context.Parameters ?? _emptyParametersDictionary);
218218
_renderHandle.Render(Found(routeData));
219219

220-
// If you navigate to a different page, then after the next render we'll update the scroll position
221-
if (context.Handler != _updateScrollPositionForHashLastHandlerType)
220+
// If you navigate to a different path, then after the next render we'll update the scroll position
221+
if (relativePath != _updateScrollPositionForHashLastLocation)
222222
{
223-
_updateScrollPositionForHashLastHandlerType = context.Handler;
223+
_updateScrollPositionForHashLastLocation = relativePath;
224224
_updateScrollPositionForHash = true;
225225
}
226226
}

src/Components/test/E2ETest/Tests/RoutingTest.cs

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,54 @@ public void AnchorWithHrefContainingHashSamePage_ScrollsToElementOnTheSamePage()
15901590
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
15911591
}
15921592

1593+
[Fact]
1594+
public void AnchorWithHrefToSameUrlWithQueryAndHash_ScrollsToElementOnTheSamePage()
1595+
{
1596+
SetUrlViaPushState("/");
1597+
var app = Browser.MountTestComponent<TestRouter>();
1598+
app.FindElement(By.LinkText("Long page with hash")).Click();
1599+
1600+
app.FindElement(By.Id("anchor-test1-with-query")).Click();
1601+
1602+
var currentWindowScrollY = BrowserScrollY;
1603+
var test1VerticalLocation = app.FindElement(By.Id("test1")).Location.Y;
1604+
var currentRelativeUrl = _serverFixture.RootUri.MakeRelativeUri(new Uri(Browser.Url)).ToString();
1605+
Assert.Equal("subdir/LongPageWithHash?color=green&number=123#test1", currentRelativeUrl);
1606+
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
1607+
}
1608+
1609+
[Fact]
1610+
public void AnchorWithHrefToSameUrlWithParamAndHash_ScrollsToElementOnTheSamePage()
1611+
{
1612+
SetUrlViaPushState("/");
1613+
var app = Browser.MountTestComponent<TestRouter>();
1614+
app.FindElement(By.LinkText("Long page with hash")).Click();
1615+
1616+
app.FindElement(By.Id("anchor-test1-with-param")).Click();
1617+
1618+
var currentWindowScrollY = BrowserScrollY;
1619+
var test1VerticalLocation = app.FindElement(By.Id("test1")).Location.Y;
1620+
var currentRelativeUrl = _serverFixture.RootUri.MakeRelativeUri(new Uri(Browser.Url)).ToString();
1621+
Assert.Equal("subdir/LongPageWithHash/11#test1", currentRelativeUrl);
1622+
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
1623+
}
1624+
1625+
[Fact]
1626+
public void AnchorWithHrefToSameUrlWithParamQueryAndHash_ScrollsToElementOnTheSamePage()
1627+
{
1628+
SetUrlViaPushState("/");
1629+
var app = Browser.MountTestComponent<TestRouter>();
1630+
app.FindElement(By.LinkText("Long page with hash")).Click();
1631+
1632+
app.FindElement(By.Id("anchor-test1-with-param-and-query")).Click();
1633+
1634+
var currentWindowScrollY = BrowserScrollY;
1635+
var test1VerticalLocation = app.FindElement(By.Id("test1")).Location.Y;
1636+
var currentRelativeUrl = _serverFixture.RootUri.MakeRelativeUri(new Uri(Browser.Url)).ToString();
1637+
Assert.Equal("subdir/LongPageWithHash/11?color=green&number=123#test1", currentRelativeUrl);
1638+
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
1639+
}
1640+
15931641
[Fact]
15941642
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/47967")]
15951643
public void AnchorWithHrefContainingHashAnotherPage_NavigatesToPageAndScrollsToElement()
@@ -1609,7 +1657,7 @@ public void AnchorWithHrefContainingHashAnotherPage_NavigatesToPageAndScrollsToE
16091657

16101658
[Fact]
16111659
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/47967")]
1612-
public void NavigationManagerNavigateToSameUrlWithHash_ScrollsToElementOnTheSamePage()
1660+
public void NavigationManagerNavigateToAnotherUrlWithHash_NavigatesToPageAndScrollsToElement()
16131661
{
16141662
SetUrlViaPushState("/");
16151663
var app = Browser.MountTestComponent<TestRouter>();
@@ -1625,7 +1673,7 @@ public void NavigationManagerNavigateToSameUrlWithHash_ScrollsToElementOnTheSame
16251673
}
16261674

16271675
[Fact]
1628-
public void NavigationManagerNavigateToAnotherUrlWithHash_NavigatesToPageAndScrollsToElement()
1676+
public void NavigationManagerNavigateToSameUrlWithHash_ScrollsToElementOnTheSamePage()
16291677
{
16301678
SetUrlViaPushState("/");
16311679
var app = Browser.MountTestComponent<TestRouter>();
@@ -1640,6 +1688,54 @@ public void NavigationManagerNavigateToAnotherUrlWithHash_NavigatesToPageAndScro
16401688
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
16411689
}
16421690

1691+
[Fact]
1692+
public void NavigationManagerNavigateToSameUrlWithQueryAndHash_ScrollsToElementOnTheSamePage()
1693+
{
1694+
SetUrlViaPushState("/");
1695+
var app = Browser.MountTestComponent<TestRouter>();
1696+
app.FindElement(By.LinkText("Long page with hash")).Click();
1697+
1698+
app.FindElement(By.Id("navigate-test1-with-query")).Click();
1699+
1700+
var currentWindowScrollY = BrowserScrollY;
1701+
var test1VerticalLocation = app.FindElement(By.Id("test1")).Location.Y;
1702+
var currentRelativeUrl = _serverFixture.RootUri.MakeRelativeUri(new Uri(Browser.Url)).ToString();
1703+
Assert.Equal("subdir/LongPageWithHash?color=green&number=123#test1", currentRelativeUrl);
1704+
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
1705+
}
1706+
1707+
[Fact]
1708+
public void NavigationManagerNavigateToSameUrlWithParamAndHash_ScrollsToElementOnTheSamePage()
1709+
{
1710+
SetUrlViaPushState("/");
1711+
var app = Browser.MountTestComponent<TestRouter>();
1712+
app.FindElement(By.LinkText("Long page with hash")).Click();
1713+
1714+
app.FindElement(By.Id("navigate-test1-with-param")).Click();
1715+
1716+
var currentWindowScrollY = BrowserScrollY;
1717+
var test1VerticalLocation = app.FindElement(By.Id("test1")).Location.Y;
1718+
var currentRelativeUrl = _serverFixture.RootUri.MakeRelativeUri(new Uri(Browser.Url)).ToString();
1719+
Assert.Equal("subdir/LongPageWithHash/22#test1", currentRelativeUrl);
1720+
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
1721+
}
1722+
1723+
[Fact]
1724+
public void NavigationManagerNavigateToSameUrlWithParamQueryAndHash_ScrollsToElementOnTheSamePage()
1725+
{
1726+
SetUrlViaPushState("/");
1727+
var app = Browser.MountTestComponent<TestRouter>();
1728+
app.FindElement(By.LinkText("Long page with hash")).Click();
1729+
1730+
app.FindElement(By.Id("navigate-test1-with-param-and-query")).Click();
1731+
1732+
var currentWindowScrollY = BrowserScrollY;
1733+
var test1VerticalLocation = app.FindElement(By.Id("test1")).Location.Y;
1734+
var currentRelativeUrl = _serverFixture.RootUri.MakeRelativeUri(new Uri(Browser.Url)).ToString();
1735+
Assert.Equal("subdir/LongPageWithHash/22?color=green&number=123#test1", currentRelativeUrl);
1736+
Assert.Equal(test1VerticalLocation, currentWindowScrollY);
1737+
}
1738+
16431739
private long BrowserScrollY
16441740
{
16451741
get => Convert.ToInt64(((IJavaScriptExecutor)Browser).ExecuteScript("return window.scrollY"), CultureInfo.CurrentCulture);

src/Components/test/testassets/BasicTestApp/RouterTest/LongPageWithHash.razor

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1-
@page "/LongPageWithHash"
1+
@page "/LongPageWithHash/{param1:int?}"
22
@inject NavigationManager NavigationManager
33

44
<a id="anchor-test1" href="LongPageWithHash#test1">Go to test1 on this page</a>
5-
<br/>
5+
<br />
66
<a id="anchor-test2" href="LongPageWithHash2#test2">Go to test2 on LongPageWithHash2 page</a>
77
<br />
8-
<button id="navigate-test1" class="btn btn-primary" @onclick="GoToTest1">NavigationManager.NavigatteTo same page #test1</button>
8+
<a id="anchor-test1-with-query" href="LongPageWithHash?color=green&number=123#test1">Go to test1 same url with query</a>
9+
<br />
10+
<a id="anchor-test1-with-param" href="LongPageWithHash/11#test1">Go to test1 with param</a>
11+
<br />
12+
<a id="anchor-test1-with-param-and-query" href="LongPageWithHash/11?color=green&number=123#test1">Go to test1 with param and query</a>
13+
<br />
14+
<button id="navigate-test1" class="btn btn-primary" @onclick="GoToTest1">NavigationManager.NavigateTo same page #test1</button>
15+
<br />
16+
<button id="navigate-test2" class="btn btn-primary" @onclick="GoToTest2">NavigationManager.NavigateTo LongPageWithHash2 #test2</button>
917
<br />
10-
<button id="navigate-test2" class="btn btn-primary" @onclick="GoToTest2">NavigationManager.NavigatteTo LongPageWithHash2 #test2</button>
18+
<button id="navigate-test1-with-query" class="btn btn-primary" @onclick="GoToTest1WithQuery">NavigationManager.NavigateTo same page #test1 with query</button>
19+
<br />
20+
<button id="navigate-test1-with-param" class="btn btn-primary" @onclick="GoToTest1WithParam">NavigationManager.NavigateTo same page #test1 with param</button>
21+
<br />
22+
<button id="navigate-test1-with-param-and-query" class="btn btn-primary" @onclick="GoToTest1WithParamAndQuery">NavigationManager.NavigateTo same page #test1 with param and query</button>
23+
24+
<p>@Param1</p>
1125

1226
<div style="border: 2px dashed red; margin: 1rem; padding: 1rem; height: 1500px;">
1327
Scroll past me to find the links
@@ -20,6 +34,9 @@
2034
</div>
2135

2236
@code {
37+
[Parameter] public int Param1 { get; set; }
38+
39+
2340
void GoToTest1()
2441
{
2542
NavigationManager.NavigateTo("LongPageWithHash#test1");
@@ -29,4 +46,19 @@
2946
{
3047
NavigationManager.NavigateTo("LongPageWithHash2#test2");
3148
}
49+
50+
void GoToTest1WithQuery()
51+
{
52+
NavigationManager.NavigateTo("LongPageWithHash?color=green&number=123#test1");
53+
}
54+
55+
void GoToTest1WithParam()
56+
{
57+
NavigationManager.NavigateTo("LongPageWithHash/22#test1");
58+
}
59+
60+
void GoToTest1WithParamAndQuery()
61+
{
62+
NavigationManager.NavigateTo("LongPageWithHash/22?color=green&number=123#test1");
63+
}
3264
}

0 commit comments

Comments
 (0)