Skip to content

Commit

Permalink
feat(hook): support custom plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
QingWei-Li committed Feb 12, 2017
1 parent 6f87529 commit 9e81a59
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 48 deletions.
52 changes: 52 additions & 0 deletions src/hook.js
@@ -0,0 +1,52 @@
export default class Hook {
constructor () {
this.beforeHooks = []
this.afterHooks = []
this.initHooks = []
this.readyHooks = []
}

beforeEach (fn) {
this.beforeHooks.push(fn)
}

afterEach (fn) {
this.afterHooks.push(fn)
}

init (fn) {
this.initHooks.push(fn)
}

ready (fn) {
this.readyHooks.push(fn)
}

emit (name, data, next) {
let newData = data
const queue = this[name + 'Hooks']
const step = function (index) {
const hook = queue[index]
if (index >= queue.length) {
next && next(newData)
} else {
if (typeof hook === 'function') {
if (hook.length === 2) {
hook(data, result => {
newData = result
step(index + 1)
})
} else {
const result = hook(data)
newData = result !== undefined ? result : newData
step(index + 1)
}
} else {
step(index + 1)
}
}
}

step(0)
}
}
39 changes: 24 additions & 15 deletions src/index.js
@@ -1,6 +1,7 @@
import * as utils from './util'
import { scrollIntoView, activeLink } from './event'
import * as render from './render'
import Hook from './hook'

const OPTIONS = utils.merge({
el: '#app',
Expand Down Expand Up @@ -33,11 +34,14 @@ if (script) {
if (OPTIONS.name === true) OPTIONS.name = ''
}

const hook = new Hook()

// utils
window.$docsify = OPTIONS
window.Docsify = {
installed: true,
utils: utils.merge({}, utils)
utils: utils.merge({}, utils),
hook
}

// load options
Expand Down Expand Up @@ -107,21 +111,26 @@ const mainRender = function (cb) {
}

const Docsify = function () {
const dom = document.querySelector(OPTIONS.el) || document.body
const replace = dom !== document.body
const main = function () {
mainRender(_ => {
scrollIntoView()
activeLink('nav')
;[].concat(window.$docsify.plugins).forEach(fn => fn && fn())
})
}
setTimeout(_ => {
;[].concat(OPTIONS.plugins).forEach(fn => typeof fn === 'function' && fn(hook))
window.Docsify.hook.emit('init')

const dom = document.querySelector(OPTIONS.el) || document.body
const replace = dom !== document.body
const main = function () {
mainRender(_ => {
scrollIntoView()
activeLink('nav')
})
}

// Render app
render.renderApp(dom, replace)
main()
if (!/^#\//.test(window.location.hash)) window.location.hash = '#/'
window.addEventListener('hashchange', main)
// Render app
render.renderApp(dom, replace)
main()
if (!/^#\//.test(window.location.hash)) window.location.hash = '#/'
window.addEventListener('hashchange', main)
window.Docsify.hook.emit('ready')
}, 0)
}

export default Docsify()
11 changes: 4 additions & 7 deletions src/plugins/ga.js
Expand Up @@ -28,18 +28,15 @@ const install = function () {
if (install.installed) return
install.installed = true

if (!window.Docsify || !window.Docsify.installed) {
console.error('[Docsify] Please load docsify.js first.')
return
}

if (!window.$docsify.ga) {
console.error('[Docsify] ga is required.')
return
}

collect()
window.$docsify.plugins = [].concat(window.$docsify.plugins, collect)
window.$docsify.plugins = [].concat(function (hook) {
hook.init(collect)
hook.beforeEach(collect)
}, window.$docsify.plugins)
}

export default install()
17 changes: 9 additions & 8 deletions src/plugins/search.js
Expand Up @@ -324,13 +324,6 @@ const install = function () {
if (install.installed) return
install.installed = true

if (!window.Docsify || !window.Docsify.installed) {
console.error('[Docsify] Please load docsify.js first.')
return
}

window.$docsify.plugins = [].concat(window.$docsify.plugins, searchPlugin)

const userConfig = window.$docsify.search
const isNil = window.Docsify.utils.isNil

Expand All @@ -342,7 +335,15 @@ const install = function () {
CONFIG.placeholder = userConfig.placeholder || CONFIG.placeholder
}

new SearchComponent()
window.$docsify.plugins = [].concat(hook => {
const isAuto = CONFIG.paths === 'auto'

hook.ready(() => {
new SearchComponent()
!isAuto && searchPlugin()
})
isAuto && hook.beforeEach(searchPlugin)
}, window.$docsify.plugins)
}

export default install()
45 changes: 27 additions & 18 deletions src/render.js
Expand Up @@ -123,25 +123,34 @@ export function renderApp (dom, replace) {
* article
*/
export function renderArticle (content) {
renderTo('article', content ? markdown(content) : 'not found')
if (!$docsify.loadSidebar) renderSidebar()

if (content && typeof Vue !== 'undefined') {
CACHE.vm && CACHE.vm.$destroy()

const script = [].slice.call(
document.body.querySelectorAll('article>script'))
.filter(script => !/template/.test(script.type)
)[0]
const code = script ? script.innerText.trim() : null

script && script.remove()
CACHE.vm = code
? new Function(`return ${code}`)()
: new Vue({ el: 'main' }) // eslint-disable-line
CACHE.vm && CACHE.vm.$nextTick(_ => event.scrollActiveSidebar())
const hook = window.Docsify.hook
const renderFn = function (data) {
renderTo('article', data)
if (!$docsify.loadSidebar) renderSidebar()

if (data && typeof Vue !== 'undefined') {
CACHE.vm && CACHE.vm.$destroy()

const script = [].slice.call(
document.body.querySelectorAll('article>script'))
.filter(script => !/template/.test(script.type)
)[0]
const code = script ? script.innerText.trim() : null

script && script.remove()
CACHE.vm = code
? new Function(`return ${code}`)()
: new Vue({ el: 'main' }) // eslint-disable-line
CACHE.vm && CACHE.vm.$nextTick(_ => event.scrollActiveSidebar())
}
if ($docsify.auto2top) setTimeout(() => event.scroll2Top($docsify.auto2top), 0)
}
if ($docsify.auto2top) setTimeout(() => event.scroll2Top($docsify.auto2top), 0)

hook.emit('before', content, result => {
const html = result ? markdown(result) : ''

hook.emit('after', html, result => renderFn(result || 'not found'))
})
}

/**
Expand Down

0 comments on commit 9e81a59

Please sign in to comment.