]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(hash): use location.pathname
authorEduardo San Martin Morote <posva13@gmail.com>
Wed, 20 May 2020 10:18:53 +0000 (12:18 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Wed, 20 May 2020 10:18:53 +0000 (12:18 +0200)
Fix #261

__tests__/history/hash.spec.ts
__tests__/history/html5.spec.ts
__tests__/utils.ts
src/history/hash.ts

index 50cfcdc94f75bc6565c90e2d340cd3cd6758d7f2..33305afaadc45ae14b361cad9cdae7c8533353e7 100644 (file)
@@ -37,10 +37,18 @@ describe('History Hash', () => {
     })
 
     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/#')
@@ -58,6 +66,26 @@ describe('History Hash', () => {
       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://', () => {
@@ -68,9 +96,7 @@ describe('History Hash', () => {
     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#')
     })
   })
 })
index 03f2b0e1cfc0acf4f0f9de6ec866ab8728f1fc49..026bed0231bc5e440a371a76f47c51786dc578a1 100644 (file)
@@ -74,4 +74,35 @@ describe('History HTMl5', () => {
     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()
+  })
 })
index 655adcb32717627a8b1c8845183ea51d1e095a80..225eca37c3c4c982140e23cca3b37660ba2ad82d 100644 (file)
@@ -94,7 +94,7 @@ export function createDom(options?: ConstructorOptions) {
   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,
index 5b8015400e8987b14fe1cbe81121bf4632dab719..15bba544cf370cb1f36d18299211bd8a9baa2683 100644 (file)
@@ -4,9 +4,31 @@ import { createWebHistory } from './html5'
 /**
  * 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)
 }