refactor(router): clean global api

This commit is contained in:
qingwei.li 2017-05-29 19:55:28 +08:00 committed by cinwell.li
commit 8741c746df
12 changed files with 46 additions and 126 deletions

View file

@ -6,13 +6,13 @@ import { scrollIntoView } from './scroll'
export function eventMixin (proto) {
proto.$resetEvents = function () {
scrollIntoView(this.route.query.id)
sidebar.getAndActive('nav')
sidebar.getAndActive(this.router, 'nav')
}
}
export function initEvent (vm) {
// Bind toggle button
sidebar.btn('button.sidebar-toggle')
sidebar.btn('button.sidebar-toggle', vm.router)
// Bind sticky effect
if (vm.config.coverpage) {
!isMobile && on('scroll', sidebar.sticky)

View file

@ -1,6 +1,5 @@
import { isMobile } from '../util/env'
import * as dom from '../util/dom'
import { parse } from '../router/hash'
const nav = {}
let hoverOver = false
@ -53,7 +52,7 @@ function highlight () {
}
}
export function scrollActiveSidebar () {
export function scrollActiveSidebar (router) {
if (isMobile) return
const sidebar = dom.getNode('.sidebar')
@ -66,7 +65,7 @@ export function scrollActiveSidebar () {
let href = a.getAttribute('href')
if (href !== '/') {
href = parse(href).query.id
href = router.parse(href).query.id
}
nav[decodeURIComponent(href)] = li

View file

@ -1,12 +1,11 @@
import { isMobile } from '../util/env'
import * as dom from '../util/dom'
import { getHash } from '../router/hash'
const title = dom.$.title
/**
* Toggle button
*/
export function btn (el) {
export function btn (el, router) {
const toggle = _ => dom.body.classList.toggle('close')
el = dom.getNode(el)
@ -21,7 +20,7 @@ export function btn (el) {
dom.body.classList.contains('close') && toggle()
)
dom.on(sidebar, 'click', _ =>
setTimeout((_ => getAndActive(sidebar, true, true), 0))
setTimeout((_ => getAndActive(router, sidebar, true, true), 0))
)
}
@ -39,16 +38,17 @@ export function sticky () {
/**
* Get and active link
* @param {object} router
* @param {string|element} el
* @param {Boolean} isParent acitve parent
* @param {Boolean} autoTitle auto set title
* @return {element}
*/
export function getAndActive (el, isParent, autoTitle) {
export function getAndActive (router, el, isParent, autoTitle) {
el = dom.getNode(el)
const links = dom.findAll(el, 'a')
const hash = '#' + getHash()
const hash = router.toURL(router.getCurrentPath())
let target
links

View file

@ -1,14 +1,14 @@
import * as util from './util'
import * as dom from './util/dom'
import * as render from './render/compiler'
import * as route from './router/hash'
import { Compiler } from './render/compiler'
import { slugify } from './render/slugify'
import { get } from './fetch/ajax'
import marked from 'marked'
import prism from 'prismjs'
export default function () {
window.Docsify = { util, dom, render, route, get, slugify }
window.Docsify = { util, dom, get, slugify }
window.DocsifyCompiler = Compiler
window.marked = marked
window.Prism = prism
}

View file

@ -17,24 +17,24 @@ export class Compiler {
this.contentBase = getBasePath(config.base)
const renderer = this._initRenderer()
let runner
let compile
const mdConf = config.markdown || {}
if (isFn(mdConf)) {
runner = mdConf(marked, renderer)
compile = mdConf(marked, renderer)
} else {
marked.setOptions(merge(mdConf, {
renderer: merge(renderer, mdConf.renderer)
}))
runner = marked
compile = marked
}
this.runner = cached(text => {
this.compile = cached(text => {
let html = ''
if (!text) return text
html = runner(text)
html = compile(text)
html = emojify(html)
slugify.clear()
@ -119,7 +119,7 @@ export class Compiler {
let html = ''
if (text) {
html = this.runner(text)
html = this.compile(text)
html = html.match(/<ul[^>]*>([\s\S]+)<\/ul>/g)[0]
} else {
const tree = this.cacheTree[currentPath] || genTree(this.toc, level)
@ -151,7 +151,7 @@ export class Compiler {
}
article (text) {
return this.runner(text)
return this.compile(text)
}
/**
@ -159,7 +159,7 @@ export class Compiler {
*/
cover (text) {
const cacheToc = this.toc.slice()
const html = this.runner(text)
const html = this.compile(text)
this.toc = cacheToc.slice()

View file

@ -1,14 +1,14 @@
import * as dom from '../util/dom'
import { getAndActive, sticky } from '../event/sidebar'
import { scrollActiveSidebar, scroll2Top } from '../event/scroll'
import cssVars from '../util/polyfill/css-vars'
import * as tpl from './tpl'
import { Compiler } from './compiler'
import { callHook } from '../init/lifecycle'
import { getBasePath, getPath, isAbsolutePath } from '../router/util'
import { isPrimitive } from '../util/core'
import { isMobile } from '../util/env'
import cssVars from '../util/polyfill/css-vars'
import tinydate from 'tinydate'
import { callHook } from '../init/lifecycle'
import { Compiler } from './compiler'
import { getAndActive, sticky } from '../event/sidebar'
import { getBasePath, getPath, isAbsolutePath } from '../router/util'
import { isMobile } from '../util/env'
import { isPrimitive } from '../util/core'
import { scrollActiveSidebar, scroll2Top } from '../event/scroll'
function executeScript () {
const script = dom.findAll('.markdown-section>script')
@ -86,13 +86,13 @@ export function renderMixin (proto) {
const { maxLevel, subMaxLevel, autoHeader, loadSidebar } = this.config
this._renderTo('.sidebar-nav', this.compiler.sidebar(text, maxLevel))
const activeEl = getAndActive('.sidebar-nav', true, true)
const activeEl = getAndActive(this.router, '.sidebar-nav', true, true)
if (loadSidebar && activeEl) {
activeEl.parentNode.innerHTML += this.compiler.subSidebar(subMaxLevel)
}
// bind event
this.activeLink = activeEl
scrollActiveSidebar()
scrollActiveSidebar(this.router)
if (autoHeader && activeEl) {
const main = dom.getNode('#main')
@ -106,13 +106,13 @@ export function renderMixin (proto) {
}
proto._renderNav = function (text) {
text && this._renderTo('nav', this.compiler.runner(text))
getAndActive('nav')
text && this._renderTo('nav', this.compiler.compile(text))
getAndActive(this.router, 'nav')
}
proto._renderMain = function (text, opt = {}) {
callHook(this, 'beforeEach', text, result => {
let html = this.isHTML ? result : this.compiler.runner(result)
let html = this.isHTML ? result : this.compiler.compile(result)
if (opt.updatedAt) {
html = formatUpdated(html, opt.updatedAt, this.config.formatUpdated)
}

View file

@ -1,80 +0,0 @@
import { merge, cached } from '../util/core'
import { parseQuery, stringifyQuery, cleanPath } from './util'
export * from './util'
function replaceHash (path) {
const i = window.location.href.indexOf('#')
window.location.replace(
window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
)
}
const replaceSlug = cached(path => {
return path
.replace('#', '?id=')
// .replace(/\?(\w+)=/g, (_, slug) => slug === 'id' ? '?id=' : `&${slug}=`)
})
/**
* Normalize the current url
*
* @example
* domain.com/docs/ => domain.com/docs/#/
* domain.com/docs/#/#slug => domain.com/docs/#/?id=slug
*/
export function normalize () {
let path = getHash()
path = replaceSlug(path)
if (path.charAt(0) === '/') return replaceHash(path)
replaceHash('/' + path)
}
export function getHash () {
// We can't use window.location.hash here because it's not
// consistent across browsers - Firefox will pre-decode it!
const href = window.location.href
const index = href.indexOf('#')
return index === -1 ? '' : href.slice(index + 1)
}
/**
* Parse the url
* @param {string} [path=window.location.herf]
* @return {object} { path, query }
*/
export function parse (path = window.location.href) {
let query = ''
const queryIndex = path.indexOf('?')
if (queryIndex >= 0) {
query = path.slice(queryIndex + 1)
path = path.slice(0, queryIndex)
}
const hashIndex = path.indexOf('#')
if (hashIndex) {
path = path.slice(hashIndex + 1)
}
return { path, query: parseQuery(query) }
}
/**
* to URL
* @param {string} path
* @param {object} qs query params
* @param {string} currentRoute optional current route
*/
export function toURL (path, params, currentRoute) {
const local = currentRoute && path[0] === '#'
const route = parse(replaceSlug(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)
}

View file

@ -1,7 +1,7 @@
import { History } from './base'
import { merge, cached, noop } from '../../util/core'
import { parseQuery, stringifyQuery, cleanPath } from '../util'
import { on } from '../../util/dom'
import { parseQuery, stringifyQuery, cleanPath } from '../util'
function replaceHash (path) {
const i = location.href.indexOf('#')

View file

@ -1,2 +1,3 @@
export * from './core'
export * from './env'
export * from '../router/util'

View file

@ -138,9 +138,9 @@ function updateNoData (text, path) {
}
}
export function init (opts) {
export function init (opts, vm) {
dom = Docsify.dom
const keywords = Docsify.route.parse().query.s
const keywords = vm.router.parse().query.s
style()
tpl(opts, keywords)

View file

@ -24,7 +24,7 @@ const install = function (hook, vm) {
const isAuto = CONFIG.paths === 'auto'
hook.mounted(_ => {
initComponet(CONFIG)
initComponet(CONFIG, vm)
!isAuto && initSearch(CONFIG, vm)
})
hook.doneEach(_ => {
@ -33,4 +33,4 @@ const install = function (hook, vm) {
})
}
window.$docsify.plugins = [].concat(install, window.$docsify.plugins)
$docsify.plugins = [].concat(install, $docsify.plugins)

View file

@ -14,18 +14,18 @@ function escapeHtml (string) {
return String(string).replace(/[&<>"'\/]/g, s => entityMap[s])
}
function getAllPaths () {
function getAllPaths (router) {
const paths = []
helper.dom.findAll('a:not([data-nosearch])')
.map(node => {
const href = node.href
const originHref = node.getAttribute('href')
const path = helper.route.parse(href).path
const path = router.parse(href).path
if (path &&
paths.indexOf(path) === -1 &&
!helper.route.isAbsolutePath(originHref)) {
!Docsify.util.isAbsolutePath(originHref)) {
paths.push(path)
}
})
@ -38,10 +38,10 @@ function saveData (maxAge) {
localStorage.setItem('docsify.search.index', JSON.stringify(INDEXS))
}
export function genIndex (path, content = '') {
export function genIndex (path, content = '', router) {
const tokens = window.marked.lexer(content)
const slugify = window.Docsify.slugify
const toURL = Docsify.route.toURL
const toURL = router.toURL
const index = {}
let slug
@ -145,7 +145,7 @@ export function init (config, vm) {
return
}
const paths = isAuto ? getAllPaths() : config.paths
const paths = isAuto ? getAllPaths(vm.router) : config.paths
const len = paths.length
let count = 0
@ -155,7 +155,7 @@ export function init (config, vm) {
helper
.get(vm.router.getFile(path))
.then(result => {
INDEXS[path] = genIndex(path, result)
INDEXS[path] = genIndex(path, result, vm.router)
len === ++count && saveData(config.maxAge)
})
})