Skip to content

Commit 518fd7d

Browse files
fix: support links with custom protocol (close #1404) (#1421)
Co-authored-by: meteorlxy <meteor.lxy@foxmail.com>
1 parent 70ae76a commit 518fd7d

File tree

12 files changed

+40
-92
lines changed

12 files changed

+40
-92
lines changed

ecosystem/theme-default/src/client/components/AutoLink.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default defineComponent({
1010

1111
<script setup lang="ts">
1212
import { useSiteData } from '@vuepress/client'
13-
import { isLinkHttp, isLinkMailto, isLinkTel } from '@vuepress/shared'
13+
import { isLinkHttp, isLinkWithProtocol } from '@vuepress/shared'
1414
import { computed, toRefs } from 'vue'
1515
import type { PropType } from 'vue'
1616
import { useRoute } from 'vue-router'
@@ -36,7 +36,7 @@ const { item } = toRefs(props)
3636
const hasHttpProtocol = computed(() => isLinkHttp(item.value.link))
3737
// if the link has non-http protocol
3838
const hasNonHttpProtocol = computed(
39-
() => isLinkMailto(item.value.link) || isLinkTel(item.value.link),
39+
() => !hasHttpProtocol.value && isLinkWithProtocol(item.value.link),
4040
)
4141
// resolve the `target` attr
4242
const linkTarget = computed(() => {

packages/shared/src/utils/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ export * from './ensureLeadingSlash.js'
66
export * from './ensureEndingSlash.js'
77
export * from './formatDateString.js'
88
export * from './isLinkExternal.js'
9-
export * from './isLinkFtp.js'
109
export * from './isLinkHttp.js'
11-
export * from './isLinkMailto.js'
12-
export * from './isLinkTel.js'
10+
export * from './isLinkWithProtocol.js'
1311
export * from './isPlainObject.js'
1412
export * from './omit.js'
1513
export * from './removeEndingSlash.js'

packages/shared/src/utils/isLinkExternal.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { isLinkFtp } from './isLinkFtp.js'
21
import { isLinkHttp } from './isLinkHttp.js'
32

43
const markdownLinkRegexp = /.md((\?|#).*)?$/
@@ -7,8 +6,7 @@ const markdownLinkRegexp = /.md((\?|#).*)?$/
76
* Determine a link is external or not
87
*/
98
export const isLinkExternal = (link: string, base = '/'): boolean => {
10-
// http link or ftp link
11-
if (isLinkHttp(link) || isLinkFtp(link)) {
9+
if (isLinkHttp(link)) {
1210
return true
1311
}
1412

packages/shared/src/utils/isLinkFtp.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/shared/src/utils/isLinkMailto.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/shared/src/utils/isLinkTel.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* Determine a link has protocol or not
3+
*/
4+
export const isLinkWithProtocol = (link: string): boolean =>
5+
/^[a-z][a-z0-9+.-]*:/.test(link)

packages/shared/tests/isLinkExternal.spec.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,28 @@ const testCases: [
55
Parameters<typeof isLinkExternal>,
66
ReturnType<typeof isLinkExternal>,
77
][] = [
8-
// http & ftp links
8+
// http links
99
[['https://foobar.com'], true],
1010
[['https://foobar.com', '/base/'], true],
1111
[['http://foobar.com'], true],
1212
[['http://foobar.com', '/base/'], true],
1313
[['//foobar.com'], true],
1414
[['//foobar.com', '/base/'], true],
15-
[['ftp://foobar.com'], true],
16-
[['ftp://foobar.com', '/base/'], true],
1715
[['https://foobar.com/base/README.md'], true],
1816
[['https://foobar.com/base/README.md', '/base/'], true],
1917
[['http://foobar.com/base/README.md'], true],
2018
[['http://foobar.com/base/README.md', '/base/'], true],
2119
[['//foobar.com/base/README.md'], true],
2220
[['//foobar.com/base/README.md', '/base/'], true],
23-
[['ftp://foobar.com/base/README.md'], true],
24-
[['ftp://foobar.com/base/README.md', '/base/'], true],
2521

2622
// links with other protocols
2723
[['mailto:foobar', '/base/'], false],
2824
[['tel:foobar', '/base/'], false],
25+
[['ftp://foobar.com'], false],
26+
[['ftp://foobar.com', '/base/'], false],
27+
[['ftp://foobar.com/base/README.md'], false],
28+
[['ftp://foobar.com/base/README.md', '/base/'], false],
29+
[['ms-windows-store://home', '/base/'], false],
2930

3031
// absolute links
3132
[['/foo/bar'], false],

packages/shared/tests/isLinkFtp.spec.ts

Lines changed: 0 additions & 21 deletions
This file was deleted.

packages/shared/tests/isLinkMailto.spec.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

packages/shared/tests/isLinkTel.spec.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { isLinkWithProtocol } from '../src/index.js'
3+
4+
const testCases: [string, ReturnType<typeof isLinkWithProtocol>][] = [
5+
['ftp://foobar.com', true],
6+
['ms-windows-store://home', true],
7+
['mailto:foobar', true],
8+
['tel:foobar', true],
9+
['https://foobar.com', true],
10+
['http://foobar.com', true],
11+
['foobar.com', false],
12+
['/foo/bar', false],
13+
['../foo/bar', false],
14+
['//foobar.com', false],
15+
]
16+
17+
describe('shared > isLinkWithProtocol', () => {
18+
describe('should determine link with protocol correctly', () => {
19+
testCases.forEach(([source, expected]) => {
20+
it(`link: ${source}`, () => {
21+
expect(isLinkWithProtocol(source)).toBe(expected)
22+
})
23+
})
24+
})
25+
})

0 commit comments

Comments
 (0)