<template> <div class="page"> <slot name="top"/> <Content :custom="false"/> <div class="page-edit"> <div class="edit-link" v-if="editLink" > <a :href="editLink" target="_blank" rel="noopener noreferrer" >{{ editLinkText }}</a> <OutboundLink/> </div> <div class="last-updated" v-if="lastUpdated" > <span class="prefix">{{ lastUpdatedText }}: </span> <span class="time">{{ lastUpdated }}</span> </div> </div> <div class="page-nav" v-if="prev || next"> <p class="inner"> <span v-if="prev" class="prev" > ← <router-link v-if="prev" class="prev" :to="prev.path" > {{ prev.title || prev.path }} </router-link> </span> <span v-if="next" class="next" > <router-link v-if="next" :to="next.path" > {{ next.title || next.path }} </router-link> → </span> </p> </div> <slot name="bottom"/> </div> </template> <script> import { resolvePage, normalize, outboundRE, endingSlashRE } from './util' export default { props: ['sidebarItems'], computed: { lastUpdated () { if (this.$page.lastUpdated) { return new Date(this.$page.lastUpdated).toLocaleString(this.$lang) } }, lastUpdatedText () { if (typeof this.$themeLocaleConfig.lastUpdated === 'string') { return this.$themeLocaleConfig.lastUpdated } if (typeof this.$site.themeConfig.lastUpdated === 'string') { return this.$site.themeConfig.lastUpdated } return 'Last Updated' }, prev () { const prev = this.$page.frontmatter.prev if (prev === false) { return } else if (prev) { return resolvePage(this.$site.pages, prev, this.$route.path) } else { return resolvePrev(this.$page, this.sidebarItems) } }, next () { const next = this.$page.frontmatter.next if (next === false) { return } else if (next) { return resolvePage(this.$site.pages, next, this.$route.path) } else { return resolveNext(this.$page, this.sidebarItems) } }, editLink () { if (this.$page.frontmatter.editLink === false) { return } const { repo, editLinks, docsDir = '', docsBranch = 'master', docsRepo = repo } = this.$site.themeConfig let path = normalize(this.$page.path) if (endingSlashRE.test(path)) { path += 'README.md' } else { path += '.md' } if (docsRepo && editLinks) { return this.createEditLink(repo, docsRepo, docsDir, docsBranch, path) } }, editLinkText () { return ( this.$themeLocaleConfig.editLinkText || this.$site.themeConfig.editLinkText || `Edit this page` ) } }, methods: { createEditLink (repo, docsRepo, docsDir, docsBranch, path) { const bitbucket = /bitbucket.org/ if (bitbucket.test(repo)) { const base = outboundRE.test(docsRepo) ? docsRepo : repo return ( base.replace(endingSlashRE, '') + `/${docsBranch}` + (docsDir ? '/' + docsDir.replace(endingSlashRE, '') : '') + path + `?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default` ) } const base = outboundRE.test(docsRepo) ? docsRepo : `https://github.com/${docsRepo}` return ( base.replace(endingSlashRE, '') + `/edit/${docsBranch}` + (docsDir ? '/' + docsDir.replace(endingSlashRE, '') : '') + path ) } } } function resolvePrev (page, items) { return find(page, items, -1) } function resolveNext (page, items) { return find(page, items, 1) } function find (page, items, offset) { const res = [] items.forEach(item => { if (item.type === 'group') { res.push(...item.children || []) } else { res.push(item) } }) for (let i = 0; i < res.length; i++) { const cur = res[i] if (cur.type === 'page' && cur.path === page.path) { return res[i + offset] } } } </script> <style lang="stylus"> @import './styles/config.styl' @require './styles/wrapper.styl' .page padding-bottom 2rem .page-edit @extend $wrapper padding-top 1rem padding-bottom 1rem overflow auto .edit-link display inline-block a color lighten($textColor, 25%) margin-right 0.25rem .last-updated float right font-size 0.9em .prefix font-weight 500 color lighten($textColor, 25%) .time font-weight 400 color #aaa .page-nav @extend $wrapper padding-top 1rem padding-bottom 0 .inner min-height 2rem margin-top 0 border-top 1px solid $borderColor padding-top 1rem overflow auto // clear float .next float right @media (max-width: $MQMobile) .page-edit .edit-link margin-bottom .5rem .last-updated font-size .8em float none text-align left </style>