Skip to content

Commit

Permalink
feat: resolve simple relative links
Browse files Browse the repository at this point in the history
Works with links like ../../url but not with ../url/./path
  • Loading branch information
posva committed Aug 3, 2020
1 parent 1367867 commit af1deaa
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 9 deletions.
6 changes: 6 additions & 0 deletions __tests__/location.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,12 @@ describe('resolveRelativePath', () => {
expect(resolveRelativePath('/add', '/users/posva')).toBe('/add')
})

it('resolves empty path', () => {
expect(resolveRelativePath('', '/users/posva')).toBe('/users/posva')
expect(resolveRelativePath('', '/users')).toBe('/users')
expect(resolveRelativePath('', '/')).toBe('/')
})

it('warns if from path is not absolute', () => {
resolveRelativePath('path', 'other')
resolveRelativePath('path', './other')
Expand Down
21 changes: 21 additions & 0 deletions __tests__/router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const routes: RouteRecordRaw[] = [
},
],
},
{ path: '/:pathMatch(.*)', component: components.Home, name: 'catch-all' },
]

async function newRouter(
Expand Down Expand Up @@ -331,6 +332,26 @@ describe('Router', () => {
})
})

it('resolves relative locations', async () => {
const { router } = await newRouter()
await router.push('/users/posva')
await router.push('add')
expect(router.currentRoute.value.path).toBe('/users/add')
await router.push('/users/posva')
await router.push('./add')
expect(router.currentRoute.value.path).toBe('/users/add')
})

it('resolves parent relative locations', async () => {
const { router } = await newRouter()
await router.push('/users/posva')
await router.push('../add')
expect(router.currentRoute.value.path).toBe('/add')
await router.push('/users/posva')
await router.push('../../../add')
expect(router.currentRoute.value.path).toBe('/add')
})

describe('Warnings', () => {
it.skip('avoid infinite redirection loops', async () => {
const history = createMemoryHistory()
Expand Down
12 changes: 3 additions & 9 deletions src/location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,8 @@ export function parseURL(
}

// no search and no query
path = path != null ? path : location
path = resolveRelativePath(path != null ? path : location, currentLocation)
// empty path means a relative query or hash `?foo=f`, `#thing`
if (!path) {
path = currentLocation + path
} else if (path[0] !== '/') {
// relative to current location. Currently we only support simple relative
// but no `..`, `.`, or complex like `../.././..`. We will always leave the
// leading slash so we can safely append path
path = currentLocation.replace(/[^\/]*$/, '') + path
}

return {
fullPath: path + (searchString && '?') + searchString + hash,
Expand Down Expand Up @@ -211,6 +203,8 @@ export function resolveRelativePath(to: string, from: string): string {
return to
}

if (!to) return from

const fromSegments = from.split('/')
const toSegments = to.split('/')

Expand Down

0 comments on commit af1deaa

Please sign in to comment.