diff options
Diffstat (limited to 'node_modules/vuepress/lib/app/root-mixins')
3 files changed, 113 insertions, 0 deletions
diff --git a/node_modules/vuepress/lib/app/root-mixins/activeHeaderLinks.js b/node_modules/vuepress/lib/app/root-mixins/activeHeaderLinks.js new file mode 100644 index 00000000..6cad69d5 --- /dev/null +++ b/node_modules/vuepress/lib/app/root-mixins/activeHeaderLinks.js @@ -0,0 +1,47 @@ +import store from '@app/store' +import throttle from 'lodash.throttle' + +export default { + mounted () { + window.addEventListener('scroll', this.onScroll) + }, + methods: { + onScroll: throttle(function () { + this.setActiveHash() + }, 300), + setActiveHash () { + const sidebarLinks = [].slice.call(document.querySelectorAll('.sidebar-link')) + const anchors = [].slice.call(document.querySelectorAll('.header-anchor')) + .filter(anchor => sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash)) + + const scrollTop = Math.max( + window.pageYOffset, + document.documentElement.scrollTop, + document.body.scrollTop + ) + + for (let i = 0; i < anchors.length; i++) { + const anchor = anchors[i] + const nextAnchor = anchors[i + 1] + + const isActive = i === 0 && scrollTop === 0 || + (scrollTop >= anchor.parentElement.offsetTop + 10 && + (!nextAnchor || scrollTop < nextAnchor.parentElement.offsetTop - 10)) + + if (isActive && decodeURIComponent(this.$route.hash) !== decodeURIComponent(anchor.hash)) { + store.disableScrollBehavior = true + this.$router.replace(decodeURIComponent(anchor.hash), () => { + // execute after scrollBehavior handler. + this.$nextTick(() => { + store.disableScrollBehavior = false + }) + }) + return + } + } + } + }, + beforeDestroy () { + window.removeEventListener('scroll', this.onScroll) + } +} diff --git a/node_modules/vuepress/lib/app/root-mixins/index.js b/node_modules/vuepress/lib/app/root-mixins/index.js new file mode 100644 index 00000000..fd966f39 --- /dev/null +++ b/node_modules/vuepress/lib/app/root-mixins/index.js @@ -0,0 +1,7 @@ +import updateMeta from './updateMeta' +import activeHeaderLinks from '@activeHeaderLinks' + +export default [ + updateMeta, // required + activeHeaderLinks // optional +] diff --git a/node_modules/vuepress/lib/app/root-mixins/updateMeta.js b/node_modules/vuepress/lib/app/root-mixins/updateMeta.js new file mode 100644 index 00000000..ff2703ac --- /dev/null +++ b/node_modules/vuepress/lib/app/root-mixins/updateMeta.js @@ -0,0 +1,59 @@ +export default { + created () { + if (this.$ssrContext) { + this.$ssrContext.title = this.$title + this.$ssrContext.lang = this.$lang + this.$ssrContext.description = this.$page.description || this.$description + } + }, + + mounted () { + // update title / meta tags + this.currentMetaTags = new Set() + + const updateMeta = () => { + document.title = this.$title + document.documentElement.lang = this.$lang + const userMeta = this.$page.frontmatter.meta || [] + const meta = userMeta.slice(0) + const useGlobalDescription = userMeta.filter(m => m.name === 'description').length === 0 + + // #665 Avoid duplicate description meta at runtime. + if (useGlobalDescription) { + meta.push({ name: 'description', content: this.$description }) + } + + // Including description meta coming from SSR. + const descriptionMetas = document.querySelectorAll('meta[name="description"]') + if (descriptionMetas.length) { + descriptionMetas.forEach(m => this.currentMetaTags.add(m)) + } + + this.currentMetaTags = new Set(updateMetaTags(meta, this.currentMetaTags)) + } + this.$watch('$page', updateMeta) + updateMeta() + }, + + beforeDestroy () { + updateMetaTags(null, this.currentMetaTags) + } +} + +function updateMetaTags (meta, current) { + if (current) { + [...current].forEach(c => { + document.head.removeChild(c) + }) + } + if (meta) { + return meta.map(m => { + const tag = document.createElement('meta') + Object.keys(m).forEach(key => { + tag.setAttribute(key, m[key]) + }) + document.head.appendChild(tag) + return tag + }) + } +} |
