Skip to content

Commit fb6e8d4

Browse files
committed
refactor: some enhancement:
1. Strip date from slug, 2. Rename I18n to ClientComputedMixin, 3. Clean internal I18nTemp plugin
1 parent 0d57666 commit fb6e8d4

File tree

10 files changed

+239
-177
lines changed

10 files changed

+239
-177
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Vue from 'vue'
2+
3+
export default class Store {
4+
constructor () {
5+
this.store = new Vue({
6+
data: {
7+
ob: {}
8+
}
9+
})
10+
}
11+
12+
get (key) {
13+
return this.store.ob[key]
14+
}
15+
16+
set (key, value) {
17+
Vue.set(this.store.ob, key, value)
18+
}
19+
}

packages/@vuepress/core/lib/app/app.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { routes } from '@internal/routes'
66
import { siteData } from '@internal/siteData'
77
import appEnhancers from '@internal/app-enhancers'
88
import globalUIComponents from '@internal/global-ui'
9-
import I18n from '@internal/i18n'
9+
import ClientComputedMixin from '../prepare/ClientComputedMixin'
10+
import Store from './Store'
1011

1112
// generated from user config
1213
import('@temp/style.styl')
@@ -30,9 +31,12 @@ if (module.hot) {
3031
}
3132

3233
Vue.config.productionTip = false
34+
35+
Vue.$store = new Store()
36+
3337
Vue.use(Router)
3438
// mixin for exposing $site and $page
35-
Vue.mixin(dataMixin(I18n, siteData))
39+
Vue.mixin(dataMixin(ClientComputedMixin, siteData))
3640
// component for rendering markdown content and setting title etc.
3741
Vue.component('Content', Content)
3842
Vue.component('OutboundLink', OutboundLink)
@@ -59,7 +63,7 @@ export function createApp (isServer) {
5963
if (saved) {
6064
return saved
6165
} else if (to.hash) {
62-
if (Vue.$store.disableScrollBehavior) {
66+
if (Vue.$store.get('disableScrollBehavior')) {
6367
return false
6468
}
6569
return {

packages/@vuepress/core/lib/app/dataMixin.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,16 @@ import Vue from 'vue'
44

55
export default function dataMixin (I18n, siteData) {
66
prepare(siteData)
7-
const store = new Vue({
8-
data: {
9-
siteData,
10-
disableScrollBehavior: false
11-
}
12-
})
13-
Vue.$store = store
7+
Vue.$store.set('siteData', siteData)
148

159
if (module.hot) {
1610
module.hot.accept(VUEPRESS_TEMP_PATH + '/internal/siteData.js', () => {
1711
prepare(siteData)
18-
store.siteData = siteData
12+
Vue.$store.set('siteData', siteData)
1913
})
2014
}
2115

22-
const I18nConstructor = I18n(store)
16+
const I18nConstructor = I18n(Vue.$store.get('siteData'))
2317
const i18n = new I18nConstructor()
2418
const descriptors = Object.getOwnPropertyDescriptors(Object.getPrototypeOf(i18n))
2519
const computed = {}

packages/@vuepress/core/lib/internal-plugins/i18nTemp.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

packages/@vuepress/core/lib/prepare/AppContext.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const loadTheme = require('./loadTheme')
1111
const { fs, logger, chalk, globby, sort, datatypes: { isFunction }} = require('@vuepress/shared-utils')
1212

1313
const Page = require('./Page')
14-
const I18n = require('./I18n')
14+
const ClientComputedMixin = require('./ClientComputedMixin')
1515
const PluginAPI = require('../plugin-api/index')
1616

1717
/**
@@ -54,7 +54,7 @@ module.exports = class AppContext {
5454

5555
this.pluginAPI = new PluginAPI(this)
5656
this.pages = [] // Array<Page>
57-
this.I18nConstructor = I18n(null)
57+
this.ClientComputedMixinConstructor = ClientComputedMixin(this.getSiteData())
5858
}
5959

6060
/**
@@ -73,8 +73,8 @@ module.exports = class AppContext {
7373

7474
await this.resolvePages()
7575
await Promise.all(
76-
this.pluginAPI.options.additionalPages.values.map(async ({ path, permalink }) => {
77-
await this.addPage({ filePath: path, permalink })
76+
this.pluginAPI.options.additionalPages.values.map(async (options) => {
77+
await this.addPage(options)
7878
})
7979
)
8080

@@ -109,7 +109,6 @@ module.exports = class AppContext {
109109
.use(require('../internal-plugins/rootMixins'))
110110
.use(require('../internal-plugins/enhanceApp'))
111111
.use(require('../internal-plugins/overrideCSS'))
112-
.use(require('../internal-plugins/i18nTemp'))
113112
.use(require('../internal-plugins/layoutComponents'))
114113
.use(require('../internal-plugins/pageComponents'))
115114
// user plugin
@@ -213,10 +212,10 @@ module.exports = class AppContext {
213212

214213
async addPage (options) {
215214
options.permalinkPattern = this.siteConfig.permalink
216-
const page = new Page(options)
215+
const page = new Page(options, this)
217216
await page.process({
218217
markdown: this.markdown,
219-
i18n: new this.I18nConstructor((this.getSiteData.bind(this))),
218+
computed: new this.ClientComputedMixinConstructor(),
220219
enhancers: this.pluginAPI.options.extendPageData.items
221220
})
222221
this.pages.push(page)
@@ -249,13 +248,20 @@ module.exports = class AppContext {
249248
*/
250249

251250
getSiteData () {
251+
const { locales } = this.siteConfig
252+
if (locales) {
253+
Object.keys(locales).forEach(path => {
254+
locales[path].path = path
255+
})
256+
}
257+
252258
return {
253259
title: this.siteConfig.title || '',
254260
description: this.siteConfig.description || '',
255261
base: this.base,
256262
pages: this.pages.map(page => page.toJson()),
257263
themeConfig: this.siteConfig.themeConfig || {},
258-
locales: this.siteConfig.locales
264+
locales
259265
}
260266
}
261267
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
'use strict'
2+
3+
/**
4+
* Get page data via path (permalink).
5+
*
6+
* @param {array} pages
7+
* @param {string} path
8+
* @returns {object}
9+
*/
10+
11+
function findPageForPath (pages, path) {
12+
for (let i = 0; i < pages.length; i++) {
13+
const page = pages[i]
14+
if (page.path === path) {
15+
return page
16+
}
17+
}
18+
return {
19+
path: '',
20+
frontmatter: {}
21+
}
22+
}
23+
24+
/**
25+
* Expose a function to get ClientComputedMixin constructor.
26+
* Note that this file will run in both server and client side.
27+
*
28+
* @param {object} siteData
29+
* @returns {ClientComputedMixin}
30+
*/
31+
32+
module.exports = siteData => {
33+
// We cannot use class here. webpack will throw error.
34+
function ClientComputedMixin () {}
35+
36+
ClientComputedMixin.prototype = {
37+
setPage (page) {
38+
this.__page = page
39+
},
40+
41+
get $site () {
42+
return siteData
43+
},
44+
45+
get $themeConfig () {
46+
return this.$site.themeConfig
47+
},
48+
49+
get $localeConfig () {
50+
const { locales = {}} = this.$site
51+
let targetLang
52+
let defaultLang
53+
for (const path in locales) {
54+
if (path === '/') {
55+
defaultLang = locales[path]
56+
} else if (this.$page.path.indexOf(path) === 0) {
57+
targetLang = locales[path]
58+
}
59+
}
60+
return targetLang || defaultLang || {}
61+
},
62+
63+
get $siteTitle () {
64+
return this.$localeConfig.title || this.$site.title || ''
65+
},
66+
67+
get $title () {
68+
const page = this.$page
69+
const siteTitle = this.$siteTitle
70+
const selfTitle = page.frontmatter.home ? null : (
71+
page.frontmatter.title || // explicit title
72+
page.title // inferred title
73+
)
74+
return siteTitle
75+
? selfTitle
76+
? (selfTitle + ' | ' + siteTitle)
77+
: siteTitle
78+
: selfTitle || 'VuePress'
79+
},
80+
81+
get $description () {
82+
// #565 hoist description from meta
83+
const description = getMetaDescription(this.$page.frontmatter.meta)
84+
if (description) {
85+
return description
86+
}
87+
// if (this.$page.frontmatter.meta) {
88+
// const descriptionMeta = this.$page.frontmatter.meta.filter(item => item.name === 'description')[0]
89+
// if (descriptionMeta) return descriptionMeta.content
90+
// }
91+
return this.$page.frontmatter.description || this.$localeConfig.description || this.$site.description || ''
92+
},
93+
94+
get $lang () {
95+
return this.$page.frontmatter.lang || this.$localeConfig.lang || 'en-US'
96+
},
97+
98+
get $localePath () {
99+
return this.$localeConfig.path || '/'
100+
},
101+
102+
get $themeLocaleConfig () {
103+
return (this.$site.themeConfig.locales || {})[this.$localePath] || {}
104+
},
105+
106+
get $page () {
107+
if (this.__page) {
108+
return this.__page
109+
}
110+
return findPageForPath(
111+
this.$site.pages,
112+
this.$route.path
113+
)
114+
}
115+
}
116+
117+
return ClientComputedMixin
118+
}
119+
120+
function getMetaDescription (meta) {
121+
if (meta) {
122+
// Why '(() => 'name')()' ?
123+
// You can use item.name directly and see what happened.
124+
// "How many pits did webpack bury?"
125+
const descriptionMeta = meta.filter(item => item[(() => 'name')()] === 'description')[0]
126+
if (descriptionMeta) return descriptionMeta.content
127+
}
128+
}

0 commit comments

Comments
 (0)