Skip to content

Commit

Permalink
fix: support links with custom protocol (close #1404) (#1421)
Browse files Browse the repository at this point in the history
Co-authored-by: meteorlxy <meteor.lxy@foxmail.com>
  • Loading branch information
Mister-Hope and meteorlxy authored Nov 15, 2023
1 parent 70ae76a commit 518fd7d
Show file tree
Hide file tree
Showing 12 changed files with 40 additions and 92 deletions.
4 changes: 2 additions & 2 deletions ecosystem/theme-default/src/client/components/AutoLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default defineComponent({

<script setup lang="ts">
import { useSiteData } from '@vuepress/client'
import { isLinkHttp, isLinkMailto, isLinkTel } from '@vuepress/shared'
import { isLinkHttp, isLinkWithProtocol } from '@vuepress/shared'
import { computed, toRefs } from 'vue'
import type { PropType } from 'vue'
import { useRoute } from 'vue-router'
Expand All @@ -36,7 +36,7 @@ const { item } = toRefs(props)
const hasHttpProtocol = computed(() => isLinkHttp(item.value.link))
// if the link has non-http protocol
const hasNonHttpProtocol = computed(
() => isLinkMailto(item.value.link) || isLinkTel(item.value.link),
() => !hasHttpProtocol.value && isLinkWithProtocol(item.value.link),
)
// resolve the `target` attr
const linkTarget = computed(() => {
Expand Down
4 changes: 1 addition & 3 deletions packages/shared/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ export * from './ensureLeadingSlash.js'
export * from './ensureEndingSlash.js'
export * from './formatDateString.js'
export * from './isLinkExternal.js'
export * from './isLinkFtp.js'
export * from './isLinkHttp.js'
export * from './isLinkMailto.js'
export * from './isLinkTel.js'
export * from './isLinkWithProtocol.js'
export * from './isPlainObject.js'
export * from './omit.js'
export * from './removeEndingSlash.js'
Expand Down
4 changes: 1 addition & 3 deletions packages/shared/src/utils/isLinkExternal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { isLinkFtp } from './isLinkFtp.js'
import { isLinkHttp } from './isLinkHttp.js'

const markdownLinkRegexp = /.md((\?|#).*)?$/
Expand All @@ -7,8 +6,7 @@ const markdownLinkRegexp = /.md((\?|#).*)?$/
* Determine a link is external or not
*/
export const isLinkExternal = (link: string, base = '/'): boolean => {
// http link or ftp link
if (isLinkHttp(link) || isLinkFtp(link)) {
if (isLinkHttp(link)) {
return true
}

Expand Down
4 changes: 0 additions & 4 deletions packages/shared/src/utils/isLinkFtp.ts

This file was deleted.

4 changes: 0 additions & 4 deletions packages/shared/src/utils/isLinkMailto.ts

This file was deleted.

4 changes: 0 additions & 4 deletions packages/shared/src/utils/isLinkTel.ts

This file was deleted.

5 changes: 5 additions & 0 deletions packages/shared/src/utils/isLinkWithProtocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Determine a link has protocol or not
*/
export const isLinkWithProtocol = (link: string): boolean =>
/^[a-z][a-z0-9+.-]*:/.test(link)
11 changes: 6 additions & 5 deletions packages/shared/tests/isLinkExternal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,28 @@ const testCases: [
Parameters<typeof isLinkExternal>,
ReturnType<typeof isLinkExternal>,
][] = [
// http & ftp links
// http links
[['https://foobar.com'], true],
[['https://foobar.com', '/base/'], true],
[['http://foobar.com'], true],
[['http://foobar.com', '/base/'], true],
[['//foobar.com'], true],
[['//foobar.com', '/base/'], true],
[['ftp://foobar.com'], true],
[['ftp://foobar.com', '/base/'], true],
[['https://foobar.com/base/README.md'], true],
[['https://foobar.com/base/README.md', '/base/'], true],
[['http://foobar.com/base/README.md'], true],
[['http://foobar.com/base/README.md', '/base/'], true],
[['//foobar.com/base/README.md'], true],
[['//foobar.com/base/README.md', '/base/'], true],
[['ftp://foobar.com/base/README.md'], true],
[['ftp://foobar.com/base/README.md', '/base/'], true],

// links with other protocols
[['mailto:foobar', '/base/'], false],
[['tel:foobar', '/base/'], false],
[['ftp://foobar.com'], false],
[['ftp://foobar.com', '/base/'], false],
[['ftp://foobar.com/base/README.md'], false],
[['ftp://foobar.com/base/README.md', '/base/'], false],
[['ms-windows-store://home', '/base/'], false],

// absolute links
[['/foo/bar'], false],
Expand Down
21 changes: 0 additions & 21 deletions packages/shared/tests/isLinkFtp.spec.ts

This file was deleted.

23 changes: 0 additions & 23 deletions packages/shared/tests/isLinkMailto.spec.ts

This file was deleted.

23 changes: 0 additions & 23 deletions packages/shared/tests/isLinkTel.spec.ts

This file was deleted.

25 changes: 25 additions & 0 deletions packages/shared/tests/isLinkWithProtocol.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, expect, it } from 'vitest'
import { isLinkWithProtocol } from '../src/index.js'

const testCases: [string, ReturnType<typeof isLinkWithProtocol>][] = [
['ftp://foobar.com', true],
['ms-windows-store://home', true],
['mailto:foobar', true],
['tel:foobar', true],
['https://foobar.com', true],
['http://foobar.com', true],
['foobar.com', false],
['/foo/bar', false],
['../foo/bar', false],
['//foobar.com', false],
]

describe('shared > isLinkWithProtocol', () => {
describe('should determine link with protocol correctly', () => {
testCases.forEach(([source, expected]) => {
it(`link: ${source}`, () => {
expect(isLinkWithProtocol(source)).toBe(expected)
})
})
})
})

0 comments on commit 518fd7d

Please sign in to comment.