refactor(core): add router
This commit is contained in:
parent
8bee8f0213
commit
30da0d5d46
17 changed files with 316 additions and 88 deletions
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue