Skip to content

Commit 5a6caeb

Browse files
committed
Revert previous approach, allow custom ShouldMatch implementations.
1 parent 825ea4c commit 5a6caeb

File tree

7 files changed

+85
-28
lines changed

7 files changed

+85
-28
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
#nullable enable
2+
virtual Microsoft.AspNetCore.Components.Routing.NavLink.ShouldMatch(string! currentUriAbsolute) -> bool

src/Components/Web/src/Routing/NavLink.cs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private void OnLocationChanged(object? sender, LocationChangedEventArgs args)
106106
}
107107
}
108108

109-
private bool ShouldMatch(string currentUriAbsolute)
109+
protected virtual bool ShouldMatch(string currentUriAbsolute)
110110
{
111111
if (_hrefAbsolute == null)
112112
{
@@ -124,33 +124,6 @@ private bool ShouldMatch(string currentUriAbsolute)
124124
return true;
125125
}
126126

127-
if (Match == NavLinkMatch.All
128-
&& IsStrictlyPrefixIgnoringQueryAndFragment(currentUriAbsolute))
129-
{
130-
return true;
131-
}
132-
133-
return false;
134-
}
135-
136-
private bool IsStrictlyPrefixIgnoringQueryAndFragment(string currentUriAbsolute)
137-
{
138-
Debug.Assert(_hrefAbsolute != null);
139-
140-
return IsStrictlyPrefixedIgnoringSuffixAfterSymbol(currentUriAbsolute, '?')
141-
|| IsStrictlyPrefixedIgnoringSuffixAfterSymbol(currentUriAbsolute, '#');
142-
}
143-
144-
private bool IsStrictlyPrefixedIgnoringSuffixAfterSymbol(string currentUriAbsolute, char symbol)
145-
{
146-
Debug.Assert(_hrefAbsolute != null);
147-
148-
var fragmentIndex = currentUriAbsolute.IndexOf(symbol);
149-
if (fragmentIndex >= 0)
150-
{
151-
var prefix = currentUriAbsolute.Substring(0, fragmentIndex);
152-
return IsStrictlyPrefixWithSeparator(currentUriAbsolute, prefix);
153-
}
154127
return false;
155128
}
156129

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,34 @@ public void CanFollowLinkDefinedInOpenShadowRoot()
383383
AssertHighlightedLinks("Other", "Other with base-relative URL (matches all)");
384384
}
385385

386+
[Fact]
387+
public void CanOverrideNavLinkToIgnoreFragment()
388+
{
389+
SetUrlViaPushState("/layout-overridden");
390+
391+
var app = Browser.MountTestComponent<TestRouter>();
392+
app.FindElement(By.LinkText("Override layout with hash, no trailing slash")).Click();
393+
Browser.Equal("This is the page with overridden layout.", () => app.FindElement(By.Id("test-info")).Text);
394+
AssertHighlightedLinks(
395+
"Override layout (matches all)",
396+
"Override layout, no trailing slash (matches all)",
397+
"Override layout with hash, no trailing slash");
398+
}
399+
400+
[Fact]
401+
public void CanOverrideNavLinkToIgnoreQuery()
402+
{
403+
SetUrlViaPushState("/layout-overridden");
404+
405+
var app = Browser.MountTestComponent<TestRouter>();
406+
app.FindElement(By.LinkText("Override layout with query, no trailing slash")).Click();
407+
Browser.Equal("This is the page with overridden layout.", () => app.FindElement(By.Id("test-info")).Text);
408+
AssertHighlightedLinks(
409+
"Override layout (matches all)",
410+
"Override layout, no trailing slash (matches all)",
411+
"Override layout with query, no trailing slash");
412+
}
413+
386414
[Fact]
387415
public void CanGoBackFromNotAComponent()
388416
{
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@page "/layout-overridden"
2+
@page "/layout-overridden/Default.html"
3+
@layout RouterTestLayoutNavLinksOverridden
4+
<div id="test-info">This is the page with overridden layout.</div>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@using Microsoft.AspNetCore.Components.Routing
2+
<style type="text/css">
3+
a.active {
4+
background-color: yellow;
5+
font-weight: bold;
6+
}
7+
</style>
8+
<ul>
9+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden/" Match=NavLinkMatch.All>Override layout (matches all)</NavLinkIgnoreQueryAndFragmentString></li>
10+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden" Match=NavLinkMatch.All>Override layout, no trailing slash (matches all)</NavLinkIgnoreQueryAndFragmentString></li>
11+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden/?abc=123">Override layout with query</NavLinkIgnoreQueryAndFragmentString></li>
12+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden?abc=123">Override layout with query, no trailing slash</NavLinkIgnoreQueryAndFragmentString></li>
13+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden/#blah">Override layout with hash</NavLinkIgnoreQueryAndFragmentString></li>
14+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden#blah">Override layout with hash, no trailing slash</NavLinkIgnoreQueryAndFragmentString></li>
15+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden/Default.html">Override layout with extension</NavLinkIgnoreQueryAndFragmentString></li>
16+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/layout-overridden/Other">Override Other</NavLinkIgnoreQueryAndFragmentString></li>
17+
<li><NavLinkIgnoreQueryAndFragmentString href="/subdir/Other" Match=NavLinkMatch.All>Override Other with base-relative URL (matches all)</NavLinkIgnoreQueryAndFragmentString></li>
18+
</ul>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@using Microsoft.AspNetCore.Components.Routing;
2+
@inherits NavLink
3+
4+
@{
5+
base.BuildRenderTree(__builder);
6+
}
7+
8+
@code{
9+
10+
protected override bool ShouldMatch(string currentUriAbsolute)
11+
{
12+
if (base.ShouldMatch(currentUriAbsolute))
13+
{
14+
return true;
15+
}
16+
17+
var originalMatch = base.Match;
18+
base.Match = NavLinkMatch.All;
19+
string uriWithoutQueryAndFragment = GetUriIgnoreQueryAndFragment(currentUriAbsolute);
20+
var shouldMatch = base.ShouldMatch(uriWithoutQueryAndFragment);
21+
base.Match = originalMatch;
22+
return shouldMatch;
23+
}
24+
25+
private string GetUriIgnoreQueryAndFragment(string uri) =>
26+
new Uri(uri).GetLeftPart(UriPartial.Path);
27+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@using Microsoft.AspNetCore.Components
2+
@inherits LayoutComponentBase
3+
4+
@Body
5+
6+
<BasicTestApp.RouterTest.LinksOverridden />

0 commit comments

Comments
 (0)