diff --git a/assets/styles/post.styl b/assets/styles/post.styl
index 3baefba..96533d4 100644
--- a/assets/styles/post.styl
+++ b/assets/styles/post.styl
@@ -34,7 +34,20 @@ margin-y($top, $bottom = $top)
.one-details
margin-bottom 5px
-[data-markdown]
+ .icon-link
+ position absolute
+ transition-property transform, opacity
+ transition-duration 0.2s
+ transform translate(calc(-1px - 100%), -50%)
+ opacity 0
+ padding 0.1em
+
+[data-target]
+ .icon-link
+ opacity 1
+ transform translate(-100%, -50%)
+
+[data-md]
h1
h1&
margin-y(0, 1.25em)
@@ -49,11 +62,6 @@ margin-y($top, $bottom = $top)
margin-y(1.3em, 1.2em)
font-size 30px
- &::before
- content "#"
- margin-right 5px
- color #ccc
-
& + h3
margin-top 2em
@@ -98,9 +106,17 @@ margin-y($top, $bottom = $top)
h5&
h6
h6&
+ position relative
+ display flex
+ align-items center
color #333
line-height 1
+ &:hover
+ .icon-link
+ opacity 1
+ transform translate(-100%, -50%)
+
br
br&
clear both
@@ -368,7 +384,7 @@ margin-y($top, $bottom = $top)
.post
padding 30px
- [data-markdown]
+ [data-md]
h1
h1&
font-size 24px
diff --git a/nuxt.config.js b/nuxt.config.js
index c3e7be4..62a565a 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -53,6 +53,7 @@ module.exports = {
],
plugins: [
+ { src: '~plugins/global.js' },
{ src: '~plugins/hm.js', ssr: false },
{ src: '~plugins/i18n.js' },
{ src: '~plugins/l10n.js' },
diff --git a/one/build/page.js b/one/build/page.js
index bb73c8d..8449378 100644
--- a/one/build/page.js
+++ b/one/build/page.js
@@ -6,6 +6,7 @@ import frontmatter from 'remark-frontmatter'
import shortcodes from 'remark-shortcodes'
import remarkToRehype from 'remark-rehype'
import raw from 'rehype-raw'
+import rehypeAutolinkHeadings from '@justfork/rehype-autolink-headings'
import html from 'rehype-stringify'
import highlight from 'rehype-highlight'
import etpl from 'etpl'
@@ -45,6 +46,14 @@ const md = remark()
.use(toc)
.use(remarkToRehype, { allowDangerousHTML: true })
.use(raw)
+ .use(rehypeAutolinkHeadings, {
+ content: {
+ type: 'element',
+ tagName: 'icon-link',
+ properties: { class: 'icon-link' }
+ },
+ test: ['h2', 'h3', 'h4', 'h5', 'h6']
+ })
.use(rehypePreviewImg)
.use(rehypeLink)
.use(rehypeScoped)
@@ -87,16 +96,20 @@ export function renderDocToPage (file) {
.replace(/\{/g, '{')
.replace(/\}/g, '}')
.replace(/v-pre="true"/g, 'v-pre')
- .replace(/data-markdown="true"/g, 'data-markdown'),
+ .replace(/data-md="true"/g, 'data-md'),
demos: demoList.map(name => {
return {
name,
- src: join('@/components/demos', relative(DOCS_DIR, demos[name].filePath))
+ src: join(
+ '@/components/demos',
+ relative(DOCS_DIR, demos[name].filePath)
+ )
}
}),
components: componentList,
alert: hasAlert,
- boilerplate: demoList.length || componentList.length || hasAlert || style === 'post',
+ boilerplate:
+ demoList.length || componentList.length || hasAlert || style === 'post',
layout,
style,
path: file,
diff --git a/one/build/rehype-link.js b/one/build/rehype-link.js
index a4771d5..e939764 100644
--- a/one/build/rehype-link.js
+++ b/one/build/rehype-link.js
@@ -10,12 +10,16 @@ export default function attacher () {
let [, locale] = localPath.match(RE_LOCALE) || []
visit(tree, 'element', node => {
- let { tagName, properties: { href, ...props } } = node
- if (tagName !== 'a' || href.match(/^\w+:\/\//)) {
+ let {
+ tagName,
+ properties: { href, ...props }
+ } = node
+ if (tagName !== 'a' || href.startsWith('#') || href.match(/^\w+:\/\//)) {
return
}
- let routePath = locale && href.indexOf('/') === 0 ? `/${locale}${href}` : href
+ let routePath =
+ locale && href.indexOf('/') === 0 ? `/${locale}${href}` : href
node.tagName = 'nuxt-link'
node.properties = { ...props, to: routePath }
diff --git a/one/build/rehype-scoped.js b/one/build/rehype-scoped.js
index 7fce431..010f46f 100644
--- a/one/build/rehype-scoped.js
+++ b/one/build/rehype-scoped.js
@@ -6,7 +6,7 @@ export default function attacher () {
return tree => {
visit(tree, 'element', ({ tagName, properties }, _, { type }) => {
if (type === 'root' && !RE_DEMO.test(tagName)) {
- properties['data-markdown'] = true
+ properties['data-md'] = true
}
})
}
diff --git a/one/build/remark-anchor.js b/one/build/remark-anchor.js
index 4f82f7e..058ea2f 100644
--- a/one/build/remark-anchor.js
+++ b/one/build/remark-anchor.js
@@ -29,7 +29,10 @@ export default function attacher () {
const { type, depth, children, value, position } = node
if (type === 'heading') {
if (depth === 3) {
- const text = children[0]
+ let text = children[0]
+ if (text && text.type === 'element' && text.tagName === 'icon-link') {
+ text = children[1]
+ }
if (text && text.type === 'text' && KNOWN_SCOPES[text.value]) {
scope = KNOWN_SCOPES[text.value]
return
diff --git a/one/docs/changelog.vue b/one/docs/changelog.vue
index eb48374..328e215 100644
--- a/one/docs/changelog.vue
+++ b/one/docs/changelog.vue
@@ -3,7 +3,7 @@
class="content post"
:class="{ 'filter-version': compareValid }"
>
-
+
升级日志
+
+
+
+ {{ value }}
+
+
+ Tabular numbers
+
+
+
+
+
+
+
+
+
diff --git a/package-lock.json b/package-lock.json
index e477172..1784470 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"devDependencies": {
"@docsearch/css": "^3.0.0-alpha.39",
"@docsearch/js": "^3.0.0-alpha.39",
+ "@justfork/rehype-autolink-headings": "^5.1.1",
"@justfork/vue-monaco": "^0.3.1",
"@stackblitz/sdk": "^1.5.2",
"@vue/runtime-dom": "^3.2.31",
@@ -58,6 +59,7 @@
"raw-loader": "^4.0.2",
"recursive-readdir": "^2.2.2",
"recursive-readdir-sync": "^1.0.6",
+ "rehype-autolink-headings": "^5.1.0",
"rehype-highlight": "^4.1.0",
"rehype-raw": "^2.0.0",
"rehype-stringify": "^3.0.0",
@@ -1975,6 +1977,62 @@
"integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==",
"dev": true
},
+ "node_modules/@justfork/rehype-autolink-headings": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@justfork/rehype-autolink-headings/-/rehype-autolink-headings-5.1.1.tgz",
+ "integrity": "sha512-6KuaNZDcTQ5xjxbxzmzJ/9PN1HfdA0m1qC3IxKM+rQWWzTlKJwnErRSgRqsF+eZV5dpy/JaBst0OTa3xTMXejA==",
+ "dev": true,
+ "dependencies": {
+ "extend": "^3.0.0",
+ "hast-util-has-property": "^1.0.0",
+ "hast-util-heading-rank": "^1.0.0",
+ "hast-util-is-element": "^1.1.0",
+ "unist-util-visit": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@justfork/rehype-autolink-headings/node_modules/unist-util-is": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@justfork/rehype-autolink-headings/node_modules/unist-util-visit": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
+ "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0",
+ "unist-util-visit-parents": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@justfork/rehype-autolink-headings/node_modules/unist-util-visit-parents": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
+ "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
+ "dev": true,
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/@justfork/vue-monaco": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@justfork/vue-monaco/-/vue-monaco-0.3.1.tgz",
@@ -10744,6 +10802,26 @@
"vfile-location": "^2.0.0"
}
},
+ "node_modules/hast-util-has-property": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz",
+ "integrity": "sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-heading-rank": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-1.0.1.tgz",
+ "integrity": "sha512-P6Hq7RCky9syMevlrN90QWpqWDXCxwIVOfQR2rK6P4GpY4bqjKEuCzoWSRORZ7vz+VgRpLnXimh+mkwvVFjbyQ==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-is-element": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz",
@@ -18014,6 +18092,61 @@
"jsesc": "bin/jsesc"
}
},
+ "node_modules/rehype-autolink-headings": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-5.1.0.tgz",
+ "integrity": "sha512-ujU4/ALnWLJQubobQaMdC0h9nkzi7HlW9SOuCxZOkkJqhc/TrQ1cigIjMFQ2Tfc/es0KiFopKvwCUGw7Gw+mFw==",
+ "dev": true,
+ "dependencies": {
+ "extend": "^3.0.0",
+ "hast-util-has-property": "^1.0.0",
+ "hast-util-heading-rank": "^1.0.0",
+ "unist-util-visit": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-autolink-headings/node_modules/unist-util-is": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-autolink-headings/node_modules/unist-util-visit": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
+ "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0",
+ "unist-util-visit-parents": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-autolink-headings/node_modules/unist-util-visit-parents": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
+ "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
+ "dev": true,
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/rehype-highlight": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-4.1.0.tgz",
@@ -25239,6 +25372,48 @@
"integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==",
"dev": true
},
+ "@justfork/rehype-autolink-headings": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@justfork/rehype-autolink-headings/-/rehype-autolink-headings-5.1.1.tgz",
+ "integrity": "sha512-6KuaNZDcTQ5xjxbxzmzJ/9PN1HfdA0m1qC3IxKM+rQWWzTlKJwnErRSgRqsF+eZV5dpy/JaBst0OTa3xTMXejA==",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "hast-util-has-property": "^1.0.0",
+ "hast-util-heading-rank": "^1.0.0",
+ "hast-util-is-element": "^1.1.0",
+ "unist-util-visit": "^2.0.0"
+ },
+ "dependencies": {
+ "unist-util-is": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
+ "dev": true
+ },
+ "unist-util-visit": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
+ "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0",
+ "unist-util-visit-parents": "^3.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
+ "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0"
+ }
+ }
+ }
+ },
"@justfork/vue-monaco": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@justfork/vue-monaco/-/vue-monaco-0.3.1.tgz",
@@ -32281,6 +32456,18 @@
"vfile-location": "^2.0.0"
}
},
+ "hast-util-has-property": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz",
+ "integrity": "sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg==",
+ "dev": true
+ },
+ "hast-util-heading-rank": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-1.0.1.tgz",
+ "integrity": "sha512-P6Hq7RCky9syMevlrN90QWpqWDXCxwIVOfQR2rK6P4GpY4bqjKEuCzoWSRORZ7vz+VgRpLnXimh+mkwvVFjbyQ==",
+ "dev": true
+ },
"hast-util-is-element": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz",
@@ -38001,6 +38188,47 @@
}
}
},
+ "rehype-autolink-headings": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-5.1.0.tgz",
+ "integrity": "sha512-ujU4/ALnWLJQubobQaMdC0h9nkzi7HlW9SOuCxZOkkJqhc/TrQ1cigIjMFQ2Tfc/es0KiFopKvwCUGw7Gw+mFw==",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "hast-util-has-property": "^1.0.0",
+ "hast-util-heading-rank": "^1.0.0",
+ "unist-util-visit": "^2.0.0"
+ },
+ "dependencies": {
+ "unist-util-is": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
+ "dev": true
+ },
+ "unist-util-visit": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
+ "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0",
+ "unist-util-visit-parents": "^3.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
+ "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0"
+ }
+ }
+ }
+ },
"rehype-highlight": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-4.1.0.tgz",
diff --git a/package.json b/package.json
index 41892e6..6072f98 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"devDependencies": {
"@docsearch/css": "^3.0.0-alpha.39",
"@docsearch/js": "^3.0.0-alpha.39",
+ "@justfork/rehype-autolink-headings": "^5.1.1",
"@justfork/vue-monaco": "^0.3.1",
"@stackblitz/sdk": "^1.5.2",
"@vue/runtime-dom": "^3.2.31",
@@ -67,6 +68,7 @@
"raw-loader": "^4.0.2",
"recursive-readdir": "^2.2.2",
"recursive-readdir-sync": "^1.0.6",
+ "rehype-autolink-headings": "^5.1.0",
"rehype-highlight": "^4.1.0",
"rehype-raw": "^2.0.0",
"rehype-stringify": "^3.0.0",
diff --git a/plugins/global.js b/plugins/global.js
new file mode 100644
index 0000000..39ab379
--- /dev/null
+++ b/plugins/global.js
@@ -0,0 +1,4 @@
+import Vue from 'vue'
+import { IconLinkAlt } from 'dls-icons-vue'
+
+Vue.component('icon-link', IconLinkAlt)
diff --git a/plugins/target.js b/plugins/target.js
index 7d75090..6be3cbf 100644
--- a/plugins/target.js
+++ b/plugins/target.js
@@ -29,6 +29,8 @@ export default ({ app }) => {
target = anchor.closest('tr')
} else if (app.router.currentRoute.name === 'changelog' && anchor.tagName === 'H2') {
target = anchor.closest('.version-item')
+ } else if (['H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(anchor.tagName)) {
+ target = anchor
}
if (target) {