docs: refactor the external link icon (#8975)

This commit is contained in:
qiang 2022-09-23 10:03:04 +08:00 committed by GitHub
parent 6813723e12
commit 5d8b2065d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 53 deletions

View File

@ -3,6 +3,7 @@ import fs from 'fs'
import MarkdownIt from 'markdown-it' import MarkdownIt from 'markdown-it'
import mdContainer from 'markdown-it-container' import mdContainer from 'markdown-it-container'
import { docRoot } from '@element-plus/build-utils' import { docRoot } from '@element-plus/build-utils'
import externalLinkIcon from '../plugins/external-link-icon'
import { highlight } from '../utils/highlight' import { highlight } from '../utils/highlight'
import type Token from 'markdown-it/lib/token' import type Token from 'markdown-it/lib/token'
import type Renderer from 'markdown-it/lib/renderer' import type Renderer from 'markdown-it/lib/renderer'
@ -22,6 +23,7 @@ interface ContainerOpts {
} }
export const mdPlugin = (md: MarkdownIt) => { export const mdPlugin = (md: MarkdownIt) => {
md.use(externalLinkIcon)
md.use(mdContainer, 'demo', { md.use(mdContainer, 'demo', {
validate(params) { validate(params) {
return !!params.trim().match(/^demo\s*(.*)$/) return !!params.trim().match(/^demo\s*(.*)$/)

View File

@ -0,0 +1,35 @@
import type MarkdownIt from 'markdown-it'
import type Renderer from 'markdown-it/lib/renderer'
export default (md: MarkdownIt): void => {
const renderToken: Renderer.RenderRule = (tokens, idx, options, env, self) =>
self.renderToken(tokens, idx, options)
const defaultLinkOpenRenderer = md.renderer.rules.link_open || renderToken
const defaultLinkCloseRenderer = md.renderer.rules.link_close || renderToken
let isExternalLink = false
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const token = tokens[idx]
const href = token.attrGet('href')
token.attrJoin('class', 'vp-link')
if (href && /^((ht|f)tps?):\/\/?/.test(href)) {
isExternalLink = true
}
return defaultLinkOpenRenderer(tokens, idx, options, env, self)
}
md.renderer.rules.link_close = (tokens, idx, options, env, self) => {
if (isExternalLink) {
isExternalLink = false
return `<i-ri-external-link-line class="link-icon" />${self.renderToken(
tokens,
idx,
options
)}`
}
return defaultLinkCloseRenderer(tokens, idx, options, env, self)
}
}

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue' import { ref } from 'vue'
import { useData } from 'vitepress' import { useData } from 'vitepress'
import { insertLinkIcon, insertTableWrapper } from '../utils' import { insertTableWrapper } from '../utils'
import VPPageFooter from './doc-content/vp-page-footer.vue' import VPPageFooter from './doc-content/vp-page-footer.vue'
import VPPageNav from './doc-content/vp-page-nav.vue' import VPPageNav from './doc-content/vp-page-nav.vue'
import VPTableOfContent from './doc-content/vp-table-of-content.vue' import VPTableOfContent from './doc-content/vp-table-of-content.vue'
@ -10,7 +10,6 @@ const { page } = useData()
const content = ref<{ $el: HTMLElement }>() const content = ref<{ $el: HTMLElement }>()
function updateDom() { function updateDom() {
insertLinkIcon(content)
insertTableWrapper(content) insertTableWrapper(content)
} }
</script> </script>

View File

@ -6,7 +6,6 @@ import {
} from 'vitepress/dist/client/theme-default/utils' } from 'vitepress/dist/client/theme-default/utils'
import { inBrowser } from 'vitepress' import { inBrowser } from 'vitepress'
import type { Ref } from 'vue'
import type { Route } from 'vitepress' import type { Route } from 'vitepress'
export * from './colors' export * from './colors'
@ -86,56 +85,6 @@ export function createCrowdinUrl(targetLang: string) {
return `https://crowdin.com/translate/element-plus/all/en-${translateLang}` return `https://crowdin.com/translate/element-plus/all/en-${translateLang}`
} }
export function insertLinkIcon(
contentRef: Ref<{ $el: HTMLElement } | undefined>
) {
if (!inBrowser) return
const links = Array.from(
contentRef.value?.$el?.querySelectorAll<HTMLLinkElement>(
'a:not(.header-anchor)'
) ?? []
)
links.forEach((link) => {
link.classList.add('vp-link')
if (
!link.href.startsWith(window.origin) &&
!/(<img)|(<svg class="link-icon")/.test(link.innerHTML)
) {
link.innerHTML = `
${link.innerHTML}
<svg class="link-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<path
d="
M853.333333 469.333333a42.666667 42.666667 0 0 0-42.666666
42.666667v256a42.666667 42.666667 0 0 1-42.666667 42.666667H256a42.666667
42.666667 0 0 1-42.666667-42.666667V256a42.666667
42.666667 0 0 1 42.666667-42.666667h256a42.666667 42.666667
0 0 0 0-85.333333H256a128 128 0 0 0-128 128v512a128 128
0 0 0 128 128h512a128 128 0 0 0 128-128v-256a42.666667
42.666667 0 0 0-42.666667-42.666667z
"
fill="currentColor">
</path>
<path
d="
M682.666667 213.333333h67.413333l-268.373333 267.946667a42.666667
42.666667 0 0 0 0 60.586667 42.666667 42.666667
0 0 0 60.586666 0L810.666667 273.92V341.333333a42.666667
42.666667 0 0 0 42.666666 42.666667 42.666667 42.666667 0 0 0
42.666667-42.666667V170.666667a42.666667 42.666667 0 0
0-42.666667-42.666667h-170.666666a42.666667
42.666667 0 0 0 0 85.333333z
"
fill="currentColor"
>
</path>
</svg>
`
}
})
}
export function insertTableWrapper(contentRef: any) { export function insertTableWrapper(contentRef: any) {
if (!inBrowser) return if (!inBrowser) return
const tables: HTMLTableElement[] = Array.from( const tables: HTMLTableElement[] = Array.from(