Skip to content

Commit

Permalink
Return early for internal URLs too
Browse files Browse the repository at this point in the history
For example when linking to other service pages (e.g. `/clear-session-data`) as described in the Exit this page guidance:

https://design-system.service.gov.uk/components/exit-this-page/#consider-what-to-do-with-user-session-data

Co-authored-by: Oliver Byford <oliver.byford@digital.cabinet-office.gov.uk>
  • Loading branch information
colinrotherham and 36degrees committed Dec 7, 2023
1 parent 74e3a6c commit 5cf5c32
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,20 @@ export class SkipLink extends GOVUKFrontendComponent {
)
}

// Check for external link URL and return early
if (url.origin !== window.location.origin) {
// Return early for external URLs or links to other pages
if (
url.origin !== window.location.origin ||
url.pathname !== window.location.pathname
) {
return
}

const linkedElementId = getFragmentFromUrl(hash)

// Check for link hash fragment
if (!linkedElementId || url.pathname !== window.location.pathname) {
// Check link path matching current page
if (!linkedElementId) {
throw new ElementError(
!linkedElementId
? `Skip link: Target link (\`href="${href}"\`) has no hash fragment`
: `Skip link: Target link (\`href="${href}"\`) must stay on page (\`${window.location.pathname}\`)`
`Skip link: Target link (\`href="${href}"\`) has no hash fragment`
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,33 @@ describe('Skip Link', () => {
})
})

it('can return early without errors when linking to another page (without hash fragment)', async () => {
await render(page, 'skip-link', {
context: {
text: 'Exit this page',
href: '/clear-session-data'
}
})
})

it('can return early without errors when linking to another page (with hash fragment)', async () => {
await render(page, 'skip-link', {
context: {
text: 'Skip to main content',
href: '/somewhere-else#main-content'
}
})
})

it('can return early without errors when linking to the current page (with hash fragment)', async () => {
await render(page, 'skip-link', {
context: {
text: 'Skip to main content',
href: '#content'
}
})
})

it('can throw a SupportError if appropriate', async () => {
await expect(
render(page, 'skip-link', examples.default, {
Expand Down Expand Up @@ -146,31 +173,14 @@ describe('Skip Link', () => {
render(page, 'skip-link', {
context: {
text: 'Skip to main content',
href: 'this-element-does-not-exist'
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Skip link: Target link (`href="this-element-does-not-exist"`) has no hash fragment'
}
})
})

it('throws when the href links to another page', async () => {
await expect(
render(page, 'skip-link', {
context: {
text: 'Skip to main content',
href: '/somewhere-else#main-content'
href: '/components/skip-link/preview'
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Skip link: Target link (`href="/somewhere-else#main-content"`) must stay on page (`/components/skip-link/preview`)'
'Skip link: Target link (`href="/components/skip-link/preview"`) has no hash fragment'
}
})
})
Expand Down

0 comments on commit 5cf5c32

Please sign in to comment.