refactor(core): add router

This commit is contained in:
qingwei.li 2017-02-18 11:41:33 +08:00 committed by cinwell.li
commit 30da0d5d46
17 changed files with 316 additions and 88 deletions

View file

@ -1,7 +1,27 @@
// import { cleanPath, getLocation } from './util'
export function ensureSlash () {
const path = getHash()
if (path.charAt(0) === '/') return
import { parseQuery } from './util'
function replaceHash (path) {
const i = window.location.href.indexOf('#')
window.location.replace(
window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
)
}
/**
* 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 = path
.replace('#', '?id=')
.replace(/\?(\w+)=/g, (_, slug) => slug === 'id' ? '?id=' : `&${slug}=`)
if (path.charAt(0) === '/') return replaceHash(path)
replaceHash('/' + path)
}
@ -13,11 +33,33 @@ export function getHash () {
return index === -1 ? '' : href.slice(index + 1)
}
function replaceHash (path) {
const i = window.location.href.indexOf('#')
window.location.replace(
window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
)
/**
* Parse the current url
* @return {object} { path, query }
*/
export function parse () {
let 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) }
}
// TODO 把第二个 hash 转成 ?id=
/**
* to URL
* @param {String} path
* @param {String} qs query string
*/
export function toURL (path, qs) {
}

View file

@ -1,17 +1,42 @@
import { ensureSlash } from './hash'
import { normalize, parse } from './hash'
import { getBasePath, cleanPath } from './util'
import { on } from '../util/dom'
function getAlias (path, alias) {
if (alias[path]) return getAlias(alias[path], alias)
return path
}
function getFileName (path) {
return /\.(md|html)$/g.test(path)
? path
: /\/$/g.test(path)
? `${path}README.md`
: `${path}.md`
}
export function routeMixin (Docsify) {
Docsify.prototype.$route = {
query: location.query || {},
path: location.path || '/',
base: ''
Docsify.prototype.route = {}
Docsify.prototype.$getFile = function (path) {
const { config } = this
const base = getBasePath(config.basePath)
path = getAlias(path, config.alias)
path = getFileName(path)
path = path === '/README.md' ? ('/' + config.homepage || path) : path
path = cleanPath(base + path)
return path
}
}
export function initRoute (vm) {
ensureSlash()
window.addEventListener('hashchange', () => {
ensureSlash()
vm.$fetch()
normalize()
vm.route = parse()
on('hashchange', _ => {
normalize()
vm.route = parse()
vm._fetch()
})
}

View file

@ -1,11 +1,45 @@
import { cached } from '../util/core'
const decode = decodeURIComponent
export const parseQuery = cached(query => {
const res = {}
query = query.trim().replace(/^(\?|#|&)/, '')
if (!query) {
return res
}
query.split('&').forEach(function (param) {
const parts = param.replace(/\+/g, ' ').split('=')
const key = decode(parts.shift())
const val = parts.length > 0
? decode(parts.join('='))
: null
if (res[key] === undefined) {
res[key] = val
} else if (Array.isArray(res[key])) {
res[key].push(val)
} else {
res[key] = [res[key], val]
}
})
return res
})
export function cleanPath (path) {
return path.replace(/\/+/g, '/')
}
export function getLocation (base) {
let path = window.location.pathname
if (base && path.indexOf(base) === 0) {
path = path.slice(base.length)
}
return (path || '/') + window.location.search + window.location.hash
export function getBasePath (base) {
return /^(\/|https?:)/g.test(base)
? base
: cleanPath(window.location.pathname + '/' + base)
}
export function getCurrentRoot (path) {
return /\/$/g.test(path) ? path : path.match(/(\S*\/)[^\/]+$/)[1]
}