Skip to content

Commit

Permalink
Merge pull request #714 from ENOVACOM/relative-path
Browse files Browse the repository at this point in the history
feat: allows relative path, fixed #590
  • Loading branch information
timaschew authored Apr 7, 2019
2 parents 270fa6c + ca8ae50 commit bba44fb
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 3 deletions.
40 changes: 40 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,46 @@ window.$docsify = {
};
```

## relativePath

- Type: `Boolean`
- Default: `false`

If **true** links are relative to the current context.

For example, the directory structure is as follows:

```text
.
└── docs
├── README.md
├── guide.md
└── zh-cn
├── README.md
├── guide.md
└── config
└── example.md
```

With relative path **enabled** and current URL `http://domain.com/zh-cn/README`, given links will resolve to:

```text
guide.md => http://domain.com/zh-cn/guide
config/example.md => http://domain.com/zh-cn/config/example
../README.md => http://domain.com/README
/README.md => http://domain.com/README
```

```js
window.$docsify = {
// Relative path enabled
relativePath: true,

// Relative path disabled (default value)
relativePath: false
};
```

## coverpage

- Type: `Boolean|String|String[]|Object`
Expand Down
3 changes: 2 additions & 1 deletion src/core/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export default function () {
formatUpdated: '',
externalLinkTarget: '_blank',
routerMode: 'hash',
noCompileLinks: []
noCompileLinks: [],
relativePath: false
},
window.$docsify
)
Expand Down
9 changes: 7 additions & 2 deletions src/core/router/history/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
isAbsolutePath,
stringifyQuery,
cleanPath,
replaceSlug
replaceSlug,
resolvePath
} from '../util'
import {noop, merge} from '../../util/core'

Expand Down Expand Up @@ -73,9 +74,13 @@ export class History {
if (local) {
const idIndex = currentRoute.indexOf('?')
path =
(idIndex > 0 ? currentRoute.substr(0, idIndex) : currentRoute) + path
(idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + path
}

if (this.config.relativePath && path.indexOf('/') !== 0) {
const currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1)
return cleanPath(resolvePath(currentDir + path))
}
return cleanPath('/' + path)
}
}
14 changes: 14 additions & 0 deletions src/core/router/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ export const cleanPath = cached(path => {
return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/')
})

export const resolvePath = cached(path => {
const segments = path.replace(/^\//, '').split('/')
let resolved = []
for (let i = 0, len = segments.length; i < len; i++) {
const segment = segments[i]
if (segment === '..') {
resolved.pop()
} else if (segment !== '.') {
resolved.push(segment)
}
}
return '/' + resolved.join('/')
})

export function getPath(...args) {
return cleanPath(args.join('/'))
}
Expand Down
62 changes: 62 additions & 0 deletions test/unit/base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* eslint-env node, chai, mocha */
require = require('esm')(module/*, options*/)
const {expect} = require('chai')
const {History} = require('../../src/core/router/history/base')

class MockHistory extends History {
parse(path) {
return {path}
}
}

describe('router/history/base', function () {
describe('relativePath true', function () {
var history

beforeEach(function () {
history = new MockHistory({relativePath: true})
})

it('toURL', function () {
// WHEN
const url = history.toURL('guide.md', {}, '/zh-ch/')

// THEN
expect(url).equal('/zh-ch/guide')
})

it('toURL with double dot', function () {
// WHEN
const url = history.toURL('../README.md', {}, '/zh-ch/')

// THEN
expect(url).equal('/README')
})

it('toURL child path', function () {
// WHEN
const url = history.toURL('config/example.md', {}, '/zh-ch/')

// THEN
expect(url).equal('/zh-ch/config/example')
})

it('toURL absolute path', function () {
// WHEN
const url = history.toURL('/README', {}, '/zh-ch/')

// THEN
expect(url).equal('/README')
})
})

it('toURL without relative path', function () {
const history = new MockHistory({relativePath: false})

// WHEN
const url = history.toURL('README', {}, '/zh-ch/')

// THEN
expect(url).equal('/README')
})
})
30 changes: 30 additions & 0 deletions test/unit/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-env node, chai, mocha */
require = require('esm')(module/*, options*/)
const {expect} = require('chai')
const {resolvePath} = require('../../src/core/router/util')

describe('router/util', function () {
it('resolvePath', async function () {
// WHEN
const result = resolvePath('hello.md')

// THEN
expect(result).equal('/hello.md')
})

it('resolvePath with dot', async function () {
// WHEN
const result = resolvePath('./hello.md')

// THEN
expect(result).equal('/hello.md')
})

it('resolvePath with two dots', async function () {
// WHEN
const result = resolvePath('test/../hello.md')

// THEN
expect(result).equal('/hello.md')
})
})

0 comments on commit bba44fb

Please sign in to comment.