waibu-mpa 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extend/bajoTemplate/template/wmpa.js +12 -8
- package/extend/waibuMpa/route/component/render.js +1 -1
- package/index.js +4 -1
- package/lib/build-page/concat-resources.js +1 -0
- package/lib/build-page/inject-elements/link.js +16 -0
- package/lib/build-page/inject-elements/meta.js +1 -1
- package/lib/build-page/inject-elements.js +6 -3
- package/lib/class/component.js +3 -1
- package/lib/class/iconset.js +2 -0
- package/lib/class/theme.js +1 -0
- package/lib/class/view-engine.js +9 -7
- package/lib/class/widget.js +1 -0
- package/lib/collect-iconsets.js +3 -2
- package/lib/collect-themes.js +8 -9
- package/lib/decorate.js +6 -4
- package/package.json +1 -1
|
@@ -98,9 +98,13 @@ class Wmpa {
|
|
|
98
98
|
return result
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
fetchRender = async (body) => {
|
|
101
|
+
fetchRender = async (body, qs = {}) => {
|
|
102
102
|
if (_.isArray(body)) body = body.join('\n')
|
|
103
|
-
|
|
103
|
+
let url = this.renderUrl + '?'
|
|
104
|
+
_.forOwn(qs, (v, k) => {
|
|
105
|
+
url += '&' + k + '=' + v
|
|
106
|
+
})
|
|
107
|
+
const resp = await fetch(url, {
|
|
104
108
|
method: 'POST',
|
|
105
109
|
headers: { 'Content-Type': 'text/plain', 'Waibu-Referer': window.location.href },
|
|
106
110
|
body
|
|
@@ -187,9 +191,9 @@ class Wmpa {
|
|
|
187
191
|
return selector instanceof HTMLElement ? selector : document.querySelector(selector)
|
|
188
192
|
}
|
|
189
193
|
|
|
190
|
-
createComponent = async (body, wrapper) => {
|
|
194
|
+
createComponent = async (body, wrapper, qs = {}) => {
|
|
191
195
|
if (_.isArray(body)) body = body.join('\n')
|
|
192
|
-
const html = await this.fetchRender(body)
|
|
196
|
+
const html = await this.fetchRender(body, qs)
|
|
193
197
|
return this.createComponentFromHtml(html, wrapper)
|
|
194
198
|
}
|
|
195
199
|
|
|
@@ -201,9 +205,9 @@ class Wmpa {
|
|
|
201
205
|
return cmp.getAttribute('id')
|
|
202
206
|
}
|
|
203
207
|
|
|
204
|
-
replaceWithComponent = async (body, selector, wrapper) => {
|
|
208
|
+
replaceWithComponent = async (body, selector, wrapper, qs = {}) => {
|
|
205
209
|
let cmp
|
|
206
|
-
if (_.isString(body) || _.isArray(body)) cmp = await this.createComponent(body, wrapper)
|
|
210
|
+
if (_.isString(body) || _.isArray(body)) cmp = await this.createComponent(body, wrapper, qs)
|
|
207
211
|
else cmp = body
|
|
208
212
|
const el = this.getElement(selector)
|
|
209
213
|
if (!el) return
|
|
@@ -221,9 +225,9 @@ class Wmpa {
|
|
|
221
225
|
return cmp.getAttribute('id')
|
|
222
226
|
}
|
|
223
227
|
|
|
224
|
-
addComponent = async (body, selector = 'body', wrapper, checkChild) => {
|
|
228
|
+
addComponent = async (body, selector = 'body', wrapper, checkChild, qs = {}) => {
|
|
225
229
|
let cmp
|
|
226
|
-
if (_.isString(body) || _.isArray(body)) cmp = await this.createComponent(body, wrapper)
|
|
230
|
+
if (_.isString(body) || _.isArray(body)) cmp = await this.createComponent(body, wrapper, qs)
|
|
227
231
|
else cmp = body
|
|
228
232
|
const el = this.getElement(selector)
|
|
229
233
|
if (!el) return
|
|
@@ -5,7 +5,7 @@ const component = {
|
|
|
5
5
|
const { ext = '.html' } = req.body
|
|
6
6
|
reply.header('Content-Type', `text/html; charset=${this.config.page.charset}`)
|
|
7
7
|
reply.header('Content-Language', req.lang)
|
|
8
|
-
const opts = { req, reply, partial: true, ext }
|
|
8
|
+
const opts = { req, reply, partial: true, ext, theme: req.params.theme ?? req.query.theme, iconset: req.params.iconset ?? req.query.iconset }
|
|
9
9
|
return this.renderString(req.body, req.query, opts)
|
|
10
10
|
}
|
|
11
11
|
}
|
package/index.js
CHANGED
|
@@ -70,6 +70,7 @@ async function factory (pkgName) {
|
|
|
70
70
|
css: true,
|
|
71
71
|
meta: true,
|
|
72
72
|
scripts: true,
|
|
73
|
+
links: true,
|
|
73
74
|
inlineScript: true,
|
|
74
75
|
inlineCss: true
|
|
75
76
|
},
|
|
@@ -83,6 +84,7 @@ async function factory (pkgName) {
|
|
|
83
84
|
autoInsert: {
|
|
84
85
|
css: true,
|
|
85
86
|
scripts: true,
|
|
87
|
+
links: true,
|
|
86
88
|
inlineScript: true,
|
|
87
89
|
inlineCss: true
|
|
88
90
|
}
|
|
@@ -91,7 +93,8 @@ async function factory (pkgName) {
|
|
|
91
93
|
cacheMaxAge: 0,
|
|
92
94
|
excluded: [],
|
|
93
95
|
css: false,
|
|
94
|
-
scripts: false
|
|
96
|
+
scripts: false,
|
|
97
|
+
links: false
|
|
95
98
|
},
|
|
96
99
|
cheerio: {
|
|
97
100
|
loadOptions: {
|
|
@@ -63,6 +63,7 @@ async function concatResources (options) {
|
|
|
63
63
|
if (!(this.app.bajoExtra && this.app.bajoCache)) return
|
|
64
64
|
if (this.config.concatResource.cacheMaxAge < 1) return
|
|
65
65
|
if (this.config.concatResource.css) await apply.call(this, { $, req, tag: 'link', attr: 'href', type: 'css' })
|
|
66
|
+
if (this.config.concatResource.links) await apply.call(this, { $, req, tag: 'link', attr: 'href', type: 'css' })
|
|
66
67
|
if (this.config.concatResource.scripts) await apply.call(this, { $, req, tag: 'script', attr: 'src', type: 'js' })
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { collectRegular } from './script.js'
|
|
2
|
+
|
|
3
|
+
export function printLink (link) {
|
|
4
|
+
const { routePath } = this.app.waibu
|
|
5
|
+
const { isString } = this.app.lib._
|
|
6
|
+
const item = isString(link) ? { href: link, rel: 'stylesheet', type: 'text/css' } : link
|
|
7
|
+
return `<link href="${routePath(item.href)}" rel="${item.rel}" type="${item.type}" />`
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function link (options) {
|
|
11
|
+
const { $ } = options ?? {}
|
|
12
|
+
const regular = await collectRegular.call(this, 'links', printLink, options)
|
|
13
|
+
if (regular.length > 0) $('head').prepend(regular.join('\n'))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default link
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const omitted = ['css', 'style', 'scripts', 'ns', 'appTitle', 'title', 'fullTitle']
|
|
1
|
+
const omitted = ['css', 'style', 'links', 'scripts', 'ns', 'appTitle', 'title', 'fullTitle']
|
|
2
2
|
const names = ['description', 'keywords', 'robots', 'viewport', 'author', 'publisher',
|
|
3
3
|
'application-name', 'generator', 'referrer', 'theme-color', 'googlebot'
|
|
4
4
|
]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import injectCss from './inject-elements/css.js'
|
|
2
2
|
import injectMeta from './inject-elements/meta.js'
|
|
3
3
|
import injectScript from './inject-elements/script.js'
|
|
4
|
+
import injectLink from './inject-elements/link.js'
|
|
4
5
|
|
|
5
6
|
async function injectElements (options) {
|
|
6
7
|
const { $, req, cmp, reply } = options ?? {}
|
|
@@ -14,7 +15,7 @@ async function injectElements (options) {
|
|
|
14
15
|
let Builder = get(cmp, `widget.${tag}`)
|
|
15
16
|
if (!isFunction(Builder)) continue
|
|
16
17
|
if (!isClass(Builder)) Builder = await Builder.call(cmp)
|
|
17
|
-
for (const key of ['scripts', 'css']) {
|
|
18
|
+
for (const key of ['scripts', 'css', 'links']) {
|
|
18
19
|
let item = Builder[key] ?? []
|
|
19
20
|
if (isString(item)) item = [item]
|
|
20
21
|
if (isFunction(item)) item = await item.call(cmp, req)
|
|
@@ -32,11 +33,13 @@ async function injectElements (options) {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
for (const key of ['scripts', 'css', 'links']) {
|
|
37
|
+
options[key] = rsc[key] ?? []
|
|
38
|
+
}
|
|
37
39
|
options.inlineScript = rsc.inlineScript
|
|
38
40
|
options.inlineCss = rsc.inlineCss
|
|
39
41
|
await runHook(`${this.ns}:beforeBuildPageInjectElement`, options)
|
|
42
|
+
await injectLink.call(this, options)
|
|
40
43
|
await injectCss.call(this, options)
|
|
41
44
|
await injectMeta.call(this, options)
|
|
42
45
|
await injectScript.call(this, options)
|
package/lib/class/component.js
CHANGED
|
@@ -261,7 +261,9 @@ async function componentFactory () {
|
|
|
261
261
|
partial: true,
|
|
262
262
|
ext: params.ext ?? '.html',
|
|
263
263
|
req: this.req,
|
|
264
|
-
reply: this.reply
|
|
264
|
+
reply: this.reply,
|
|
265
|
+
theme: this.theme.name,
|
|
266
|
+
iconset: this.iconset.name
|
|
265
267
|
}
|
|
266
268
|
let html = await renderString(sentence, params, opts)
|
|
267
269
|
if (extra.wrapped) html = html.slice(3, html.length - 4)
|
package/lib/class/iconset.js
CHANGED
|
@@ -9,6 +9,7 @@ async function iconsetFactory () {
|
|
|
9
9
|
const { isArray } = this.app.lib._
|
|
10
10
|
this.name = opts.name
|
|
11
11
|
this.css = opts.css ?? []
|
|
12
|
+
this.links = opts.links ?? []
|
|
12
13
|
this.scripts = opts.scripts ?? []
|
|
13
14
|
this.inlineCss = opts.inlineCss
|
|
14
15
|
this.inlineScript = opts.inlineScript
|
|
@@ -18,6 +19,7 @@ async function iconsetFactory () {
|
|
|
18
19
|
|
|
19
20
|
if (!isArray(this.css)) this.css = [this.css]
|
|
20
21
|
if (!isArray(this.scripts)) this.scripts = [this.scripts]
|
|
22
|
+
if (!isArray(this.links)) this.links = [this.links]
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
resolve = (name) => {
|
package/lib/class/theme.js
CHANGED
package/lib/class/view-engine.js
CHANGED
|
@@ -9,25 +9,27 @@ async function viewEngineFactory () {
|
|
|
9
9
|
this.history = {}
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
_applySetting = (opts = {}) => {
|
|
12
|
+
_applySetting = (locals = {}, opts = {}) => {
|
|
13
13
|
const { req } = opts
|
|
14
14
|
const { get } = this.app.lib._
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
for (const key of ['theme', 'iconset']) {
|
|
16
|
+
let item = get(this.app.waibuMpa, `config.${key}.set`, req[key])
|
|
17
|
+
item = item ?? 'default'
|
|
18
|
+
opts[key] = opts[key] ?? item
|
|
19
|
+
req[key] = opts[key]
|
|
20
|
+
}
|
|
19
21
|
opts.postProcessor = applyFormat.bind(this.plugin)
|
|
20
22
|
opts.groupId = opts.req.id
|
|
21
23
|
opts.lang = opts.req.lang
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
render = async (tpl, locals = {}, opts = {}) => {
|
|
25
|
-
this._applySetting(opts)
|
|
27
|
+
this._applySetting(locals, opts)
|
|
26
28
|
return await this.app.bajoTemplate.render(tpl, locals, opts)
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
renderString = async (content, locals = {}, opts = {}) => {
|
|
30
|
-
this._applySetting(opts)
|
|
32
|
+
this._applySetting(locals, opts)
|
|
31
33
|
return await this.app.bajoTemplate.renderString(content, locals, opts)
|
|
32
34
|
}
|
|
33
35
|
}
|
package/lib/class/widget.js
CHANGED
package/lib/collect-iconsets.js
CHANGED
|
@@ -19,8 +19,9 @@ async function collectIconsets (ctx) {
|
|
|
19
19
|
if (isFunction(mod)) mod = await mod.call(this, ctx)
|
|
20
20
|
if (!isArray(mod)) mod = [mod]
|
|
21
21
|
for (const m of mod) {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
for (const key of ['css', 'links', 'scripts']) {
|
|
23
|
+
m[key] = await loadResource.call(me, m, key)
|
|
24
|
+
}
|
|
24
25
|
m.ns = ns
|
|
25
26
|
all.push(m)
|
|
26
27
|
}
|
package/lib/collect-themes.js
CHANGED
|
@@ -46,8 +46,8 @@ async function build (mod, fw) {
|
|
|
46
46
|
const cmp = new Cls({ plugin: fw ? fw.plugin : mod.plugin, $, theme, iconset, req, reply, locals, scriptBlock, styleBlock })
|
|
47
47
|
await cmp.loadBaseWidgets()
|
|
48
48
|
const framework = theme.framework ? find(me.themes, { name: theme.framework }) : undefined
|
|
49
|
-
merge(cmp.widget, framework ? framework.widget : theme.widget)
|
|
50
|
-
Object.assign(cmp, framework ? framework.method : theme.method)
|
|
49
|
+
merge(cmp.widget, framework ? framework.widget : {}, theme.widget)
|
|
50
|
+
Object.assign(cmp, merge({}, framework ? framework.method : {}, theme.method))
|
|
51
51
|
return cmp
|
|
52
52
|
}
|
|
53
53
|
this.themes.push(theme)
|
|
@@ -78,10 +78,9 @@ async function collectThemes (ctx) {
|
|
|
78
78
|
if (!isArray(m.meta)) m.meta = [m.meta]
|
|
79
79
|
m.metaExcludes = m.metaExcludes ?? []
|
|
80
80
|
if (!isArray(m.metaExcludes)) m.metaExcludes = [m.metaExcludes]
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
m.scriptsExcludes = await loadResource.call(this, m, 'scriptsExcludes')
|
|
81
|
+
for (const key of ['css', 'links', 'scripts', 'cssExcludes', 'linksExcludes', 'scriptsExcludes']) {
|
|
82
|
+
m[key] = await loadResource.call(this, m, key)
|
|
83
|
+
}
|
|
85
84
|
m.component = {}
|
|
86
85
|
if (m.framework) modsf.push(m) // module needs framework
|
|
87
86
|
else modso.push(m) // independent module
|
|
@@ -93,9 +92,9 @@ async function collectThemes (ctx) {
|
|
|
93
92
|
for (const mod of modsf) {
|
|
94
93
|
const fw = find(modso, { name: mod.framework })
|
|
95
94
|
if (!fw) throw this.error('cantFindThemeFramework%s', mod.framework)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
for (const key of ['meta', 'css', 'links', 'scripts']) {
|
|
96
|
+
mod[key].push(...without(fw[key], ...mod[`${key}Excludes`]))
|
|
97
|
+
}
|
|
99
98
|
mod.moveToEnd = fw.moveToEnd
|
|
100
99
|
await build.call(this, mod, fw)
|
|
101
100
|
}
|
package/lib/decorate.js
CHANGED
|
@@ -11,16 +11,18 @@ async function decorate (ctx) {
|
|
|
11
11
|
ctx.decorateRequest('darkMode', cfg.darkMode.set)
|
|
12
12
|
ctx.decorateRequest('referer', '')
|
|
13
13
|
ctx.decorateReply('ctags', null)
|
|
14
|
-
ctx.decorateReply('view', async function (tpl, params = {}) {
|
|
14
|
+
ctx.decorateReply('view', async function (tpl, params = {}, opts = {}) {
|
|
15
15
|
let ext = path.extname(tpl)
|
|
16
16
|
if (ext === '.md') ext = '.html'
|
|
17
17
|
let mimeType = isEmpty(ext) ? 'text/html' : mime.getType(ext)
|
|
18
18
|
mimeType += `; charset=${cfg.page.charset}`
|
|
19
19
|
this.header('Content-Type', mimeType)
|
|
20
20
|
this.header('Content-Language', this.request.lang)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
opts.req = this.request
|
|
22
|
+
opts.reply = this
|
|
23
|
+
for (const item of ['theme', 'iconset']) {
|
|
24
|
+
if (me[item + 's'].length === 1) this.request[item] = me[item + 's'][0].name
|
|
25
|
+
}
|
|
24
26
|
const result = await me.render(tpl, params, opts)
|
|
25
27
|
if (this.request.session) {
|
|
26
28
|
ext = path.extname(this.request.url)
|