Skip to content

Commit

Permalink
fix(history): allow base with / and base tag
Browse files Browse the repository at this point in the history
Close #164
  • Loading branch information
posva committed Apr 13, 2020
1 parent 56d310c commit d7c71b5
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
53 changes: 52 additions & 1 deletion __tests__/history/html5.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { JSDOM } from 'jsdom'
import createWebHistory from '../../src/history/html5'
import { createDom } from '../utils'

// These unit tests are supposed to tests very specific scenarios that are easier to setup
// on a unit test than an e2e tests
describe('History HTMl5', () => {
let dom: JSDOM
beforeAll(() => {
createDom()
dom = createDom()
})

afterAll(() => {
dom.window.close()
})

afterEach(() => {
// ensure no base element is left after a test as only the first is
// respected
for (let element of Array.from(document.getElementsByTagName('base')))
element.remove()
})

// this problem is very common on hash history when using a regular link
Expand All @@ -17,4 +30,42 @@ describe('History HTMl5', () => {
fullPath: '/',
})
})

it('handles a basic base', () => {
expect(createWebHistory().base).toBe('')
expect(createWebHistory('/').base).toBe('')
})

it('handles a base tag', () => {
const baseEl = document.createElement('base')
baseEl.href = '/foo/'
document.head.appendChild(baseEl)
expect(createWebHistory().base).toBe('/foo')
})

it('handles a base tag with origin', () => {
const baseEl = document.createElement('base')
baseEl.href = 'https://example.com/foo/'
document.head.appendChild(baseEl)
expect(createWebHistory().base).toBe('/foo')
})

it('handles a base tag with origin without trailing slash', () => {
const baseEl = document.createElement('base')
baseEl.href = 'https://example.com/bar'
document.head.appendChild(baseEl)
expect(createWebHistory().base).toBe('/bar')
})

it('ignores base tag if base is provided', () => {
const baseEl = document.createElement('base')
baseEl.href = '/foo/'
document.head.appendChild(baseEl)
expect(createWebHistory('/bar/').base).toBe('/bar')
})

it('handles a non-empty base', () => {
expect(createWebHistory('/foo/').base).toBe('/foo')
expect(createWebHistory('/foo').base).toBe('/foo')
})
})
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = {
preset: 'ts-jest',
globals: {
__DEV__: true,
__BROWSER__: true,
},
coverageDirectory: 'coverage',
coverageReporters: ['html', 'lcov', 'text'],
Expand Down
33 changes: 31 additions & 2 deletions src/history/html5.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,36 @@ function useHistoryStateNavigation(base: string) {
}
}

export default function createWebHistory(base: string = ''): RouterHistory {
/**
* Normalizes a base by removing any trailing slash and reading the base tag if
* present.
*
* @param base base to normalize
*/
function normalizeBase(base?: string): string {
if (!base) {
if (__BROWSER__) {
// respect <base> tag
const baseEl = document.querySelector('base')
base = (baseEl && baseEl.getAttribute('href')) || '/'
// strip full URL origin
base = base.replace(/^\w+:\/\/[^\/]+/, '')
} else {
base = '/'
}
}

// ensure leading slash when it was removed by the regex above
if (base.charAt(0) !== '/') base = '/' + base

// remove the trailing slash so all other method can just do `base + fullPath`
// to build an href
return base.replace(/\/$/, '')
}

export default function createWebHistory(base?: string): RouterHistory {
base = normalizeBase(base)

const historyNavigation = useHistoryStateNavigation(base)
const historyListeners = useHistoryListeners(
base,
Expand All @@ -283,7 +312,7 @@ export default function createWebHistory(base: string = ''): RouterHistory {
const routerHistory: RouterHistory = {
// it's overridden right after
// @ts-ignore
location: historyNavigation.location.value,
location: '',
base,
back,
forward,
Expand Down

0 comments on commit d7c71b5

Please sign in to comment.