Page.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <template>
  2. <div>
  3. <main :class="{'withouttoc': !showPageToc, 'page':true}">
  4. <slot name="top"/>
  5. <Content class="theme-default-content"/>
  6. <footer class="page-edit">
  7. <div
  8. class="edit-link"
  9. v-if="editLink"
  10. >
  11. <a
  12. :href="editLink"
  13. target="_blank"
  14. rel="noopener noreferrer"
  15. >{{ editLinkText }}</a>
  16. <OutboundLink/>
  17. </div>
  18. <div
  19. class="last-updated"
  20. v-if="lastUpdated"
  21. >
  22. <span class="prefix">{{ lastUpdatedText }}: </span>
  23. <span class="time">{{ lastUpdated }}</span>
  24. </div>
  25. </footer>
  26. <div class="page-nav" v-if="prev || next">
  27. <p class="inner">
  28. <span
  29. v-if="prev"
  30. class="prev"
  31. >
  32. <router-link
  33. v-if="prev"
  34. class="prev"
  35. :to="prev.path"
  36. >
  37. {{ prev.title || prev.path }}
  38. </router-link>
  39. </span>
  40. <span
  41. v-if="next"
  42. class="next"
  43. >
  44. <router-link
  45. v-if="next"
  46. :to="next.path"
  47. >
  48. {{ next.title || next.path }}
  49. </router-link>
  50. </span>
  51. </p>
  52. </div>
  53. <slot name="bottom"/>
  54. </main>
  55. </div>
  56. </template>
  57. <script>
  58. import { resolvePage, outboundRE, endingSlashRE } from '../util'
  59. export default {
  60. props: ['sidebarItems'],
  61. computed: {
  62. showPageToc () {
  63. return this.prev || this.next
  64. },
  65. lastUpdated () {
  66. if(this.$page.lastUpdated){
  67. return this.$page.lastUpdated.split(" ")[0]
  68. }
  69. return this.$page.lastUpdated
  70. },
  71. lastUpdatedText () {
  72. if (typeof this.$themeLocaleConfig.lastUpdated === 'string') {
  73. return this.$themeLocaleConfig.lastUpdated
  74. }
  75. if (typeof this.$site.themeConfig.lastUpdated === 'string') {
  76. return this.$site.themeConfig.lastUpdated
  77. }
  78. return 'Last Updated'
  79. },
  80. prev () {
  81. const prev = this.$page.frontmatter.prev
  82. if (prev === false) {
  83. return
  84. } else if (prev) {
  85. return resolvePage(this.$site.pages, prev, this.$route.path)
  86. } else {
  87. return resolvePrev(this.$page, this.sidebarItems)
  88. }
  89. },
  90. next () {
  91. const next = this.$page.frontmatter.next
  92. if (next === false) {
  93. return
  94. } else if (next) {
  95. return resolvePage(this.$site.pages, next, this.$route.path)
  96. } else {
  97. return resolveNext(this.$page, this.sidebarItems)
  98. }
  99. },
  100. editLink () {
  101. if (this.$page.frontmatter.editLink === false) {
  102. return
  103. }
  104. const {
  105. repo,
  106. editLinks,
  107. docsDir = '',
  108. docsBranch = 'master',
  109. docsRepo = repo
  110. } = this.$site.themeConfig
  111. if (docsRepo && editLinks && this.$page.relativePath) {
  112. return this.createEditLink(repo, docsRepo, docsDir, docsBranch, this.$page.relativePath)
  113. }
  114. },
  115. editLinkText () {
  116. return (
  117. this.$themeLocaleConfig.editLinkText
  118. || this.$site.themeConfig.editLinkText
  119. || `Edit this page`
  120. )
  121. }
  122. },
  123. methods: {
  124. createEditLink (repo, docsRepo, docsDir, docsBranch, path) {
  125. const bitbucket = /bitbucket.org/
  126. if (bitbucket.test(repo)) {
  127. const base = outboundRE.test(docsRepo)
  128. ? docsRepo
  129. : repo
  130. return (
  131. base.replace(endingSlashRE, '')
  132. + `/src`
  133. + `/${docsBranch}/`
  134. + (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '')
  135. + path
  136. + `?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
  137. )
  138. }
  139. const base = outboundRE.test(docsRepo)
  140. ? docsRepo
  141. : `https://github.com/${docsRepo}`
  142. return (
  143. base.replace(endingSlashRE, '')
  144. + `/edit`
  145. + `/${docsBranch}/`
  146. + (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '')
  147. + path
  148. )
  149. }
  150. }
  151. }
  152. function resolvePrev (page, items) {
  153. return find(page, items, -1)
  154. }
  155. function resolveNext (page, items) {
  156. return find(page, items, 1)
  157. }
  158. function find (page, items, offset) {
  159. const res = []
  160. flatten(items, res)
  161. for (let i = 0; i < res.length; i++) {
  162. const cur = res[i]
  163. if (cur.type === 'page' && cur.path === decodeURIComponent(page.path)) {
  164. return res[i + offset]
  165. }
  166. }
  167. }
  168. function flatten (items, res) {
  169. for (let i = 0, l = items.length; i < l; i++) {
  170. if (items[i].type === 'group') {
  171. flatten(items[i].children || [], res)
  172. } else {
  173. res.push(items[i])
  174. }
  175. }
  176. }
  177. </script>
  178. <style lang="stylus">
  179. @require '../styles/wrapper.styl'
  180. .page
  181. display block
  182. word-break break-word
  183. padding-bottom 15px
  184. padding-right 315px
  185. padding-top 55px
  186. padding-left 18rem
  187. background #f3f5f7
  188. .theme-default-content
  189. margin-top 14px
  190. margin-left 12px
  191. background #fff
  192. .page.withouttoc
  193. padding-right 65px
  194. .h1
  195. padding-top 1rem
  196. .page-contract
  197. display none
  198. background #fff
  199. .page-edit
  200. @extend $wrapper
  201. padding-top 1rem
  202. background #fff
  203. padding-bottom 1rem
  204. margin-left 12px
  205. overflow auto
  206. .edit-link
  207. display inline-block
  208. a
  209. color lighten($textColor, 25%)
  210. margin-right 0.25rem
  211. .last-updated
  212. float right
  213. font-size 0.9em
  214. .prefix
  215. font-weight 500
  216. color lighten($textColor, 25%)
  217. .time
  218. font-weight 400
  219. color #aaa
  220. .page-nav
  221. @extend $wrapper
  222. padding-top 1rem
  223. padding-bottom 0
  224. background #fff
  225. margin-left 12px
  226. .inner
  227. min-height 2rem
  228. margin-top 0
  229. border-top 1px solid $borderColor
  230. padding-top 1rem
  231. overflow auto // clear float
  232. .next
  233. float right
  234. .theme-default-content:not(.custom) > h1:first-child
  235. margin-top -4.5rem
  236. @media (max-width: $MQNarrow)
  237. h1
  238. font-size 1.6rem
  239. h2
  240. font-size 1.5rem
  241. h3
  242. font-size 1.3rem
  243. .page
  244. font-size 0.9rem
  245. padding-right 3.5rem
  246. padding-bottom 1rem
  247. display block
  248. padding-top 55px
  249. .theme-default-content
  250. margin-top 0px
  251. margin-left 0px
  252. .page-edit
  253. margin-left 0px
  254. .page-contract
  255. margin-left 0px
  256. .page-nav
  257. margin-left 0px
  258. .page.withouttoc
  259. padding-right: 55px;
  260. @media (max-width: $MQMobile)
  261. .page
  262. font-size 0.9rem
  263. padding-right 0rem
  264. margin: 0;
  265. padding: 0;
  266. padding-top: 3.5rem;
  267. .theme-default-content
  268. padding 1rem
  269. overflow-x hidden
  270. .page-contract
  271. display block
  272. padding 2rem
  273. padding-top 0rem
  274. overflow auto
  275. .c-content
  276. text-align center
  277. width 99%
  278. .page-edit
  279. .edit-link
  280. margin-bottom .5rem
  281. .last-updated
  282. font-size .8em
  283. float none
  284. text-align left
  285. .page.withouttoc
  286. padding-right: 0rem;
  287. </style>