fix(docs-infra): correctly handle in-page anchor links (#43460)

Previously, anchor links that were supposed to point to fragments inside
the current page (e.g. `href="#something"`) would end up navigating to
the homepage (`/`). This was due to them being resolved relative to the
base URL, which is set to `/` (via `<base href="/">`). See also
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base#in-page_anchors.

This commit fixes this issue by handling such links specially in
`LocationService#handleAnchorClick()` and prepending the current path to
the URL.

This will also be useful for implementing a "skip to content" link as
described in #42936.

PR Close #43460
This commit is contained in:
George Kalpakas
2021-09-19 11:46:48 +03:00
committed by Jessica Janiuk
parent 235e4aaa25
commit 4dd107d18c
2 changed files with 15 additions and 2 deletions
@@ -436,6 +436,14 @@ describe('LocationService', () => {
expect(result).toBe(false);
});
it('local fragment-only URL', () => {
location.internalPath = '/some/path';
anchor.href = '#some-fragment';
const result = service.handleAnchorClick(anchor);
expect(service.go).toHaveBeenCalledWith('/some/path#some-fragment');
expect(result).toBe(false);
});
it('local url with query params', () => {
anchor.href = 'some/local/url?query=xxx&other=yyy';
const result = service.handleAnchorClick(anchor);
+7 -2
View File
@@ -145,11 +145,16 @@ export class LocationService {
}
const { pathname, search, hash } = anchor;
const relativeUrl = pathname + search + hash;
// Fix in-page anchors that are supposed to point to fragments inside the page, but are resolved
// relative the the root path (`/`), due to the base URL being set to `/`.
// (See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base#in-page_anchors.)
const isInPageAnchor = anchor.getAttribute('href')?.startsWith('#') ?? false;
const correctPathname = isInPageAnchor ? this.location.path() : pathname;
const relativeUrl = correctPathname + search + hash;
this.urlParser.href = relativeUrl;
// don't navigate if external link or has extension
if ( anchor.href !== this.urlParser.href ||
if ( (!isInPageAnchor && anchor.href !== this.urlParser.href) ||
!/\/[^/.]*$/.test(pathname) ) {
return true;
}