Unverified Commit ebc52594 authored by Renée Kooi's avatar Renée Kooi Committed by GitHub
Browse files

Inject server rendered app at mount point. (#414)

Server rendering can reply with a `.selector` property indicating where
the rendered content should be mounted. It's optional; by default we
assume that we're rendering into the `<body>`.

This injects the server rendered content into the html _after_ all the
head tags are added, which should speed it up a bit for views with lots
of html. It detaches the initial template generation (the `head`
function) from injecting the server rendered response, so we can
implement custom index.html files (#343) later too.
parent 2cec2e66
......@@ -74,10 +74,11 @@ function node (state, createEdge) {
var route = content.route
var title = content.title
var body = content.body
var selector = content.selector
var hasDynamicScripts = state.scripts.list.buffer.length > 0
var html = head(body, language)
var html = head(language)
var d = documentify(entry, html)
var header = [
viewportTag(),
......@@ -111,6 +112,11 @@ function node (state, createEdge) {
d.transform(addToHead, styleTag({ hash: state.styles.bundle.hash, base: base }))
d.transform(insertApp, {
selector: selector,
body: body
})
function complete (buf) { done(null, buf) }
pump(d.bundle(), concat({ encoding: 'buffer' }, complete), function (err) {
......@@ -119,9 +125,9 @@ function node (state, createEdge) {
}
}
function head (body, lang) {
function head (lang) {
var dir = 'ltr'
return `<!DOCTYPE html><html lang="${lang}" dir="${dir}"><head></head>${body}</html>`
return `<!DOCTYPE html><html lang="${lang}" dir="${dir}"><head></head><body></body></html>`
}
// Make sure that rel=preload works in Safari.
......@@ -215,6 +221,14 @@ function addToHead (str) {
})
}
function insertApp (opts) {
return hyperstream({
[opts.selector]: {
_replaceHtml: opts.body
}
})
}
// Specific to the document node's layout
function extractFonts (state) {
var list = String(state.list.buffer).split(',')
......
......@@ -75,6 +75,7 @@ module.exports.render = function (app, route, cb) {
if (body) res.body = body
if (app.state.title) res.title = app.state.title
if (app.state.language) res.language = app.state.language
if (app.selector) res.selector = app.selector
cb(null, res)
}
}
......@@ -18,7 +18,8 @@ module.exports = class ServerRender {
this.DEFAULT_RESPONSE = {
body: '<body></body>',
title: '',
language: 'en-US'
language: 'en-US',
selector: 'body'
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment