Skip to content

Commit

Permalink
feat: finish ssr
Browse files Browse the repository at this point in the history
  • Loading branch information
QingWei-Li committed May 29, 2017
1 parent 6dea685 commit 3444884
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 40 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.git/
packages/docsify-server-renderer/build.js
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
"themes"
],
"scripts": {
"build": "rm -rf lib themes && node build/build.js && mkdir lib/themes && mkdir themes && node build/build-css.js",
"dev:build": "rm -rf lib themes && mkdir themes && node build/build.js --dev && node build/build-css.js --dev",
"dev": "node app.js & nodemon -w src -e js,css --exec 'npm run dev:build'",
"build": "rm -rf lib themes && node build/build && mkdir lib/themes && mkdir themes && node build/build-css",
"dev:build": "rm -rf lib themes && mkdir themes && node build/build --dev && node build/build-css --dev",
"dev": "node app & nodemon -w src -e js,css --exec 'npm run dev:build'",
"build:ssr": "node build/build-ssr",
"test": "eslint src --fix"
"test": "eslint {src,packages} --fix"
},
"dependencies": {
"marked": "^0.3.6",
Expand Down
4 changes: 2 additions & 2 deletions packages/docsify-server-renderer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ renderer.renderToString({ url })
<link rel="stylesheet" href="//unpkg.com/docsify/themes/buble.css" title="buble" disabled>
</head>
<body>
<div id="app"></div>
<!--inject-docsify-config-->
<!--inject-app-->
<!--inject-config-->
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
</body>
</html>
Expand Down
100 changes: 92 additions & 8 deletions packages/docsify-server-renderer/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
import { Compiler } from '../../src/core/render/compiler'
import { AbstractHistory } from '../../src/core/router/history/abstract'
import path from 'path'
import fs from 'fs'
import { resolve, basename } from 'path'
import { readFileSync } from 'fs'
import * as tpl from '../../src/core/render/tpl'

function cwd (...args) {
return resolve(process.cwd(), ...args)
}

function mainTpl (config) {
let html = `<nav class="app-nav${config.repo ? '' : 'no-badge'}"><!--navbar--></nav>`

if (config.repo) {
html += tpl.corner(config.repo)
}
if (config.coverpage) {
html += tpl.cover()
}

html += tpl.main(config)

return html
}

export default class Renderer {
constructor ({
Expand All @@ -10,16 +30,80 @@ export default class Renderer {
config,
cache
}) {
this.template = template
this.path = path
this.config = config
this.html = this.template = template
this.path = cwd(path)
this.config = Object.assign(config, {
routerMode: 'history'
})
this.cache = cache

this.router = new AbstractHistory()
this.router = new AbstractHistory(config)
this.compiler = new Compiler(config, this.router)

this.router.getCurrentPath = () => this.url
this._renderHtml('inject-config', `<script>window.$docsify = ${JSON.stringify(config)}</script>`)
this._renderHtml('inject-app', mainTpl(config))
}

renderToString (url) {
this.url = url
// TODO render cover page
const { loadSidebar, loadNavbar } = this.config

const mainFile = cwd(this.path, `./${this.router.getFile(url)}`)
this._renderHtml('main', this._render(mainFile))

if (loadSidebar) {
const name = loadSidebar === true ? '_sidebar.md' : loadSidebar
const sidebarFile = cwd(mainFile, '..', name)
this._renderHtml('sidebar', this._render(sidebarFile, 'sidebar'))
}

if (loadNavbar) {
const name = loadNavbar === true ? '_navbar.md' : loadNavbar
const navbarFile = cwd(mainFile, '..', name)
this._renderHtml('navbar', this._render(navbarFile, 'navbar'))
}

return this.html
}

_renderHtml (match, content) {
this.html = this.html.replace(new RegExp(`<!--${match}-->`, 'g'), content)
}

renderToString(url) {
console.log(url)
_render (path, type) {
let html = this._loadFile(path)

switch (type) {
case 'sidebar':
html = this.compiler.sidebar(html)
break
case 'cover':
html = this.compiler.cover(html)
break
case 'navbar':
case 'article':
default:
html = this.compiler.compile(html)
break
}

return html
}

_loadFile (filePath) {
try {
return readFileSync(filePath, 'utf8')
} catch (e) {
const fileName = basename(filePath)
const parentPath = cwd(filePath, '../..')

if (this.path.length < parentPath.length) {
throw Error(`Not found file ${fileName}`)
}

this._loadFile(cwd(filePath, '../..', fileName))
}
}
}
9 changes: 8 additions & 1 deletion src/core/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,12 @@ export function fetchMixin (proto) {
}

export function initFetch (vm) {
vm.$fetch(_ => callHook(vm, 'ready'))
if (vm.rendered) {
vm._fetchCover()
vm.$resetEvents()
callHook(vm, 'doneEach')
callHook(vm, 'ready')
} else {
vm.$fetch(_ => callHook(vm, 'ready'))
}
}
2 changes: 1 addition & 1 deletion src/core/render/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class Compiler {
if (!text) return text

html = compile(text)
html = emojify(html)
html = config.noEmoji ? html : emojify(html)
slugify.clear()

return html
Expand Down
6 changes: 4 additions & 2 deletions src/core/render/emojify.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { inBrowser } from '../util/env'

function replace (m, $1) {
return '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
}

export function emojify (text) {
return $docsify.noEmoji ? text : text
return text
.replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, m => m.replace(/:/g, '__colon__'))
.replace(/:(\w+?):/ig, window.emojify || replace)
.replace(/:(\w+?):/ig, (inBrowser && window.emojify) || replace)
.replace(/__colon__/g, ':')
}
26 changes: 13 additions & 13 deletions src/core/render/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,20 +172,20 @@ export function initRender (vm) {
let html = ''
let navAppendToTarget = dom.body

if (!el) {
el = dom.create(id)
dom.appendTo(dom.body, el)
}
if (config.repo) {
html += tpl.corner(config.repo)
}
if (config.coverpage) {
html += tpl.cover()
}
if (el) {
if (config.repo) {
html += tpl.corner(config.repo)
}
if (config.coverpage) {
html += tpl.cover()
}

html += tpl.main(config)
// Render main app
vm._renderTo(el, html, true)
html += tpl.main(config)
// Render main app
vm._renderTo(el, html, true)
} else {
vm.rendered = true
}

if (config.mergeNavbar && isMobile) {
navAppendToTarget = dom.find('.sidebar')
Expand Down
4 changes: 2 additions & 2 deletions src/core/render/tpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ export function main (config) {
(config.name
? `<h1><a class="app-name-link" data-nosearch>${config.name}</a></h1>`
: '') +
'<div class="sidebar-nav"></div>' +
'<div class="sidebar-nav"><!--sidebar--></div>' +
'</aside>')

return (isMobile ? `${aside}<main>` : `<main>${aside}`) +
'<section class="content">' +
'<article class="markdown-section" id="main"></article>' +
'<article class="markdown-section" id="main"><!--main--></article>' +
'</section>' +
'</main>'
}
Expand Down
27 changes: 27 additions & 0 deletions src/core/router/history/abstract.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,35 @@
import { History } from './base'
import { parseQuery, stringifyQuery, cleanPath } from '../util'
import { merge } from '../../util/core'

export class AbstractHistory extends History {
constructor (config) {
super(config)
this.mode = 'abstract'
}

parse (path) {
let query = ''

const queryIndex = path.indexOf('?')
if (queryIndex >= 0) {
query = path.slice(queryIndex + 1)
path = path.slice(0, queryIndex)
}

return { path, query: parseQuery(query) }
}

toURL (path, params, currentRoute) {
const local = currentRoute && path[0] === '#'
const route = this.parse(path)

route.query = merge({}, route.query, params)
path = route.path + stringifyQuery(route.query)
path = path.replace(/\.md(\?)|\.md$/, '$1')

if (local) path = currentRoute + path

return cleanPath('/' + path)
}
}
8 changes: 6 additions & 2 deletions src/core/router/util.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { cached } from '../util/core'
import { inBrowser } from '../util/env'

const decode = decodeURIComponent
const encode = encodeURIComponent
Expand Down Expand Up @@ -31,10 +32,13 @@ export function stringifyQuery (obj) {
return qs.length ? `?${qs.join('&')}` : ''
}

export const getBasePath = cached(base => {
export const getBasePath = cached((base = '') => {
// TODO
const path = inBrowser ? window.location.pathname : ''

return /^(\/|https?:)/g.test(base)
? base
: cleanPath(window.location.pathname + '/' + base)
: cleanPath(path + '/' + base)
})

export function getPath (...args) {
Expand Down
8 changes: 3 additions & 5 deletions src/core/util/env.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
export const UA = window.navigator.userAgent.toLowerCase()
export const inBrowser = typeof window !== 'undefined'

export const isIE = UA && /msie|trident/.test(UA)

export const isMobile = document.body.clientWidth <= 600
export const isMobile = inBrowser && document.body.clientWidth <= 600

/**
* @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js
*/
export const supportsPushState = (function () {
export const supportsPushState = inBrowser && (function () {
// Borrowed wholesale from https://github.com/defunkt/jquery-pjax
return window.history &&
window.history.pushState &&
Expand Down

0 comments on commit 3444884

Please sign in to comment.