})
it('should use a correct base', () => {
+ dom.reconfigure({ url: 'https://esm.dev' })
+ console.log(location.host, location.pathname)
createWebHashHistory()
+ // starts with a `/`
expect(createWebHistory).toHaveBeenCalledWith('/#')
})
+ it('does not append a # if the user provides one', () => {
+ createWebHashHistory('/#/app')
+ expect(createWebHistory).toHaveBeenCalledWith('/#/app')
+ })
+
it('should be able to provide a base', () => {
createWebHashHistory('/folder/')
expect(createWebHistory).toHaveBeenCalledWith('/folder/#')
createWebHashHistory('/bar/')
expect(createWebHistory).toHaveBeenCalledWith('/bar/#')
})
+
+ describe('url with pathname', () => {
+ it('keeps the pathname as base', () => {
+ dom.reconfigure({ url: 'https://esm.dev/subfolder' })
+ createWebHashHistory()
+ expect(createWebHistory).toHaveBeenCalledWith('/subfolder#')
+ })
+
+ it('keeps the pathname without a trailing slash as base', () => {
+ dom.reconfigure({ url: 'https://esm.dev/subfolder#/foo' })
+ createWebHashHistory()
+ expect(createWebHistory).toHaveBeenCalledWith('/subfolder#')
+ })
+
+ it('keeps the pathname with trailing slash as base', () => {
+ dom.reconfigure({ url: 'https://esm.dev/subfolder/#/foo' })
+ createWebHashHistory()
+ expect(createWebHistory).toHaveBeenCalledWith('/subfolder/#')
+ })
+ })
})
describe('file://', () => {
it('should use a correct base', () => {
createWebHashHistory()
// both, a trailing / and none work
- expect(createWebHistory).toHaveBeenCalledWith(
- expect.stringMatching(/^#\/?$/)
- )
+ expect(createWebHistory).toHaveBeenCalledWith('/usr/some-file.html#')
})
})
})
expect(createWebHistory('#/bar').base).toBe('#/bar')
expect(createWebHistory('#/bar/').base).toBe('#/bar')
})
+
+ it('prepends the host to support // urls', () => {
+ let history = createWebHistory()
+ let spy = jest.spyOn(window.history, 'pushState')
+ history.push('/foo')
+ expect(spy).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.any(String),
+ 'https://example.com/foo'
+ )
+ history.push('//foo')
+ expect(spy).toHaveBeenLastCalledWith(
+ expect.anything(),
+ expect.any(String),
+ 'https://example.com//foo'
+ )
+ spy.mockRestore()
+ })
+
+ it('works with file:/// urls and a base', () => {
+ dom.reconfigure({ url: 'file:///usr/etc/index.html' })
+ let history = createWebHistory('/usr/etc/index.html#/')
+ let spy = jest.spyOn(window.history, 'pushState')
+ history.push('/foo')
+ expect(spy).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.any(String),
+ 'file:///usr/etc/index.html#/foo'
+ )
+ spy.mockRestore()
+ })
})
const dom = new JSDOM(
`<!DOCTYPE html><html><head></head><body></body></html>`,
{
- url: 'https://example.org/',
+ url: 'https://example.com/',
referrer: 'https://example.com/',
contentType: 'text/html',
...options,
/**
* Creates a hash history.
*
- * @param base - optional base to provide. Defaults to `/`
+ * @param base - optional base to provide. Defaults to `location.pathname` or
+ * `/` if at root. If there is a `base` tag in the `head`, its value will be
+ * **ignored**.
+ *
+ * @example
+ * ```js
+ * // at https://example.com/folder
+ * createWebHashHistory() // gives a url of `https://example.com/folder#`
+ * createWebHashHistory('/folder/') // gives a url of `https://example.com/folder/#`
+ * // if the `#` is provided in the base, it won't be added by `createWebHashHistory`
+ * createWebHashHistory('/folder/#/app/') // gives a url of `https://example.com/folder/#/app/`
+ * // you should avoid doing this because it changes the original url and breaks copying urls
+ * createWebHashHistory('/other-folder/') // gives a url of `https://example.com/other-folder/#`
+ *
+ * // at file:///usr/etc/folder/index.html
+ * // for locations with no `host`, the base is ignored
+ * createWebHashHistory('/iAmIgnored') // gives a url of `file:///usr/etc/folder/index.html#`
+ * ```
*/
-export function createWebHashHistory(base: string = '/'): RouterHistory {
+export function createWebHashHistory(base?: string): RouterHistory {
// Make sure this implementation is fine in terms of encoding, specially for IE11
- return createWebHistory(location.host ? base + '#' : '#')
+ // for `file://`, directly use the pathname and ignore the base
+ // location.pathname contains an initial `/` even at the root: `https://example.com`
+ base = location.host ? base || location.pathname : location.pathname
+ // allow the user to provide a `#` in the middle: `/base/#/app`
+ if (base.indexOf('#') < 0) base += '#'
+ return createWebHistory(base)
}